8272609: Add string deduplication support to SerialGC

Reviewed-by: kbarrett, iwalulya
This commit is contained in:
Denghui Dong 2021-08-23 06:12:01 +00:00 committed by Yi Yang
parent b690f29699
commit e8a289e77d
19 changed files with 249 additions and 3 deletions

View File

@ -26,6 +26,7 @@
#include "gc/serial/defNewGeneration.inline.hpp"
#include "gc/serial/serialGcRefProcProxyTask.hpp"
#include "gc/serial/serialHeap.inline.hpp"
#include "gc/serial/serialStringDedup.inline.hpp"
#include "gc/serial/tenuredGeneration.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/ageTable.inline.hpp"
@ -142,7 +143,8 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs,
: Generation(rs, initial_size),
_preserved_marks_set(false /* in_c_heap */),
_promo_failure_drain_in_progress(false),
_should_allocate_from_space(false)
_should_allocate_from_space(false),
_string_dedup_requests()
{
MemRegion cmr((HeapWord*)_virtual_space.low(),
(HeapWord*)_virtual_space.high());
@ -601,6 +603,8 @@ void DefNewGeneration::collect(bool full,
// Verify that the usage of keep_alive didn't copy any objects.
assert(heap->no_allocs_since_save_marks(), "save marks have not been newly set.");
_string_dedup_requests.flush();
if (!_promotion_failed) {
// Swap the survivor spaces.
eden()->clear(SpaceDecorator::Mangle);
@ -705,6 +709,7 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) {
obj = cast_to_oop(to()->allocate(s));
}
bool new_obj_is_tenured = false;
// Otherwise try allocating obj tenured
if (obj == NULL) {
obj = _old_gen->promote(old, s);
@ -712,6 +717,7 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) {
handle_promotion_failure(old);
return old;
}
new_obj_is_tenured = true;
} else {
// Prefetch beyond obj
const intx interval = PrefetchCopyIntervalInBytes;
@ -728,6 +734,11 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) {
// Done, insert forward pointer to obj in this header
old->forward_to(obj);
if (SerialStringDedup::is_candidate_from_evacuation(obj, new_obj_is_tenured)) {
// Record old; request adds a new weak reference, which reference
// processing expects to refer to a from-space object.
_string_dedup_requests.add(old);
}
return obj;
}

View File

@ -31,6 +31,7 @@
#include "gc/shared/generation.hpp"
#include "gc/shared/generationCounters.hpp"
#include "gc/shared/preservedMarks.hpp"
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shared/tlab_globals.hpp"
#include "utilities/align.hpp"
#include "utilities/stack.hpp"
@ -139,6 +140,8 @@ protected:
STWGCTimer* _gc_timer;
StringDedup::Requests _string_dedup_requests;
enum SomeProtectedConstants {
// Generations are GenGrain-aligned and have size that are multiples of
// GenGrain.

View File

@ -112,6 +112,8 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
deallocate_stacks();
MarkSweep::_string_dedup_requests->flush();
// If compaction completely evacuated the young generation then we
// can clear the card table. Otherwise, we must invalidate
// it (consider all cards dirty). In the future, we might consider doing

View File

@ -57,6 +57,8 @@ ReferenceProcessor* MarkSweep::_ref_processor = NULL;
STWGCTimer* MarkSweep::_gc_timer = NULL;
SerialOldTracer* MarkSweep::_gc_tracer = NULL;
StringDedup::Requests* MarkSweep::_string_dedup_requests = NULL;
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
MarkAndPushClosure MarkSweep::mark_and_push_closure;
@ -214,4 +216,5 @@ void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClo
void MarkSweep::initialize() {
MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
MarkSweep::_string_dedup_requests = new StringDedup::Requests();
}

View File

@ -27,6 +27,7 @@
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/genOopClosures.hpp"
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shared/taskqueue.hpp"
#include "memory/iterator.hpp"
#include "oops/markWord.hpp"
@ -111,6 +112,8 @@ class MarkSweep : AllStatic {
static STWGCTimer* _gc_timer;
static SerialOldTracer* _gc_tracer;
static StringDedup::Requests* _string_dedup_requests;
// Non public closures
static KeepAliveClosure keep_alive;

View File

@ -28,6 +28,8 @@
#include "gc/serial/markSweep.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "gc/serial/serialStringDedup.hpp"
#include "memory/universe.hpp"
#include "oops/markWord.hpp"
#include "oops/access.inline.hpp"
@ -37,6 +39,12 @@
#include "utilities/stack.inline.hpp"
inline void MarkSweep::mark_object(oop obj) {
if (StringDedup::is_enabled() &&
java_lang_String::is_instance_inlined(obj) &&
SerialStringDedup::is_candidate_from_mark(obj)) {
_string_dedup_requests->add(obj);
}
// some marks may contain information we need to preserve so we store them away
// and overwrite the mark. We'll restore it at the end of markSweep.
markWord mark = obj->mark();

View File

@ -28,6 +28,7 @@
#include "gc/serial/tenuredGeneration.inline.hpp"
#include "gc/shared/genMemoryPools.hpp"
#include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/suspendibleThreadSet.hpp"
#include "memory/universe.hpp"
#include "services/memoryManager.hpp"
@ -99,3 +100,15 @@ void SerialHeap::young_process_roots(OopIterateClosure* root_closure,
old_gen()->younger_refs_iterate(old_gen_closure);
}
void SerialHeap::safepoint_synchronize_begin() {
if (UseStringDeduplication) {
SuspendibleThreadSet::synchronize();
}
}
void SerialHeap::safepoint_synchronize_end() {
if (UseStringDeduplication) {
SuspendibleThreadSet::desynchronize();
}
}

View File

@ -80,6 +80,9 @@ public:
void young_process_roots(OopIterateClosure* root_closure,
OopIterateClosure* old_gen_closure,
CLDClosure* cld_closure);
virtual void safepoint_synchronize_begin();
virtual void safepoint_synchronize_end();
};
#endif // SHARE_GC_SERIAL_SERIALHEAP_HPP

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021, Alibaba Group Holding Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/serial/serialStringDedup.hpp"
#include "oops/oop.inline.hpp"
bool SerialStringDedup::is_candidate_from_mark(oop java_string) {
// Candidate if string is being evacuated from young to old but has not
// reached the deduplication age threshold, i.e. has not previously been a
// candidate during its life in the young generation.
return SerialHeap::heap()->young_gen()->is_in_reserved(java_string) &&
StringDedup::is_below_threshold_age(java_string->age());
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021, Alibaba Group Holding Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_GC_SERIAL_STRINGDEDUP_HPP
#define SHARE_GC_SERIAL_STRINGDEDUP_HPP
#include "memory/allStatic.hpp"
#include "oops/oopsHierarchy.hpp"
class SerialStringDedup : AllStatic {
public:
// Candidate selection policy for full GC, returning true if the given
// String is a candidate for string deduplication.
// precondition: StringDedup::is_enabled()
// precondition: java_string is a Java String
static bool is_candidate_from_mark(oop java_string);
// Candidate selection policy for young during evacuation.
static inline bool is_candidate_from_evacuation(oop obj, bool obj_is_tenured);
};
#endif // SHARE_GC_SERIAL_STRINGDEDUP_HPP

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021, Alibaba Group Holding Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_GC_SERIAL_STRINGDEDUP_INLINE_HPP
#define SHARE_GC_SERIAL_STRINGDEDUP_INLINE_HPP
#include "gc/serial/serialStringDedup.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "oops/oop.inline.hpp"
bool SerialStringDedup::is_candidate_from_evacuation(oop obj,
bool obj_is_tenured) {
return StringDedup::is_enabled() &&
java_lang_String::is_instance_inlined(obj) &&
(obj_is_tenured ?
StringDedup::is_below_threshold_age(obj->age()) :
StringDedup::is_threshold_age(obj->age()));
}
#endif // SHARE_GC_SERIAL_STRINGDEDUP_INLINE_HPP

View File

@ -96,6 +96,7 @@
// For additional information on string deduplication, please see JEP 192,
// http://openjdk.java.net/jeps/192
#include "memory/allocation.hpp"
#include "memory/allStatic.hpp"
#include "oops/oopsHierarchy.hpp"
#include "utilities/globalDefinitions.hpp"
@ -195,7 +196,7 @@ public:
// Each marking thread should have it's own Requests object. When marking
// is completed the Requests object must be flushed (either explicitly or by
// the destructor).
class StringDedup::Requests {
class StringDedup::Requests : public CHeapObj<mtGC> {
StorageUse* _storage_for_requests;
oop** _buffer;
size_t _index;

View File

@ -116,7 +116,7 @@ size_t StringDedup::Config::desired_table_size(size_t entry_count) {
bool StringDedup::Config::ergo_initialize() {
if (!UseStringDeduplication) {
return true;
} else if (!UseG1GC && !UseShenandoahGC && !UseZGC && !UseParallelGC) {
} else if (!UseG1GC && !UseShenandoahGC && !UseZGC && !UseParallelGC && !UseSerialGC) {
// String deduplication requested but not supported by the selected GC.
// Warn and force disable, but don't error except in debug build with
// incorrect default.

View File

@ -23,6 +23,19 @@
package gc.stringdedup;
/*
* @test TestStringDeduplicationAgeThreshold
* @summary Test string deduplication age threshold
* @bug 8029075
* @requires vm.gc.Serial
* @library /test/lib
* @library /
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
* @run driver gc.stringdedup.TestStringDeduplicationAgeThreshold Serial
*/
/*
* @test TestStringDeduplicationAgeThreshold
* @summary Test string deduplication age threshold

View File

@ -23,6 +23,19 @@
package gc.stringdedup;
/*
* @test TestStringDeduplicationFullGC
* @summary Test string deduplication during full GC
* @bug 8029075
* @requires vm.gc.Serial
* @library /test/lib
* @library /
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
* @run driver gc.stringdedup.TestStringDeduplicationFullGC Serial
*/
/*
* @test TestStringDeduplicationFullGC
* @summary Test string deduplication during full GC

View File

@ -23,6 +23,19 @@
package gc.stringdedup;
/*
* @test TestStringDeduplicationInterned
* @summary Test string deduplication of interned strings
* @bug 8029075
* @requires vm.gc.Serial
* @library /test/lib
* @library /
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
* @run driver gc.stringdedup.TestStringDeduplicationInterned Serial
*/
/*
* @test TestStringDeduplicationInterned
* @summary Test string deduplication of interned strings

View File

@ -23,6 +23,19 @@
package gc.stringdedup;
/*
* @test TestStringDeduplicationPrintOptions
* @summary Test string deduplication print options
* @bug 8029075
* @requires vm.gc.Serial
* @library /test/lib
* @library /
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
* @run driver gc.stringdedup.TestStringDeduplicationPrintOptions Serial
*/
/*
* @test TestStringDeduplicationPrintOptions
* @summary Test string deduplication print options

View File

@ -23,6 +23,19 @@
package gc.stringdedup;
/*
* @test TestStringDeduplicationTableResize
* @summary Test string deduplication table resize
* @bug 8029075
* @requires vm.gc.Serial
* @library /test/lib
* @library /
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
* @run driver gc.stringdedup.TestStringDeduplicationTableResize Serial
*/
/*
* @test TestStringDeduplicationTableResize
* @summary Test string deduplication table resize

View File

@ -23,6 +23,19 @@
package gc.stringdedup;
/*
* @test TestStringDeduplicationYoungGC
* @summary Test string deduplication during young GC
* @bug 8029075
* @requires vm.gc.Serial
* @library /test/lib
* @library /
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
* @run driver gc.stringdedup.TestStringDeduplicationYoungGC Serial
*/
/*
* @test TestStringDeduplicationYoungGC
* @summary Test string deduplication during young GC