8272609: Add string deduplication support to SerialGC
Reviewed-by: kbarrett, iwalulya
This commit is contained in:
parent
b690f29699
commit
e8a289e77d
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
36
src/hotspot/share/gc/serial/serialStringDedup.cpp
Normal file
36
src/hotspot/share/gc/serial/serialStringDedup.cpp
Normal 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());
|
||||
}
|
44
src/hotspot/share/gc/serial/serialStringDedup.hpp
Normal file
44
src/hotspot/share/gc/serial/serialStringDedup.hpp
Normal 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
|
41
src/hotspot/share/gc/serial/serialStringDedup.inline.hpp
Normal file
41
src/hotspot/share/gc/serial/serialStringDedup.inline.hpp
Normal 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
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user