Skip to content
Permalink
Browse files
8254598: StringDedupTable should use OopStorage
Co-authored-by: Kim Barrett <kbarrett@openjdk.org>
Co-authored-by: Zhengyu Gu <zgu@openjdk.org>
Reviewed-by: coleenp, iklam, tschatzl, ayang
  • Loading branch information
Kim Barrett and zhengyu123 committed May 14, 2021
1 parent 360928d commit be0a655208f64e076e9e0141fe5dadc862cba981
Showing with 2,315 additions and 3,150 deletions.
  1. +1 −18 src/hotspot/share/cds/metaspaceShared.cpp
  2. +5 −1 src/hotspot/share/classfile/compactHashtable.hpp
  3. +15 −0 src/hotspot/share/classfile/javaClasses.cpp
  4. +35 −0 src/hotspot/share/classfile/javaClasses.hpp
  5. +26 −0 src/hotspot/share/classfile/javaClasses.inline.hpp
  6. +20 −19 src/hotspot/share/classfile/stringTable.cpp
  7. +2 −1 src/hotspot/share/classfile/stringTable.hpp
  8. +1 −72 src/hotspot/share/gc/g1/g1CollectedHeap.cpp
  9. +0 −8 src/hotspot/share/gc/g1/g1CollectedHeap.hpp
  10. +0 −6 src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
  11. +0 −5 src/hotspot/share/gc/g1/g1FullCollector.cpp
  12. +2 −6 src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp
  13. +0 −3 src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp
  14. +1 −2 src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp
  15. +1 −2 src/hotspot/share/gc/g1/g1FullGCMarkTask.hpp
  16. +6 −4 src/hotspot/share/gc/g1/g1FullGCMarker.hpp
  17. +5 −4 src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp
  18. +0 −1 src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp
  19. +0 −1 src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp
  20. +0 −17 src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
  21. +0 −8 src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp
  22. +0 −6 src/hotspot/share/gc/g1/g1HeapVerifier.cpp
  23. +10 −22 src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
  24. +3 −4 src/hotspot/share/gc/g1/g1ParScanThreadState.hpp
  25. +2 −7 src/hotspot/share/gc/g1/g1ParallelCleaning.cpp
  26. +2 −4 src/hotspot/share/gc/g1/g1ParallelCleaning.hpp
  27. +5 −52 src/hotspot/share/gc/g1/g1StringDedup.cpp
  28. +23 −28 src/hotspot/share/gc/g1/g1StringDedup.hpp
  29. +0 −151 src/hotspot/share/gc/g1/g1StringDedupQueue.cpp
  30. +0 −87 src/hotspot/share/gc/g1/g1StringDedupQueue.hpp
  31. +0 −82 src/hotspot/share/gc/g1/g1StringDedupStat.cpp
  32. +0 −52 src/hotspot/share/gc/g1/g1StringDedupStat.hpp
  33. +2 −4 src/hotspot/share/gc/shared/collectedHeap.cpp
  34. +0 −3 src/hotspot/share/gc/shared/collectedHeap.hpp
  35. +1 −1 src/hotspot/share/gc/shared/gc_globals.hpp
  36. +1 −1 src/hotspot/share/gc/shared/oopStorageSet.hpp
  37. +1 −24 src/hotspot/share/gc/shared/parallelCleaning.cpp
  38. +1 −12 src/hotspot/share/gc/shared/parallelCleaning.hpp
  39. +156 −35 src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp
  40. +148 −70 src/hotspot/share/gc/shared/stringdedup/stringDedup.hpp
  41. +0 −41 src/hotspot/share/gc/shared/stringdedup/stringDedup.inline.hpp
  42. +166 −0 src/hotspot/share/gc/shared/stringdedup/stringDedupConfig.cpp
  43. +70 −0 src/hotspot/share/gc/shared/stringdedup/stringDedupConfig.hpp
  44. +227 −0 src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp
  45. +80 −0 src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.hpp
  46. +0 −66 src/hotspot/share/gc/shared/stringdedup/stringDedupQueue.cpp
  47. +0 −112 src/hotspot/share/gc/shared/stringdedup/stringDedupQueue.hpp
  48. +197 −88 src/hotspot/share/gc/shared/stringdedup/stringDedupStat.cpp
  49. +103 −73 src/hotspot/share/gc/shared/stringdedup/stringDedupStat.hpp
  50. +22 −24 src/hotspot/share/gc/shared/stringdedup/{stringDedupQueue.inline.hpp → stringDedupStorageUse.cpp}
  51. +58 −0 src/hotspot/share/gc/shared/stringdedup/stringDedupStorageUse.hpp
  52. +633 −504 src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp
  53. +105 −209 src/hotspot/share/gc/shared/stringdedup/stringDedupTable.hpp
  54. +0 −94 src/hotspot/share/gc/shared/stringdedup/stringDedupThread.cpp
  55. +0 −72 src/hotspot/share/gc/shared/stringdedup/stringDedupThread.hpp
  56. +0 −95 src/hotspot/share/gc/shared/stringdedup/stringDedupThread.inline.hpp
  57. +0 −11 src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp
  58. +0 −14 src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
  59. +0 −2 src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
  60. +1 −0 src/hotspot/share/gc/shenandoah/shenandoahMark.cpp
  61. +2 −1 src/hotspot/share/gc/shenandoah/shenandoahMark.hpp
  62. +4 −3 src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
  63. +2 −2 src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp
  64. +1 −1 src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp
  65. +0 −2 src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.hpp
  66. +0 −2 src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.inline.hpp
  67. +0 −2 src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp
  68. +0 −68 src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
  69. +0 −28 src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp
  70. +0 −3 src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
  71. +0 −8 src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp
  72. +1 −1 src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp
  73. +0 −249 src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp
  74. +0 −118 src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp
  75. +0 −126 src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.inline.hpp
  76. +0 −136 src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp
  77. +1 −24 src/hotspot/share/gc/shenandoah/shenandoahStringDedup.hpp
  78. +21 −3 src/hotspot/share/gc/shenandoah/shenandoahStringDedup.inline.hpp
  79. +1 −0 src/hotspot/share/memory/allocation.hpp
  80. +7 −2 src/hotspot/share/memory/universe.cpp
  81. +1 −0 src/hotspot/share/memory/universe.hpp
  82. +5 −0 src/hotspot/share/runtime/arguments.cpp
  83. +27 −4 src/hotspot/share/runtime/globals.hpp
  84. +6 −0 src/hotspot/share/runtime/java.cpp
  85. +4 −9 src/hotspot/share/runtime/mutexLocker.cpp
  86. +2 −2 src/hotspot/share/runtime/mutexLocker.hpp
  87. +9 −0 src/hotspot/share/runtime/thread.cpp
  88. +2 −7 src/hotspot/share/utilities/hashtable.cpp
  89. +0 −5 test/hotspot/jtreg/gc/g1/TestGCLogMessages.java
  90. +0 −43 test/hotspot/jtreg/gc/g1/TestStringDeduplicationTableRehash.java
  91. +4 −4 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationAgeThreshold.java
  92. +4 −4 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationFullGC.java
  93. +4 −4 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationInterned.java
  94. +4 −4 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationPrintOptions.java
  95. +4 −4 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationTableResize.java
  96. +58 −49 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationTools.java
  97. +4 −4 test/hotspot/jtreg/gc/{g1 → stringdedup}/TestStringDeduplicationYoungGC.java
