Skip to content

Commit 953eef4

Browse files
committed
8347337: ZGC: String dedups short-lived strings
Reviewed-by: kbarrett, aboldtch, eosterlund
1 parent 7bfbb9a commit 953eef4

File tree

7 files changed

+118
-44
lines changed

7 files changed

+118
-44
lines changed

src/hotspot/share/gc/z/zForwarding.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ class ZForwarding {
5959
const size_t _object_alignment_shift;
6060
const AttachedArray _entries;
6161
ZPage* const _page;
62-
ZPageAge _from_age;
63-
ZPageAge _to_age;
62+
const ZPageAge _from_age;
63+
const ZPageAge _to_age;
6464
volatile bool _claimed;
6565
mutable ZConditionLock _ref_lock;
6666
volatile int32_t _ref_count;

src/hotspot/share/gc/z/zMark.cpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "code/nmethod.hpp"
2828
#include "gc/shared/continuationGCSupport.inline.hpp"
2929
#include "gc/shared/gc_globals.hpp"
30-
#include "gc/shared/stringdedup/stringDedup.hpp"
3130
#include "gc/shared/suspendibleThreadSet.hpp"
3231
#include "gc/shared/workerThread.hpp"
3332
#include "gc/z/zAbort.inline.hpp"
@@ -389,25 +388,6 @@ void ZMark::follow_object(oop obj, bool finalizable) {
389388
}
390389
}
391390

392-
static void try_deduplicate(ZMarkContext* context, oop obj) {
393-
if (!StringDedup::is_enabled()) {
394-
// Not enabled
395-
return;
396-
}
397-
398-
if (!java_lang_String::is_instance(obj)) {
399-
// Not a String object
400-
return;
401-
}
402-
403-
if (java_lang_String::test_and_set_deduplication_requested(obj)) {
404-
// Already requested deduplication
405-
return;
406-
}
407-
408-
// Request deduplication
409-
context->string_dedup_requests()->add(obj);
410-
}
411391

412392
void ZMark::mark_and_follow(ZMarkContext* context, ZMarkStackEntry entry) {
413393
// Decode flags
@@ -449,13 +429,7 @@ void ZMark::mark_and_follow(ZMarkContext* context, ZMarkStackEntry entry) {
449429
if (is_array(addr)) {
450430
follow_array_object(objArrayOop(to_oop(addr)), finalizable);
451431
} else {
452-
const oop obj = to_oop(addr);
453-
follow_object(obj, finalizable);
454-
455-
if (!finalizable) {
456-
// Try deduplicate
457-
try_deduplicate(context, obj);
458-
}
432+
follow_object(to_oop(addr), finalizable);
459433
}
460434
}
461435
}

src/hotspot/share/gc/z/zMarkContext.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#ifndef SHARE_GC_Z_ZMARKCONTEXT_HPP
2525
#define SHARE_GC_Z_ZMARKCONTEXT_HPP
2626

27-
#include "gc/shared/stringdedup/stringDedup.hpp"
2827
#include "gc/z/zMarkCache.hpp"
2928
#include "memory/allocation.hpp"
3029

