Skip to content

Commit e8a289e

Browse files
D-D-Hy1yang0
authored andcommitted
8272609: Add string deduplication support to SerialGC
Reviewed-by: kbarrett, iwalulya
1 parent b690f29 commit e8a289e

19 files changed

Lines changed: 249 additions & 3 deletions

src/hotspot/share/gc/serial/defNewGeneration.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "gc/serial/defNewGeneration.inline.hpp"
2727
#include "gc/serial/serialGcRefProcProxyTask.hpp"
2828
#include "gc/serial/serialHeap.inline.hpp"
29+
#include "gc/serial/serialStringDedup.inline.hpp"
2930
#include "gc/serial/tenuredGeneration.hpp"
3031
#include "gc/shared/adaptiveSizePolicy.hpp"
3132
#include "gc/shared/ageTable.inline.hpp"
@@ -142,7 +143,8 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs,
142143
: Generation(rs, initial_size),
143144
_preserved_marks_set(false /* in_c_heap */),
144145
_promo_failure_drain_in_progress(false),
145-
_should_allocate_from_space(false)
146+
_should_allocate_from_space(false),
147+
_string_dedup_requests()
146148
{
147149
MemRegion cmr((HeapWord*)_virtual_space.low(),
148150
(HeapWord*)_virtual_space.high());
@@ -601,6 +603,8 @@ void DefNewGeneration::collect(bool full,
601603
// Verify that the usage of keep_alive didn't copy any objects.
602604
assert(heap->no_allocs_since_save_marks(), "save marks have not been newly set.");
603605

606+
_string_dedup_requests.flush();
607+
604608
if (!_promotion_failed) {
605609
// Swap the survivor spaces.
606610
eden()->clear(SpaceDecorator::Mangle);
@@ -705,13 +709,15 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) {
705709
obj = cast_to_oop(to()->allocate(s));
706710
}
707711

712+
bool new_obj_is_tenured = false;
708713
// Otherwise try allocating obj tenured
709714
if (obj == NULL) {
710715
obj = _old_gen->promote(old, s);
711716
if (obj == NULL) {
712717
handle_promotion_failure(old);
713718
return old;
714719
}
720+
new_obj_is_tenured = true;
715721
} else {
716722
// Prefetch beyond obj
717723
const intx interval = PrefetchCopyIntervalInBytes;
@@ -728,6 +734,11 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) {
728734
// Done, insert forward pointer to obj in this header
729735
old->forward_to(obj);
730736

737+
if (SerialStringDedup::is_candidate_from_evacuation(obj, new_obj_is_tenured)) {
738+
// Record old; request adds a new weak reference, which reference
739+
// processing expects to refer to a from-space object.
740+
_string_dedup_requests.add(old);
741+
}
731742
return obj;
732743
}
733744

src/hotspot/share/gc/serial/defNewGeneration.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "gc/shared/generation.hpp"
3232
#include "gc/shared/generationCounters.hpp"
3333
#include "gc/shared/preservedMarks.hpp"
34+
#include "gc/shared/stringdedup/stringDedup.hpp"
3435
#include "gc/shared/tlab_globals.hpp"
3536
#include "utilities/align.hpp"
3637
#include "utilities/stack.hpp"
@@ -139,6 +140,8 @@ class DefNewGeneration: public Generation {
139140

140141
STWGCTimer* _gc_timer;
141142

143+
StringDedup::Requests _string_dedup_requests;
144+
142145
enum SomeProtectedConstants {
143146
// Generations are GenGrain-aligned and have size that are multiples of
144147
// GenGrain.

src/hotspot/share/gc/serial/genMarkSweep.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
112112

113113
deallocate_stacks();
114114

115+
MarkSweep::_string_dedup_requests->flush();
116+
115117
// If compaction completely evacuated the young generation then we
116118
// can clear the card table. Otherwise, we must invalidate
117119
// it (consider all cards dirty). In the future, we might consider doing

src/hotspot/share/gc/serial/markSweep.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ ReferenceProcessor* MarkSweep::_ref_processor = NULL;
5757
STWGCTimer* MarkSweep::_gc_timer = NULL;
5858
SerialOldTracer* MarkSweep::_gc_tracer = NULL;
5959

60+
StringDedup::Requests* MarkSweep::_string_dedup_requests = NULL;
61+
6062
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
6163

6264
MarkAndPushClosure MarkSweep::mark_and_push_closure;
@@ -214,4 +216,5 @@ void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClo
214216
void MarkSweep::initialize() {
215217
MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
216218
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
219+
MarkSweep::_string_dedup_requests = new StringDedup::Requests();
217220
}

src/hotspot/share/gc/serial/markSweep.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "gc/shared/collectedHeap.hpp"
2929
#include "gc/shared/genOopClosures.hpp"
30+
#include "gc/shared/stringdedup/stringDedup.hpp"
3031
#include "gc/shared/taskqueue.hpp"
3132
#include "memory/iterator.hpp"
3233
#include "oops/markWord.hpp"
@@ -111,6 +112,8 @@ class MarkSweep : AllStatic {
111112
static STWGCTimer* _gc_timer;
112113
static SerialOldTracer* _gc_tracer;
113114

115+
static StringDedup::Requests* _string_dedup_requests;
116+
114117
// Non public closures
115118
static KeepAliveClosure keep_alive;
116119

src/hotspot/share/gc/serial/markSweep.inline.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "gc/serial/markSweep.hpp"
2929

3030
#include "classfile/classLoaderData.inline.hpp"
31+
#include "classfile/javaClasses.inline.hpp"
32+
#include "gc/serial/serialStringDedup.hpp"
3133
#include "memory/universe.hpp"
3234
#include "oops/markWord.hpp"
3335
#include "oops/access.inline.hpp"
@@ -37,6 +39,12 @@
3739
#include "utilities/stack.inline.hpp"
3840

3941
inline void MarkSweep::mark_object(oop obj) {
42+
if (StringDedup::is_enabled() &&
43+
java_lang_String::is_instance_inlined(obj) &&
44+
SerialStringDedup::is_candidate_from_mark(obj)) {
45+
_string_dedup_requests->add(obj);
46+
}
47+
4048
// some marks may contain information we need to preserve so we store them away
4149
// and overwrite the mark. We'll restore it at the end of markSweep.
4250
markWord mark = obj->mark();

src/hotspot/share/gc/serial/serialHeap.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "gc/serial/tenuredGeneration.inline.hpp"
2929
#include "gc/shared/genMemoryPools.hpp"
3030
#include "gc/shared/strongRootsScope.hpp"
31+
#include "gc/shared/suspendibleThreadSet.hpp"
3132
#include "memory/universe.hpp"
3233
#include "services/memoryManager.hpp"
3334

@@ -99,3 +100,15 @@ void SerialHeap::young_process_roots(OopIterateClosure* root_closure,
99100

100101
old_gen()->younger_refs_iterate(old_gen_closure);
101102
}
103+
104+
void SerialHeap::safepoint_synchronize_begin() {
105+
if (UseStringDeduplication) {
106+
SuspendibleThreadSet::synchronize();
107+
}
108+
}
109+
110+
void SerialHeap::safepoint_synchronize_end() {
111+
if (UseStringDeduplication) {
112+
SuspendibleThreadSet::desynchronize();
113+
}
114+
}

src/hotspot/share/gc/serial/serialHeap.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ class SerialHeap : public GenCollectedHeap {
8080
void young_process_roots(OopIterateClosure* root_closure,
8181
OopIterateClosure* old_gen_closure,
8282
CLDClosure* cld_closure);
83+
84+
virtual void safepoint_synchronize_begin();
85+
virtual void safepoint_synchronize_end();
8386
};
8487

8588
#endif // SHARE_GC_SERIAL_SERIALHEAP_HPP
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2021, Alibaba Group Holding Limited. 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+
#include "precompiled.hpp"
25+
#include "gc/serial/defNewGeneration.hpp"
26+
#include "gc/serial/serialHeap.hpp"
27+
#include "gc/serial/serialStringDedup.hpp"
28+
#include "oops/oop.inline.hpp"
29+
30+
bool SerialStringDedup::is_candidate_from_mark(oop java_string) {
31+
// Candidate if string is being evacuated from young to old but has not
32+
// reached the deduplication age threshold, i.e. has not previously been a
33+
// candidate during its life in the young generation.
34+
return SerialHeap::heap()->young_gen()->is_in_reserved(java_string) &&
35+
StringDedup::is_below_threshold_age(java_string->age());
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2021, Alibaba Group Holding Limited. 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_SERIAL_STRINGDEDUP_HPP
25+
#define SHARE_GC_SERIAL_STRINGDEDUP_HPP
26+
27+
#include "memory/allStatic.hpp"
28+
#include "oops/oopsHierarchy.hpp"
29+
30+
class SerialStringDedup : AllStatic {
31+
public:
32+
33+
// Candidate selection policy for full GC, returning true if the given
34+
// String is a candidate for string deduplication.
35+
// precondition: StringDedup::is_enabled()
36+
// precondition: java_string is a Java String
37+
static bool is_candidate_from_mark(oop java_string);
38+
39+
// Candidate selection policy for young during evacuation.
40+
static inline bool is_candidate_from_evacuation(oop obj, bool obj_is_tenured);
41+
42+
};
43+
44+
#endif // SHARE_GC_SERIAL_STRINGDEDUP_HPP

0 commit comments

Comments
 (0)