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
25 #include "cds/archiveBuilder.hpp"
26 #include "cds/archiveHeapLoader.inline.hpp"
27 #include "cds/archiveHeapWriter.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/heapShared.hpp"
30 #include "classfile/altHashing.hpp"
31 #include "classfile/compactHashtable.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/stringTable.hpp"
34 #include "classfile/vmClasses.hpp"
35 #include "gc/shared/collectedHeap.hpp"
36 #include "gc/shared/oopStorage.inline.hpp"
37 #include "gc/shared/oopStorageSet.hpp"
38 #include "gc/shared/stringdedup/stringDedup.hpp"
39 #include "logging/log.hpp"
40 #include "logging/logStream.hpp"
41 #include "memory/allocation.inline.hpp"
42 #include "memory/oopFactory.hpp"
43 #include "memory/resourceArea.hpp"
44 #include "oops/access.inline.hpp"
45 #include "oops/compressedOops.hpp"
46 #include "oops/oop.inline.hpp"
47 #include "oops/typeArrayOop.inline.hpp"
48 #include "oops/weakHandle.inline.hpp"
49 #include "runtime/atomic.hpp"
50 #include "runtime/handles.inline.hpp"
51 #include "runtime/interfaceSupport.inline.hpp"
52 #include "runtime/mutexLocker.hpp"
53 #include "runtime/safepointVerifiers.hpp"
54 #include "runtime/timerTrace.hpp"
98
99 typedef CompactHashtable<
100 const StringTable::StringWrapper&, oop,
101 StringTable::read_string_from_compact_hashtable,
102 StringTable::wrapped_string_equals> SharedStringTable;
103
104 static SharedStringTable _shared_table;
105 #endif
106
107 // --------------------------------------------------------------------------
108
109 typedef ConcurrentHashTable<StringTableConfig, mtSymbol> StringTableHash;
110 static StringTableHash* _local_table = nullptr;
111
112 volatile bool StringTable::_has_work = false;
113 volatile bool StringTable::_needs_rehashing = false;
114 OopStorage* StringTable::_oop_storage;
115
116 static size_t _current_size = 0;
117 static volatile size_t _items_count = 0;
118
119 volatile bool _alt_hash = false;
120
121 static bool _rehashed = false;
122 static uint64_t _alt_hash_seed = 0;
123
124 enum class StringType {
125 OopStr, UnicodeStr, SymbolStr, UTF8Str
126 };
127
128 struct StringWrapperInternal {
129 union {
130 const Handle oop_str;
131 const jchar* unicode_str;
132 const Symbol* symbol_str;
133 const char* utf8_str;
134 };
135 const StringType type;
136 const size_t length;
137
329 void StringTable::item_removed() {
330 Atomic::dec(&_items_count);
331 }
332
333 double StringTable::get_load_factor() {
334 return double(_items_count)/double(_current_size);
335 }
336
337 double StringTable::get_dead_factor(size_t num_dead) {
338 return double(num_dead)/double(_current_size);
339 }
340
341 size_t StringTable::table_size() {
342 return ((size_t)1) << _local_table->get_size_log2(Thread::current());
343 }
344
345 bool StringTable::has_work() {
346 return Atomic::load_acquire(&_has_work);
347 }
348
349 void StringTable::trigger_concurrent_work() {
350 // Avoid churn on ServiceThread
351 if (!has_work()) {
352 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
353 Atomic::store(&_has_work, true);
354 Service_lock->notify_all();
355 }
356 }
357
358 // Probing
359 oop StringTable::lookup(Symbol* symbol) {
360 ResourceMark rm;
361 int length;
362 jchar* chars = symbol->as_unicode(length);
363 return lookup(chars, length);
364 }
365
366 oop StringTable::lookup(const jchar* name, int len) {
367 unsigned int hash = java_lang_String::hash_code(name, len);
368 StringWrapper wrapped_name(name, len);
487 }
488
489 oop StringTable::intern(oop string, TRAPS) {
490 if (string == nullptr) return nullptr;
491 int length = java_lang_String::length(string);
492 Handle h_string (THREAD, string);
493 StringWrapper name(h_string, length);
494 oop result = intern(name, CHECK_NULL);
495 return result;
496 }
497
498 oop StringTable::intern(const char* utf8_string, TRAPS) {
499 if (utf8_string == nullptr) return nullptr;
500 size_t length = strlen(utf8_string);
501 StringWrapper name(utf8_string, length);
502 oop result = intern(name, CHECK_NULL);
503 return result;
504 }
505
506 oop StringTable::intern(const StringWrapper& name, TRAPS) {
507 // shared table always uses java_lang_String::hash_code
508 unsigned int hash = hash_wrapped_string(name);
509 oop found_string = lookup_shared(name, hash);
510 if (found_string != nullptr) {
511 return found_string;
512 }
513
514 if (_alt_hash) {
515 ResourceMark rm(THREAD);
516 // Convert to unicode for alt hashing
517 int unicode_length;
518 const jchar* chars = to_unicode(name, unicode_length, CHECK_NULL);
519 hash = hash_string(chars, unicode_length, true);
520 }
521
522 found_string = do_lookup(name, hash);
523 if (found_string != nullptr) {
524 return found_string;
525 }
526 return do_intern(name, hash, THREAD);
776
777 // Verification
778 class VerifyStrings : StackObj {
779 public:
780 bool operator()(WeakHandle* val) {
781 oop s = val->peek();
782 if (s != nullptr) {
783 assert(java_lang_String::length(s) >= 0, "Length on string must work.");
784 }
785 return true;
786 };
787 };
788
789 // This verification is part of Universe::verify() and needs to be quick.
790 void StringTable::verify() {
791 VerifyStrings vs;
792 _local_table->do_safepoint_scan(vs);
793 }
794
795 // Verification and comp
796 class VerifyCompStrings : StackObj {
797 static unsigned string_hash(oop const& str) {
798 return java_lang_String::hash_code_noupdate(str);
799 }
800 static bool string_equals(oop const& a, oop const& b) {
801 return java_lang_String::equals(a, b);
802 }
803
804 ResizeableResourceHashtable<oop, bool, AnyObj::C_HEAP, mtInternal,
805 string_hash, string_equals> _table;
806 public:
807 size_t _errors;
808 VerifyCompStrings() : _table(unsigned(_items_count / 8) + 1, 0 /* do not resize */), _errors(0) {}
809 bool operator()(WeakHandle* val) {
810 oop s = val->resolve();
811 if (s == nullptr) {
812 return true;
813 }
814 bool created;
815 _table.put_if_absent(s, true, &created);
816 assert(created, "Duplicate strings");
817 if (!created) {
818 _errors++;
819 }
820 return true;
821 };
822 };
823
824 size_t StringTable::verify_and_compare_entries() {
825 Thread* thr = Thread::current();
826 VerifyCompStrings vcs;
827 _local_table->do_scan(thr, vcs);
828 return vcs._errors;
922
923 // Sharing
924 #if INCLUDE_CDS_JAVA_HEAP
925 size_t StringTable::shared_entry_count() {
926 return _shared_table.entry_count();
927 }
928
929 oop StringTable::lookup_shared(const StringWrapper& name, unsigned int hash) {
930 assert(hash == hash_wrapped_string(name),
931 "hash must be computed using java_lang_String::hash_code");
932 // len is required but is already part of StringWrapper, so 0 is used
933 return _shared_table.lookup(name, hash, 0);
934 }
935
936 oop StringTable::lookup_shared(const jchar* name, int len) {
937 StringWrapper wrapped_name(name, len);
938 // len is required but is already part of StringWrapper, so 0 is used
939 return _shared_table.lookup(wrapped_name, java_lang_String::hash_code(name, len), 0);
940 }
941
942 // This is called BEFORE we enter the CDS safepoint. We can allocate heap objects.
943 // This should be called when we know no more strings will be added (which will be easy
944 // to guarantee because CDS runs with a single Java thread. See JDK-8253495.)
945 void StringTable::allocate_shared_strings_array(TRAPS) {
946 if (!CDSConfig::is_dumping_heap()) {
947 return;
948 }
949 assert(CDSConfig::allow_only_single_java_thread(), "No more interned strings can be added");
950
951 if (_items_count > (size_t)max_jint) {
952 fatal("Too many strings to be archived: %zu", _items_count);
953 }
954
955 int total = (int)_items_count;
956 size_t single_array_size = objArrayOopDesc::object_size(total);
957
958 log_info(aot)("allocated string table for %d strings", total);
959
960 if (!ArchiveHeapWriter::is_too_large_to_archive(single_array_size)) {
961 // The entire table can fit in a single array
962 objArrayOop array = oopFactory::new_objArray(vmClasses::Object_klass(), total, CHECK);
963 _shared_strings_array = OopHandle(Universe::vm_global(), array);
964 log_info(aot)("string table array (single level) length = %d", total);
965 } else {
966 // Split the table in two levels of arrays.
967 int primary_array_length = (total + _secondary_array_max_length - 1) / _secondary_array_max_length;
968 size_t primary_array_size = objArrayOopDesc::object_size(primary_array_length);
969 size_t secondary_array_size = objArrayOopDesc::object_size(_secondary_array_max_length);
970
971 if (ArchiveHeapWriter::is_too_large_to_archive(secondary_array_size)) {
972 // This can only happen if you have an extremely large number of classes that
973 // refer to more than 16384 * 16384 = 26M interned strings! Not a practical concern
974 // but bail out for safety.
975 log_error(aot)("Too many strings to be archived: %zu", _items_count);
976 MetaspaceShared::unrecoverable_writing_error();
977 }
978
979 objArrayOop primary = oopFactory::new_objArray(vmClasses::Object_klass(), primary_array_length, CHECK);
980 objArrayHandle primaryHandle(THREAD, primary);
981 _shared_strings_array = OopHandle(Universe::vm_global(), primary);
982
983 log_info(aot)("string table array (primary) length = %d", primary_array_length);
984 for (int i = 0; i < primary_array_length; i++) {
985 int len;
986 if (total > _secondary_array_max_length) {
987 len = _secondary_array_max_length;
988 } else {
989 len = total;
990 }
991 total -= len;
992
993 objArrayOop secondary = oopFactory::new_objArray(vmClasses::Object_klass(), len, CHECK);
994 primaryHandle()->obj_at_put(i, secondary);
995
1053
1054 assert(primary_index < array->length(), "no strings should have been added");
1055 objArrayOop secondary = (objArrayOop)array->obj_at(primary_index);
1056
1057 assert(secondary != nullptr && secondary->is_objArray(), "must be");
1058 assert(secondary_index < secondary->length(), "no strings should have been added");
1059 secondary->obj_at_put(secondary_index, string);
1060 }
1061 index ++;
1062 }
1063 return true;
1064 };
1065
1066 _local_table->do_safepoint_scan(copy_into_array);
1067 log_info(aot)("Archived %d interned strings", index);
1068 return array;
1069 };
1070
1071 void StringTable::write_shared_table() {
1072 _shared_table.reset();
1073 CompactHashtableWriter writer((int)_items_count, ArchiveBuilder::string_stats());
1074
1075 int index = 0;
1076 auto copy_into_shared_table = [&] (WeakHandle* val) {
1077 oop string = val->peek();
1078 if (string != nullptr && !ArchiveHeapWriter::is_string_too_large_to_archive(string)) {
1079 unsigned int hash = java_lang_String::hash_code(string);
1080 writer.add(hash, index);
1081 index ++;
1082 }
1083 return true;
1084 };
1085 _local_table->do_safepoint_scan(copy_into_shared_table);
1086 writer.dump(&_shared_table, "string");
1087 }
1088
1089 void StringTable::set_shared_strings_array_index(int root_index) {
1090 _shared_strings_array_root_index = root_index;
1091 }
1092
1093 void StringTable::serialize_shared_table_header(SerializeClosure* soc) {
1094 _shared_table.serialize_header(soc);
1095
1096 if (soc->writing()) {
1097 // Sanity. Make sure we don't use the shared table at dump time
1098 _shared_table.reset();
1099 } else if (!ArchiveHeapLoader::is_in_use()) {
1100 _shared_table.reset();
1101 }
1102
1103 soc->do_bool(&_is_two_dimensional_shared_strings_array);
1104 soc->do_int(&_shared_strings_array_root_index);
1105 }
1106 #endif //INCLUDE_CDS_JAVA_HEAP
|
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
25 #include "cds/archiveBuilder.hpp"
26 #include "cds/archiveHeapLoader.inline.hpp"
27 #include "cds/archiveHeapWriter.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/heapShared.hpp"
30 #include "classfile/altHashing.hpp"
31 #include "classfile/compactHashtable.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/stringTable.hpp"
34 #include "classfile/vmClasses.hpp"
35 #include "compiler/compileBroker.hpp"
36 #include "gc/shared/collectedHeap.hpp"
37 #include "gc/shared/oopStorage.inline.hpp"
38 #include "gc/shared/oopStorageSet.hpp"
39 #include "gc/shared/stringdedup/stringDedup.hpp"
40 #include "logging/log.hpp"
41 #include "logging/logStream.hpp"
42 #include "memory/allocation.inline.hpp"
43 #include "memory/oopFactory.hpp"
44 #include "memory/resourceArea.hpp"
45 #include "oops/access.inline.hpp"
46 #include "oops/compressedOops.hpp"
47 #include "oops/oop.inline.hpp"
48 #include "oops/typeArrayOop.inline.hpp"
49 #include "oops/weakHandle.inline.hpp"
50 #include "runtime/atomic.hpp"
51 #include "runtime/handles.inline.hpp"
52 #include "runtime/interfaceSupport.inline.hpp"
53 #include "runtime/mutexLocker.hpp"
54 #include "runtime/safepointVerifiers.hpp"
55 #include "runtime/timerTrace.hpp"
99
100 typedef CompactHashtable<
101 const StringTable::StringWrapper&, oop,
102 StringTable::read_string_from_compact_hashtable,
103 StringTable::wrapped_string_equals> SharedStringTable;
104
105 static SharedStringTable _shared_table;
106 #endif
107
108 // --------------------------------------------------------------------------
109
110 typedef ConcurrentHashTable<StringTableConfig, mtSymbol> StringTableHash;
111 static StringTableHash* _local_table = nullptr;
112
113 volatile bool StringTable::_has_work = false;
114 volatile bool StringTable::_needs_rehashing = false;
115 OopStorage* StringTable::_oop_storage;
116
117 static size_t _current_size = 0;
118 static volatile size_t _items_count = 0;
119 DEBUG_ONLY(static bool _disable_interning_during_cds_dump = false);
120
121 volatile bool _alt_hash = false;
122
123 static bool _rehashed = false;
124 static uint64_t _alt_hash_seed = 0;
125
126 enum class StringType {
127 OopStr, UnicodeStr, SymbolStr, UTF8Str
128 };
129
130 struct StringWrapperInternal {
131 union {
132 const Handle oop_str;
133 const jchar* unicode_str;
134 const Symbol* symbol_str;
135 const char* utf8_str;
136 };
137 const StringType type;
138 const size_t length;
139
331 void StringTable::item_removed() {
332 Atomic::dec(&_items_count);
333 }
334
335 double StringTable::get_load_factor() {
336 return double(_items_count)/double(_current_size);
337 }
338
339 double StringTable::get_dead_factor(size_t num_dead) {
340 return double(num_dead)/double(_current_size);
341 }
342
343 size_t StringTable::table_size() {
344 return ((size_t)1) << _local_table->get_size_log2(Thread::current());
345 }
346
347 bool StringTable::has_work() {
348 return Atomic::load_acquire(&_has_work);
349 }
350
351 size_t StringTable::items_count_acquire() {
352 return Atomic::load_acquire(&_items_count);
353 }
354
355 void StringTable::trigger_concurrent_work() {
356 // Avoid churn on ServiceThread
357 if (!has_work()) {
358 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
359 Atomic::store(&_has_work, true);
360 Service_lock->notify_all();
361 }
362 }
363
364 // Probing
365 oop StringTable::lookup(Symbol* symbol) {
366 ResourceMark rm;
367 int length;
368 jchar* chars = symbol->as_unicode(length);
369 return lookup(chars, length);
370 }
371
372 oop StringTable::lookup(const jchar* name, int len) {
373 unsigned int hash = java_lang_String::hash_code(name, len);
374 StringWrapper wrapped_name(name, len);
493 }
494
495 oop StringTable::intern(oop string, TRAPS) {
496 if (string == nullptr) return nullptr;
497 int length = java_lang_String::length(string);
498 Handle h_string (THREAD, string);
499 StringWrapper name(h_string, length);
500 oop result = intern(name, CHECK_NULL);
501 return result;
502 }
503
504 oop StringTable::intern(const char* utf8_string, TRAPS) {
505 if (utf8_string == nullptr) return nullptr;
506 size_t length = strlen(utf8_string);
507 StringWrapper name(utf8_string, length);
508 oop result = intern(name, CHECK_NULL);
509 return result;
510 }
511
512 oop StringTable::intern(const StringWrapper& name, TRAPS) {
513 assert(!Atomic::load_acquire(&_disable_interning_during_cds_dump),
514 "All threads that may intern strings should have been stopped before CDS starts copying the interned string table");
515
516 // shared table always uses java_lang_String::hash_code
517 unsigned int hash = hash_wrapped_string(name);
518 oop found_string = lookup_shared(name, hash);
519 if (found_string != nullptr) {
520 return found_string;
521 }
522
523 if (_alt_hash) {
524 ResourceMark rm(THREAD);
525 // Convert to unicode for alt hashing
526 int unicode_length;
527 const jchar* chars = to_unicode(name, unicode_length, CHECK_NULL);
528 hash = hash_string(chars, unicode_length, true);
529 }
530
531 found_string = do_lookup(name, hash);
532 if (found_string != nullptr) {
533 return found_string;
534 }
535 return do_intern(name, hash, THREAD);
785
786 // Verification
787 class VerifyStrings : StackObj {
788 public:
789 bool operator()(WeakHandle* val) {
790 oop s = val->peek();
791 if (s != nullptr) {
792 assert(java_lang_String::length(s) >= 0, "Length on string must work.");
793 }
794 return true;
795 };
796 };
797
798 // This verification is part of Universe::verify() and needs to be quick.
799 void StringTable::verify() {
800 VerifyStrings vs;
801 _local_table->do_safepoint_scan(vs);
802 }
803
804 // Verification and comp
805 class StringTable::VerifyCompStrings : StackObj {
806 static unsigned string_hash(oop const& str) {
807 return java_lang_String::hash_code_noupdate(str);
808 }
809 static bool string_equals(oop const& a, oop const& b) {
810 return java_lang_String::equals(a, b);
811 }
812
813 ResizeableResourceHashtable<oop, bool, AnyObj::C_HEAP, mtInternal,
814 string_hash, string_equals> _table;
815 public:
816 size_t _errors;
817 VerifyCompStrings() : _table(unsigned(items_count_acquire() / 8) + 1, 0 /* do not resize */), _errors(0) {}
818 bool operator()(WeakHandle* val) {
819 oop s = val->resolve();
820 if (s == nullptr) {
821 return true;
822 }
823 bool created;
824 _table.put_if_absent(s, true, &created);
825 assert(created, "Duplicate strings");
826 if (!created) {
827 _errors++;
828 }
829 return true;
830 };
831 };
832
833 size_t StringTable::verify_and_compare_entries() {
834 Thread* thr = Thread::current();
835 VerifyCompStrings vcs;
836 _local_table->do_scan(thr, vcs);
837 return vcs._errors;
931
932 // Sharing
933 #if INCLUDE_CDS_JAVA_HEAP
934 size_t StringTable::shared_entry_count() {
935 return _shared_table.entry_count();
936 }
937
938 oop StringTable::lookup_shared(const StringWrapper& name, unsigned int hash) {
939 assert(hash == hash_wrapped_string(name),
940 "hash must be computed using java_lang_String::hash_code");
941 // len is required but is already part of StringWrapper, so 0 is used
942 return _shared_table.lookup(name, hash, 0);
943 }
944
945 oop StringTable::lookup_shared(const jchar* name, int len) {
946 StringWrapper wrapped_name(name, len);
947 // len is required but is already part of StringWrapper, so 0 is used
948 return _shared_table.lookup(wrapped_name, java_lang_String::hash_code(name, len), 0);
949 }
950
951 // This is called BEFORE we enter the CDS safepoint. We can still allocate Java object arrays to
952 // be used by the shared strings table.
953 void StringTable::allocate_shared_strings_array(TRAPS) {
954 if (!CDSConfig::is_dumping_heap()) {
955 return;
956 }
957
958 CompileBroker::wait_for_no_active_tasks();
959
960 precond(CDSConfig::allow_only_single_java_thread());
961
962 // At this point, no more strings will be added:
963 // - There's only a single Java thread (this thread). It no longer executes Java bytecodes
964 // so JIT compilation will eventually stop.
965 // - CompileBroker has no more active tasks, so all JIT requests have been processed.
966
967 // This flag will be cleared after intern table dumping has completed, so we can run the
968 // compiler again (for future AOT method compilation, etc).
969 DEBUG_ONLY(Atomic::release_store(&_disable_interning_during_cds_dump, true));
970
971 if (items_count_acquire() > (size_t)max_jint) {
972 fatal("Too many strings to be archived: %zu", items_count_acquire());
973 }
974
975 int total = (int)items_count_acquire();
976 size_t single_array_size = objArrayOopDesc::object_size(total);
977
978 log_info(aot)("allocated string table for %d strings", total);
979
980 if (!ArchiveHeapWriter::is_too_large_to_archive(single_array_size)) {
981 // The entire table can fit in a single array
982 objArrayOop array = oopFactory::new_objArray(vmClasses::Object_klass(), total, CHECK);
983 _shared_strings_array = OopHandle(Universe::vm_global(), array);
984 log_info(aot)("string table array (single level) length = %d", total);
985 } else {
986 // Split the table in two levels of arrays.
987 int primary_array_length = (total + _secondary_array_max_length - 1) / _secondary_array_max_length;
988 size_t primary_array_size = objArrayOopDesc::object_size(primary_array_length);
989 size_t secondary_array_size = objArrayOopDesc::object_size(_secondary_array_max_length);
990
991 if (ArchiveHeapWriter::is_too_large_to_archive(secondary_array_size)) {
992 // This can only happen if you have an extremely large number of classes that
993 // refer to more than 16384 * 16384 = 26M interned strings! Not a practical concern
994 // but bail out for safety.
995 log_error(aot)("Too many strings to be archived: %zu", items_count_acquire());
996 MetaspaceShared::unrecoverable_writing_error();
997 }
998
999 objArrayOop primary = oopFactory::new_objArray(vmClasses::Object_klass(), primary_array_length, CHECK);
1000 objArrayHandle primaryHandle(THREAD, primary);
1001 _shared_strings_array = OopHandle(Universe::vm_global(), primary);
1002
1003 log_info(aot)("string table array (primary) length = %d", primary_array_length);
1004 for (int i = 0; i < primary_array_length; i++) {
1005 int len;
1006 if (total > _secondary_array_max_length) {
1007 len = _secondary_array_max_length;
1008 } else {
1009 len = total;
1010 }
1011 total -= len;
1012
1013 objArrayOop secondary = oopFactory::new_objArray(vmClasses::Object_klass(), len, CHECK);
1014 primaryHandle()->obj_at_put(i, secondary);
1015
1073
1074 assert(primary_index < array->length(), "no strings should have been added");
1075 objArrayOop secondary = (objArrayOop)array->obj_at(primary_index);
1076
1077 assert(secondary != nullptr && secondary->is_objArray(), "must be");
1078 assert(secondary_index < secondary->length(), "no strings should have been added");
1079 secondary->obj_at_put(secondary_index, string);
1080 }
1081 index ++;
1082 }
1083 return true;
1084 };
1085
1086 _local_table->do_safepoint_scan(copy_into_array);
1087 log_info(aot)("Archived %d interned strings", index);
1088 return array;
1089 };
1090
1091 void StringTable::write_shared_table() {
1092 _shared_table.reset();
1093 CompactHashtableWriter writer((int)items_count_acquire(), ArchiveBuilder::string_stats());
1094
1095 int index = 0;
1096 auto copy_into_shared_table = [&] (WeakHandle* val) {
1097 oop string = val->peek();
1098 if (string != nullptr && !ArchiveHeapWriter::is_string_too_large_to_archive(string)) {
1099 unsigned int hash = java_lang_String::hash_code(string);
1100 writer.add(hash, index);
1101 index ++;
1102 }
1103 return true;
1104 };
1105 _local_table->do_safepoint_scan(copy_into_shared_table);
1106 writer.dump(&_shared_table, "string");
1107
1108 DEBUG_ONLY(Atomic::release_store(&_disable_interning_during_cds_dump, false));
1109 }
1110
1111 void StringTable::set_shared_strings_array_index(int root_index) {
1112 _shared_strings_array_root_index = root_index;
1113 }
1114
1115 void StringTable::serialize_shared_table_header(SerializeClosure* soc) {
1116 if (soc->writing() && !CDSConfig::is_dumping_heap()) {
1117 _shared_table.reset();
1118 _is_two_dimensional_shared_strings_array = false;
1119 _shared_strings_array_root_index = -1;
1120 }
1121
1122 _shared_table.serialize_header(soc);
1123
1124 if (soc->writing()) {
1125 // Sanity. Make sure we don't use the shared table at dump time
1126 _shared_table.reset();
1127 } else if (!ArchiveHeapLoader::is_in_use()) {
1128 _shared_table.reset();
1129 }
1130
1131 soc->do_bool(&_is_two_dimensional_shared_strings_array);
1132 soc->do_int(&_shared_strings_array_root_index);
1133 }
1134 #endif //INCLUDE_CDS_JAVA_HEAP
|