@@ -37,7 +36,6 @@ class ZMarkContext : public StackObj {
3736
ZMarkStripe* _stripe;
3837
ZMarkThreadLocalStacks* const _stacks;
3938
size_t _nstripes;
40-
StringDedup::Requests _string_dedup_requests;
4139

4240
public:
4341
ZMarkContext(size_t nstripes,
@@ -48,7 +46,6 @@ class ZMarkContext : public StackObj {
4846
ZMarkStripe* stripe();
4947
void set_stripe(ZMarkStripe* stripe);
5048
ZMarkThreadLocalStacks* stacks();
51-
StringDedup::Requests* string_dedup_requests();
5249

5350
size_t nstripes();
5451
void set_nstripes(size_t nstripes);

src/hotspot/share/gc/z/zMarkContext.inline.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ inline ZMarkContext::ZMarkContext(size_t nstripes,
3232
: _cache(nstripes),
3333
_stripe(stripe),
3434
_stacks(stacks),
35-
_nstripes(nstripes),
36-
_string_dedup_requests() {}
35+
_nstripes(nstripes) {}
3736

3837
inline ZMarkCache* ZMarkContext::cache() {
3938
return &_cache;
@@ -51,10 +50,6 @@ inline ZMarkThreadLocalStacks* ZMarkContext::stacks() {
5150
return _stacks;
5251
}
5352

54-
inline StringDedup::Requests* ZMarkContext::string_dedup_requests() {
55-
return &_string_dedup_requests;
56-
}
57-
5853
inline size_t ZMarkContext::nstripes() {
5954
return _nstripes;
6055
}

src/hotspot/share/gc/z/zRelocate.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "gc/z/zRootsIterator.hpp"
4141
#include "gc/z/zStackWatermark.hpp"
4242
#include "gc/z/zStat.hpp"
43+
#include "gc/z/zStringDedup.inline.hpp"
4344
#include "gc/z/zTask.hpp"
4445
#include "gc/z/zUncoloredRoot.inline.hpp"
4546
#include "gc/z/zVerify.hpp"
@@ -559,12 +560,14 @@ class ZRelocateMediumAllocator {
559560
template <typename Allocator>
560561
class ZRelocateWork : public StackObj {
561562
private:
562-
Allocator* const _allocator;
563-
ZForwarding* _forwarding;
564-
ZPage* _target[ZAllocator::_relocation_allocators];
565-
ZGeneration* const _generation;
566-
size_t _other_promoted;
567-
size_t _other_compacted;
563+
Allocator* const _allocator;
564+
ZForwarding* _forwarding;
565+
ZPage* _target[ZAllocator::_relocation_allocators];
566+
ZGeneration* const _generation;
567+
size_t _other_promoted;
568+
size_t _other_compacted;
569+
ZStringDedupContext _string_dedup_context;
570+
568571

569572
ZPage* target(ZPageAge age) {
570573
return _target[static_cast<uint>(age) - 1];
@@ -795,6 +798,13 @@ class ZRelocateWork : public StackObj {
795798
update_remset_promoted(to_addr);
796799
}
797800

801+
void maybe_string_dedup(zaddress to_addr) {
802+
if (_forwarding->is_promotion()) {
803+
// Only deduplicate promoted objects, and let short-lived strings simply die instead.
804+
_string_dedup_context.request(to_oop(to_addr));
805+
}
806+
}
807+
798808
bool try_relocate_object(zaddress from_addr) {
799809
const zaddress to_addr = try_relocate_object_inner(from_addr);
800810

@@ -804,6 +814,8 @@ class ZRelocateWork : public StackObj {
804814

805815
update_remset_for_fields(from_addr, to_addr);
806816

817+
maybe_string_dedup(to_addr);
818+
807819
return true;
808820
}
809821

@@ -1176,10 +1188,15 @@ class ZRelocateAddRemsetForFlipPromoted : public ZRestartableTask {
11761188

11771189
virtual void work() {
11781190
SuspendibleThreadSetJoiner sts_joiner;
1191+
ZStringDedupContext string_dedup_context;
11791192

11801193
for (ZPage* page; _iter.next(&page);) {
11811194
page->object_iterate([&](oop obj) {
1195+
// Remap oops and add remset if needed
11821196
ZIterator::basic_oop_iterate_safe(obj, remap_and_maybe_add_remset);
1197+
1198+
// String dedup
1199+
string_dedup_context.request(obj);
11831200
});
11841201

11851202
SuspendibleThreadSet::yield();
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#ifndef SHARE_GC_Z_ZSTRINGDEDUP_HPP
25+
#define SHARE_GC_Z_ZSTRINGDEDUP_HPP
26+
27+
#include "gc/shared/stringdedup/stringDedup.hpp"
28+
#include "gc/z/zAddress.hpp"
29+
#include "oops/oopsHierarchy.hpp"
30+
31+
class ZStringDedupContext {
32+
private:
33+
StringDedup::Requests _requests;
34+
35+
public:
36+
void request(oop obj);
37+
};
38+
39+
#endif // SHARE_GC_Z_ZSTRINGDEDUP_HPP
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#ifndef SHARE_GC_Z_ZSTRINGDEDUP_INLINE_HPP
25+
#define SHARE_GC_Z_ZSTRINGDEDUP_INLINE_HPP
26+
27+
#include "gc/z/zStringDedup.hpp"
28+
29+
#include "classfile/javaClasses.inline.hpp"
30+
#include "gc/shared/gc_globals.hpp"
31+
32+
inline void ZStringDedupContext::request(oop obj) {
33+
if (!StringDedup::is_enabled()) {
34+
// Not enabled
35+
return;
36+
}
37+
38+
if (!java_lang_String::is_instance(obj)) {
39+
// Not a String object
40+
return;
41+
}
42+
43+
if (java_lang_String::test_and_set_deduplication_requested(obj)) {
44+
// Already requested deduplication
45+
return;
46+
}
47+
48+
// Request deduplication
49+
_requests.add(obj);
50+
}
51+
52+
#endif // SHARE_GC_Z_ZSTRINGDEDUP_INLINE_HPP

0 commit comments

Comments
 (0)