@@ -1375,21 +1375,6 @@ class CountSharedSymbols : public SymbolClosure {

};

// For -XX:PrintSharedArchiveAndExit
class CountSharedStrings : public OopClosure {
private:
int _count;
public:
CountSharedStrings() : _count(0) {}
void do_oop(oop* p) {
_count++;
}
void do_oop(narrowOop* p) {
_count++;
}
int total() { return _count; }
};

// Read the miscellaneous data from the shared file, and
// serialize it out to its various destinations.

@@ -1444,9 +1429,7 @@ void MetaspaceShared::initialize_shared_spaces() {
CountSharedSymbols cl;
SymbolTable::shared_symbols_do(&cl);
tty->print_cr("Number of shared symbols: %d", cl.total());
CountSharedStrings cs;
StringTable::shared_oops_do(&cs);
tty->print_cr("Number of shared strings: %d", cs.total());
tty->print_cr("Number of shared strings: %zu", StringTable::shared_entry_count());
tty->print_cr("VM version: %s\r\n", static_mapinfo->vm_version());
if (FileMapInfo::current_info() == NULL || _archive_loading_failed) {
tty->print_cr("archive is invalid");
@@ -222,10 +222,14 @@ class SimpleCompactHashtable {
// Read/Write the table's header from/to the CDS archive
void serialize_header(SerializeClosure* soc) NOT_CDS_RETURN;

inline bool empty() {
inline bool empty() const {
return (_entry_count == 0);
}

inline size_t entry_count() const {
return _entry_count;
}

static size_t calculate_header_size();
};

@@ -201,13 +201,26 @@ int java_lang_String::_value_offset;
int java_lang_String::_hash_offset;
int java_lang_String::_hashIsZero_offset;
int java_lang_String::_coder_offset;
int java_lang_String::_flags_offset;

bool java_lang_String::_initialized;

bool java_lang_String::is_instance(oop obj) {
return is_instance_inlined(obj);
}

bool java_lang_String::test_and_set_flag(oop java_string, uint8_t flag_mask) {
uint8_t* addr = flags_addr(java_string);
uint8_t value = Atomic::load(addr);
while ((value & flag_mask) == 0) {
uint8_t old_value = value;
value |= flag_mask;
value = Atomic::cmpxchg(addr, old_value, value);
if (value == old_value) return false; // Flag bit changed from 0 to 1.
}
return true; // Flag bit is already 1.
}

#define STRING_FIELDS_DO(macro) \
macro(_value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \
macro(_hash_offset, k, "hash", int_signature, false); \
@@ -221,13 +234,15 @@ void java_lang_String::compute_offsets() {

InstanceKlass* k = vmClasses::String_klass();
STRING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
STRING_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);

_initialized = true;
}

#if INCLUDE_CDS
void java_lang_String::serialize_offsets(SerializeClosure* f) {
STRING_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
STRING_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
f->do_bool(&_initialized);
}
#endif
@@ -96,19 +96,38 @@ class java_lang_Object : AllStatic {

// Interface to java.lang.String objects

// The flags field is a collection of bits representing boolean values used
// internally by the VM.
#define STRING_INJECTED_FIELDS(macro) \
macro(java_lang_String, flags, byte_signature, false)

class java_lang_String : AllStatic {
private:
static int _value_offset;
static int _hash_offset;
static int _hashIsZero_offset;
static int _coder_offset;
static int _flags_offset;

static bool _initialized;

static Handle basic_create(int length, bool byte_arr, TRAPS);

static inline void set_coder(oop string, jbyte coder);

// Bitmasks for values in the injected flags field.
static const uint8_t _deduplication_forbidden_mask = 1 << 0;
static const uint8_t _deduplication_requested_mask = 1 << 1;

static int flags_offset() { CHECK_INIT(_flags_offset); }
// Return the address of the injected flags field.
static inline uint8_t* flags_addr(oop java_string);
// Test whether the designated bit of the injected flags field is set.
static inline bool is_flag_set(oop java_string, uint8_t flag_mask);
// Atomically test and set the designated bit of the injected flags field,
// returning true if the bit was already set.
static bool test_and_set_flag(oop java_string, uint8_t flag_mask);

public:

// Coders
@@ -137,11 +156,26 @@ class java_lang_String : AllStatic {
static inline void set_value_raw(oop string, typeArrayOop buffer);
static inline void set_value(oop string, typeArrayOop buffer);

// Set the deduplication_forbidden flag true. This flag is sticky; once
// set it never gets cleared. This is set when a String is interned in
// the StringTable, to prevent string deduplication from changing the
// String's value array.
static inline void set_deduplication_forbidden(oop java_string);

// Test and set the deduplication_requested flag. Returns the old value
// of the flag. This flag is sticky; once set it never gets cleared.
// Some GCs may use this flag when deciding whether to request
// deduplication of a String, to avoid multiple requests for the same
// object.
static inline bool test_and_set_deduplication_requested(oop java_string);

// Accessors
static inline typeArrayOop value(oop java_string);
static inline typeArrayOop value_no_keepalive(oop java_string);
static inline bool hash_is_set(oop string);
static inline bool is_latin1(oop java_string);
static inline bool deduplication_forbidden(oop java_string);
static inline bool deduplication_requested(oop java_string);
static inline int length(oop java_string);
static inline int length(oop java_string, typeArrayOop string_value);
static int utf8_length(oop java_string);
@@ -1735,6 +1769,7 @@ class InjectedField {
klass##_##name##_enum,

#define ALL_INJECTED_FIELDS(macro) \
STRING_INJECTED_FIELDS(macro) \
CLASS_INJECTED_FIELDS(macro) \
CLASSLOADER_INJECTED_FIELDS(macro) \
RESOLVEDMETHOD_INJECTED_FIELDS(macro) \
@@ -73,6 +73,32 @@ bool java_lang_String::is_latin1(oop java_string) {
return coder == CODER_LATIN1;
}

uint8_t* java_lang_String::flags_addr(oop java_string) {
assert(_initialized, "Must be initialized");
assert(is_instance(java_string), "Must be java string");
return java_string->obj_field_addr<uint8_t>(_flags_offset);
}

bool java_lang_String::is_flag_set(oop java_string, uint8_t flag_mask) {
return (Atomic::load(flags_addr(java_string)) & flag_mask) != 0;
}

bool java_lang_String::deduplication_forbidden(oop java_string) {
return is_flag_set(java_string, _deduplication_forbidden_mask);
}

bool java_lang_String::deduplication_requested(oop java_string) {
return is_flag_set(java_string, _deduplication_requested_mask);
}

void java_lang_String::set_deduplication_forbidden(oop java_string) {
test_and_set_flag(java_string, _deduplication_forbidden_mask);
}

bool java_lang_String::test_and_set_deduplication_requested(oop java_string) {
return test_and_set_flag(java_string, _deduplication_requested_mask);
}

int java_lang_String::length(oop java_string, typeArrayOop value) {
assert(_initialized, "Must be initialized");
assert(is_instance(java_string), "must be java_string");
@@ -33,11 +33,11 @@
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/oopStorageSet.hpp"
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
#include "oops/compressedOops.hpp"
#include "oops/oop.inline.hpp"
@@ -346,15 +346,17 @@ oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
string_h = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
}

// Deduplicate the string before it is interned. Note that we should never
// deduplicate a string after it has been interned. Doing so will counteract
// compiler optimizations done on e.g. interned string literals.
Universe::heap()->deduplicate_string(string_h());

assert(java_lang_String::equals(string_h(), name, len),
"string must be properly initialized");
assert(len == java_lang_String::length(string_h()), "Must be same length");

// Notify deduplication support that the string is being interned. A string
// must never be deduplicated after it has been interned. Doing so interferes
// with compiler optimizations done on e.g. interned string literals.
if (StringDedup::is_enabled()) {
StringDedup::notify_intern(string_h());
}

StringTableLookupOop lookup(THREAD, hash, string_h);
StringTableGet stg(THREAD);

@@ -700,12 +702,20 @@ void StringtableDCmd::execute(DCmdSource source, TRAPS) {

// Sharing
#if INCLUDE_CDS_JAVA_HEAP
size_t StringTable::shared_entry_count() {
return _shared_table.entry_count();
}

oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) {
assert(hash == java_lang_String::hash_code(name, len),
"hash must be computed using java_lang_String::hash_code");
return _shared_table.lookup(name, hash, len);
}

oop StringTable::lookup_shared(const jchar* name, int len) {
return _shared_table.lookup(name, java_lang_String::hash_code(name, len), len);
}

oop StringTable::create_archived_string(oop s) {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
assert(java_lang_String::is_instance(s), "sanity");
@@ -724,6 +734,10 @@ oop StringTable::create_archived_string(oop s) {

// adjust the pointer to the 'value' field in the new String oop
java_lang_String::set_value_raw(new_s, new_v);
// Prevent string deduplication from changing the 'value' field to
// something not in the archive before building the archive. Also marks
// the shared string when loaded.
java_lang_String::set_deduplication_forbidden(new_s);
return new_s;
}

@@ -769,17 +783,4 @@ void StringTable::serialize_shared_table_header(SerializeClosure* soc) {
}
}

class SharedStringIterator {
OopClosure* _oop_closure;
public:
SharedStringIterator(OopClosure* f) : _oop_closure(f) {}
void do_value(oop string) {
_oop_closure->do_oop(&string);
}
};

void StringTable::shared_oops_do(OopClosure* f) {
SharedStringIterator iter(f);
_shared_table.iterate(&iter);
}
#endif //INCLUDE_CDS_JAVA_HEAP
@@ -107,8 +107,9 @@ class StringTable : public CHeapObj<mtSymbol>{
private:
static oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
public:
static oop lookup_shared(const jchar* name, int len) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
static size_t shared_entry_count() NOT_CDS_JAVA_HEAP_RETURN_(0);
static oop create_archived_string(oop s) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
static void shared_oops_do(OopClosure* f) NOT_CDS_JAVA_HEAP_RETURN;
static void write_to_archive(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN;
static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;

0 comments on commit be0a655

Please sign in to comment.