diff -r d4f3e37d1fda -r f4e3900c8d08 src/hotspot/share/memory/metaspaceShared.cpp --- a/src/hotspot/share/memory/metaspaceShared.cpp Tue Nov 13 21:43:10 2018 -0500 +++ b/src/hotspot/share/memory/metaspaceShared.cpp Wed Nov 07 19:40:27 2018 -0800 @@ -64,7 +64,6 @@ #include "utilities/align.hpp" #include "utilities/bitMap.hpp" #include "utilities/defaultStream.hpp" -#include "utilities/hashtable.inline.hpp" #if INCLUDE_G1GC #include "gc/g1/g1CollectedHeap.hpp" #endif @@ -124,6 +123,15 @@ MetaspaceShared::report_out_of_space(_name, newtop - _top); ShouldNotReachHere(); } + uintx delta = MetaspaceShared::object_delta_uintx(newtop); + if (delta > MAX_SHARED_DELTA) { + // This is just a sanity check and should not appear in any real world usage. This + // happens only if you allocate more than 2GB of shared objects and would require + // millions of shared classes. + vm_exit_during_initialization("Out of memory in the CDS archive", + "Please reduce the number of shared classes."); + } + MetaspaceShared::commit_shared_space_to(newtop); _top = newtop; return _top; @@ -323,6 +331,7 @@ } _mc_region.init(&_shared_rs); + SharedBaseAddress = (size_t)_shared_rs.base(); tty->print_cr("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT, _shared_rs.size(), p2i(_shared_rs.base())); } @@ -416,6 +425,7 @@ SymbolTable::serialize_shared_table_header(soc); StringTable::serialize_shared_table_header(soc); HeapShared::serialize_subgraph_info_table_header(soc); + SystemDictionaryShared::serialize_dictionary_headers(soc); JavaClasses::serialize_offsets(soc); InstanceMirrorKlass::serialize_offsets(soc); @@ -464,13 +474,11 @@ class CollectClassesClosure : public KlassClosure { void do_klass(Klass* k) { - if (!(k->is_instance_klass() && InstanceKlass::cast(k)->is_in_error_state())) { - if (k->is_instance_klass() && InstanceKlass::cast(k)->signers() != NULL) { - // Mark any class with signers and don't add to the _global_klass_objects - k->set_has_signer_and_not_archived(); - } else { - _global_klass_objects->append_if_missing(k); - } + if (k->is_instance_klass() && + SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(k))) { + // Don't add to the _global_klass_objects + } else { + _global_klass_objects->append_if_missing(k); } if (k->is_array_klass()) { // Add in the array classes too @@ -577,16 +585,6 @@ } } -NOT_PRODUCT( -static void assert_not_unsafe_anonymous_class(InstanceKlass* k) { - assert(!(k->is_unsafe_anonymous()), "cannot archive unsafe anonymous classes"); -} - -// Unsafe anonymous classes are not stored inside any dictionaries. -static void assert_no_unsafe_anonymous_classes_in_dictionaries() { - ClassLoaderDataGraph::dictionary_classes_do(assert_not_unsafe_anonymous_class); -}) - // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. // (In GCC this is the field ::_vptr, i.e., first word in the object.) // @@ -1123,6 +1121,17 @@ newtop = _ro_region.top(); } else { oldtop = _rw_region.top(); + if (ref->msotype() == MetaspaceObj::ClassType) { + // Save a pointer immediate in front of an InstanceKlass, so + // we can do a quick lookup from InstanceKlass* -> RunTimeSharedClassInfo* + // without building another hashtable. See RunTimeSharedClassInfo::get_for() + // in systemDictionaryShared.cpp. + Klass* klass = (Klass*)obj; + if (klass->is_instance_klass()) { + SystemDictionaryShared::validate_before_archiving(InstanceKlass::cast(klass)); + _rw_region.allocate(sizeof(address), BytesPerWord); + } + } p = _rw_region.allocate(bytes, alignment); newtop = _rw_region.top(); } @@ -1132,16 +1141,6 @@ assert(isnew, "must be"); _alloc_stats->record(ref->msotype(), int(newtop - oldtop), read_only); - if (ref->msotype() == MetaspaceObj::SymbolType) { - uintx delta = MetaspaceShared::object_delta(p); - if (delta > MAX_SHARED_DELTA) { - // This is just a sanity check and should not appear in any real world usage. This - // happens only if you allocate more than 2GB of Symbols and would require - // millions of shared classes. - vm_exit_during_initialization("Too many Symbols in the CDS archive", - "Please reduce the number of shared classes."); - } - } } static address get_new_loc(MetaspaceClosure::Ref* ref) { @@ -1281,7 +1280,7 @@ } } FileMapInfo::metaspace_pointers_do(it); - SystemDictionary::classes_do(it); + SystemDictionaryShared::dumptime_classes_do(it); Universe::metaspace_pointers_do(it); SymbolTable::metaspace_pointers_do(it); vmSymbols::metaspace_pointers_do(it); @@ -1315,9 +1314,6 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables() { ArchiveCompactor::OtherROAllocMark mark; - // Reorder the system dictionary. Moving the symbols affects - // how the hash table indices are calculated. - SystemDictionary::reorder_dictionary_for_sharing(); tty->print("Removing java_mirror ... "); if (!HeapShared::is_heap_object_archiving_allowed()) { @@ -1325,15 +1321,10 @@ } remove_java_mirror_in_classes(); tty->print_cr("done. "); - NOT_PRODUCT(SystemDictionary::verify();) - size_t buckets_bytes = SystemDictionary::count_bytes_for_buckets(); - char* buckets_top = _ro_region.allocate(buckets_bytes, sizeof(intptr_t)); - SystemDictionary::copy_buckets(buckets_top, _ro_region.top()); + SystemDictionaryShared::write_to_archive(); - size_t table_bytes = SystemDictionary::count_bytes_for_table(); - char* table_top = _ro_region.allocate(table_bytes, sizeof(intptr_t)); - SystemDictionary::copy_table(table_top, _ro_region.top()); + char* start = _ro_region.top(); // Write the other data to the output array. WriteClosure wc(&_ro_region); @@ -1342,7 +1333,7 @@ // Write the bitmaps for patching the archive heap regions dump_archive_heap_oopmaps(); - return buckets_top; + return start; } void VM_PopulateDumpSharedSpace::doit() { @@ -1367,14 +1358,11 @@ "loader constraints are not saved"); guarantee(SystemDictionary::placeholders()->number_of_entries() == 0, "placeholders are not saved"); - // Revisit and implement this if we prelink method handle call sites: - guarantee(SystemDictionary::invoke_method_table() == NULL || - SystemDictionary::invoke_method_table()->number_of_entries() == 0, - "invoke method table is not saved"); // At this point, many classes have been loaded. // Gather systemDictionary classes in a global array and do everything to // that so we don't have to walk the SystemDictionary again. + SystemDictionaryShared::check_excluded_classes(); _global_klass_objects = new GrowableArray(1000); CollectClassesClosure collect_classes; ClassLoaderDataGraph::loaded_classes_do(&collect_classes); @@ -1403,21 +1391,11 @@ rewrite_nofast_bytecodes_and_calculate_fingerprints(); tty->print_cr("done. "); - // Move classes from platform/system dictionaries into the boot dictionary - SystemDictionary::combine_shared_dictionaries(); - - // Make sure all classes have a correct loader type. - ClassLoaderData::the_null_class_loader_data()->dictionary()->classes_do(MetaspaceShared::check_shared_class_loader_type); - // Remove all references outside the metadata tty->print("Removing unshareable information ... "); remove_unshareable_in_classes(); tty->print_cr("done. "); - // We don't support archiving unsafe anonymous classes. Verify that they are not stored in - // any dictionaries. - NOT_PRODUCT(assert_no_unsafe_anonymous_classes_in_dictionaries()); - ArchiveCompactor::initialize(); ArchiveCompactor::copy_and_compact(); @@ -1466,6 +1444,7 @@ mapinfo->set_core_spaces_size(core_spaces_size); for (int pass=1; pass<=2; pass++) { + bool print_archive_log = (pass==1); if (pass == 1) { // The first pass doesn't actually write the data to disk. All it // does is to update the fields in the mapinfo->_header. @@ -1490,12 +1469,14 @@ _closed_archive_heap_regions, _closed_archive_heap_oopmaps, MetaspaceShared::first_closed_archive_heap_region, - MetaspaceShared::max_closed_archive_heap_region); + MetaspaceShared::max_closed_archive_heap_region, + print_archive_log); _total_open_archive_region_size = mapinfo->write_archive_heap_regions( _open_archive_heap_regions, _open_archive_heap_oopmaps, MetaspaceShared::first_open_archive_heap_region, - MetaspaceShared::max_open_archive_heap_region); + MetaspaceShared::max_open_archive_heap_region, + print_archive_log); } mapinfo->close(); @@ -1608,17 +1589,6 @@ } }; -void MetaspaceShared::check_shared_class_loader_type(InstanceKlass* ik) { - ResourceMark rm; - if (ik->shared_classpath_index() == UNREGISTERED_INDEX) { - guarantee(ik->loader_type() == 0, - "Class loader type must not be set for this class %s", ik->name()->as_C_string()); - } else { - guarantee(ik->loader_type() != 0, - "Class loader type must be set for this class %s", ik->name()->as_C_string()); - } -} - void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) { // We need to iterate because verification may cause additional classes // to be loaded. @@ -1639,9 +1609,6 @@ check_closure.reset(); ClassLoaderDataGraph::unlocked_loaded_classes_do(&check_closure); } while (check_closure.made_progress()); - - // Unverifiable classes will not be included in the CDS archive. - SystemDictionary::remove_classes_in_error_state(); } } @@ -1717,10 +1684,6 @@ link_and_cleanup_shared_classes(CATCH); tty->print_cr("Rewriting and linking classes: done"); - SystemDictionary::clear_invoke_method_table(); - - SystemDictionaryShared::finalize_verification_constraints(); - VM_PopulateDumpSharedSpace op; VMThread::execute(&op); } @@ -1731,36 +1694,36 @@ ClassListParser parser(class_list_path); int class_count = 0; - while (parser.parse_one_line()) { - Klass* klass = ClassLoaderExt::load_one_class(&parser, THREAD); - if (HAS_PENDING_EXCEPTION) { - if (klass == NULL && - (PENDING_EXCEPTION->klass()->name() == vmSymbols::java_lang_ClassNotFoundException())) { - // print a warning only when the pending exception is class not found - tty->print_cr("Preload Warning: Cannot find %s", parser.current_class_name()); - } - CLEAR_PENDING_EXCEPTION; + while (parser.parse_one_line()) { + Klass* klass = parser.load_current_class(THREAD); + if (HAS_PENDING_EXCEPTION) { + if (klass == NULL && + (PENDING_EXCEPTION->klass()->name() == vmSymbols::java_lang_ClassNotFoundException())) { + // print a warning only when the pending exception is class not found + tty->print_cr("Preload Warning: Cannot find %s", parser.current_class_name()); + } + CLEAR_PENDING_EXCEPTION; + } + if (klass != NULL) { + if (log_is_enabled(Trace, cds)) { + ResourceMark rm; + log_trace(cds)("Shared spaces preloaded: %s", klass->external_name()); } - if (klass != NULL) { - if (log_is_enabled(Trace, cds)) { - ResourceMark rm; - log_trace(cds)("Shared spaces preloaded: %s", klass->external_name()); - } - if (klass->is_instance_klass()) { - InstanceKlass* ik = InstanceKlass::cast(klass); + if (klass->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(klass); - // Link the class to cause the bytecodes to be rewritten and the - // cpcache to be created. The linking is done as soon as classes - // are loaded in order that the related data structures (klass and - // cpCache) are located together. - try_link_class(ik, THREAD); - guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class"); - } + // Link the class to cause the bytecodes to be rewritten and the + // cpcache to be created. The linking is done as soon as classes + // are loaded in order that the related data structures (klass and + // cpCache) are located together. + try_link_class(ik, THREAD); + guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class"); + } - class_count++; - } + class_count++; } + } return class_count; } @@ -1994,21 +1957,6 @@ // The rest of the data is now stored in the RW region buffer = mapinfo->read_only_tables_start(); - int sharedDictionaryLen = *(intptr_t*)buffer; - buffer += sizeof(intptr_t); - int number_of_entries = *(intptr_t*)buffer; - buffer += sizeof(intptr_t); - SystemDictionary::set_shared_dictionary((HashtableBucket*)buffer, - sharedDictionaryLen, - number_of_entries); - buffer += sharedDictionaryLen; - - // The following data are the linked list elements - // (HashtableEntry objects) for the shared dictionary table. - - int len = *(intptr_t*)buffer; // skip over shared dictionary entries - buffer += sizeof(intptr_t); - buffer += len; // Verify various attributes of the archive, plus initialize the // shared string/symbol tables @@ -2027,7 +1975,7 @@ if (PrintSharedArchiveAndExit) { if (PrintSharedDictionary) { tty->print_cr("\nShared classes:\n"); - SystemDictionary::print_shared(tty); + SystemDictionaryShared::print_on(tty); } if (_archive_loading_failed) { tty->print_cr("archive is invalid");