3232#include " classfile/javaClasses.inline.hpp"
3333#include " classfile/stringTable.hpp"
3434#include " classfile/vmClasses.hpp"
35+ #include " compiler/compileBroker.hpp"
3536#include " gc/shared/collectedHeap.hpp"
3637#include " gc/shared/oopStorage.inline.hpp"
3738#include " gc/shared/oopStorageSet.hpp"
@@ -115,6 +116,7 @@ OopStorage* StringTable::_oop_storage;
115116
116117static size_t _current_size = 0 ;
117118static volatile size_t _items_count = 0 ;
119+ DEBUG_ONLY (static bool _disable_interning_during_cds_dump = false );
118120
119121volatile bool _alt_hash = false ;
120122
@@ -346,6 +348,10 @@ bool StringTable::has_work() {
346348 return Atomic::load_acquire (&_has_work);
347349}
348350
351+ size_t StringTable::items_count_acquire () {
352+ return Atomic::load_acquire (&_items_count);
353+ }
354+
349355void StringTable::trigger_concurrent_work () {
350356 // Avoid churn on ServiceThread
351357 if (!has_work ()) {
@@ -504,6 +510,9 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
504510}
505511
506512oop 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+
507516 // shared table always uses java_lang_String::hash_code
508517 unsigned int hash = hash_wrapped_string (name);
509518 oop found_string = lookup_shared (name, hash);
@@ -793,7 +802,7 @@ void StringTable::verify() {
793802}
794803
795804// Verification and comp
796- class VerifyCompStrings : StackObj {
805+ class StringTable :: VerifyCompStrings : StackObj {
797806 static unsigned string_hash (oop const & str) {
798807 return java_lang_String::hash_code_noupdate (str);
799808 }
@@ -805,7 +814,7 @@ class VerifyCompStrings : StackObj {
805814 string_hash, string_equals> _table;
806815 public:
807816 size_t _errors;
808- VerifyCompStrings () : _table(unsigned (_items_count / 8 ) + 1 , 0 /* do not resize */ ), _errors(0 ) {}
817+ VerifyCompStrings () : _table(unsigned (items_count_acquire() / 8 ) + 1 , 0 /* do not resize */ ), _errors(0 ) {}
809818 bool operator ()(WeakHandle* val) {
810819 oop s = val->resolve ();
811820 if (s == nullptr ) {
@@ -939,20 +948,31 @@ oop StringTable::lookup_shared(const jchar* name, int len) {
939948 return _shared_table.lookup (wrapped_name, java_lang_String::hash_code (name, len), 0 );
940949}
941950
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.)
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.
945953void StringTable::allocate_shared_strings_array (TRAPS) {
946954 if (!CDSConfig::is_dumping_heap ()) {
947955 return ;
948956 }
949- assert (CDSConfig::allow_only_single_java_thread (), " No more interned strings can be added" );
950957
951- if (_items_count > (size_t )max_jint) {
952- fatal (" Too many strings to be archived: %zu" , _items_count);
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 ());
953973 }
954974
955- int total = (int )_items_count ;
975+ int total = (int )items_count_acquire () ;
956976 size_t single_array_size = objArrayOopDesc::object_size (total);
957977
958978 log_info (aot)(" allocated string table for %d strings" , total);
@@ -972,7 +992,7 @@ void StringTable::allocate_shared_strings_array(TRAPS) {
972992 // This can only happen if you have an extremely large number of classes that
973993 // refer to more than 16384 * 16384 = 26M interned strings! Not a practical concern
974994 // but bail out for safety.
975- log_error (aot)(" Too many strings to be archived: %zu" , _items_count );
995+ log_error (aot)(" Too many strings to be archived: %zu" , items_count_acquire () );
976996 MetaspaceShared::unrecoverable_writing_error ();
977997 }
978998
@@ -1070,7 +1090,7 @@ oop StringTable::init_shared_strings_array() {
10701090
10711091void StringTable::write_shared_table () {
10721092 _shared_table.reset ();
1073- CompactHashtableWriter writer ((int )_items_count , ArchiveBuilder::string_stats ());
1093+ CompactHashtableWriter writer ((int )items_count_acquire () , ArchiveBuilder::string_stats ());
10741094
10751095 int index = 0 ;
10761096 auto copy_into_shared_table = [&] (WeakHandle* val) {
@@ -1084,6 +1104,8 @@ void StringTable::write_shared_table() {
10841104 };
10851105 _local_table->do_safepoint_scan (copy_into_shared_table);
10861106 writer.dump (&_shared_table, " string" );
1107+
1108+ DEBUG_ONLY (Atomic::release_store (&_disable_interning_during_cds_dump, false ));
10871109}
10881110
10891111void StringTable::set_shared_strings_array_index (int root_index) {
0 commit comments