diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 4eaa0a26b17..46af33af146 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -430,6 +430,12 @@ void HeapShared::archive_strings() { StringTable::set_shared_strings_array_index(append_root(shared_strings_array)); } +int HeapShared::archive_exception_instance(oop exception) { + bool success = archive_reachable_objects_from(1, _default_subgraph_info, exception); + assert(success, "sanity"); + return append_root(exception); +} + void HeapShared::mark_native_pointers(oop orig_obj) { if (java_lang_Class::is_instance(orig_obj)) { ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::klass_offset()); @@ -589,6 +595,7 @@ void HeapShared::copy_special_objects() { init_seen_objects_table(); archive_java_mirrors(); archive_strings(); + Universe::archive_exception_instances(); delete_seen_objects_table(); } @@ -1387,11 +1394,15 @@ void HeapShared::check_default_subgraph_classes() { i, subgraph_k->external_name()); } - guarantee(subgraph_k->name()->equals("java/lang/Class") || - subgraph_k->name()->equals("java/lang/String") || - subgraph_k->name()->equals("[Ljava/lang/Object;") || - subgraph_k->name()->equals("[C") || - subgraph_k->name()->equals("[B"), + Symbol* name = ArchiveBuilder::current()->get_source_addr(subgraph_k->name()); + guarantee(name == vmSymbols::java_lang_Class() || + name == vmSymbols::java_lang_String() || + name == vmSymbols::java_lang_ArithmeticException() || + name == vmSymbols::java_lang_NullPointerException() || + name == vmSymbols::java_lang_VirtualMachineError() || + name == vmSymbols::object_array_signature() || + name == vmSymbols::byte_array_signature() || + name == vmSymbols::char_array_signature(), "default subgraph can have only these objects"); } } diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index e1b73eeced7..f66de5c5e95 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -365,6 +365,7 @@ private: return _archived_object_cache; } + static int archive_exception_instance(oop exception); static void archive_objects(ArchiveHeapInfo* heap_info); static void copy_objects(); static void copy_special_objects(); diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index a133b0e916b..95cf4dfa791 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -1466,8 +1466,7 @@ void MetaspaceShared::initialize_shared_spaces() { // done after ReadClosure. static_mapinfo->patch_heap_embedded_pointers(); ArchiveHeapLoader::finish_initialization(); - - CDS_JAVA_HEAP_ONLY(Universe::update_archived_basic_type_mirrors()); + Universe::load_archived_object_instances(); // Close the mapinfo file static_mapinfo->close(); diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index 0f29c7c005e..eacede462db 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -149,10 +149,6 @@ volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0; OopHandle Universe::_msg_metaspace; OopHandle Universe::_msg_class_metaspace; -OopHandle Universe::_null_ptr_exception_instance; -OopHandle Universe::_arithmetic_exception_instance; -OopHandle Universe::_virtual_machine_error_instance; - OopHandle Universe::_reference_pending_list; Array* Universe::_the_array_interfaces_array = nullptr; @@ -186,6 +182,52 @@ OopStorage* Universe::_vm_global = nullptr; CollectedHeap* Universe::_collectedHeap = nullptr; +// These are the exceptions that are always created and are guatanteed to exist. +// If possible, they can be stored as CDS archived objects to speed up AOT code. +class BuiltinException { + OopHandle _instance; + CDS_JAVA_HEAP_ONLY(int _archived_root_index;) + +public: + BuiltinException() : _instance() { + CDS_JAVA_HEAP_ONLY(_archived_root_index = 0); + } + + void init_if_empty(Symbol* symbol, TRAPS) { + if (_instance.is_empty()) { + Klass* k = SystemDictionary::resolve_or_fail(symbol, true, CHECK); + oop obj = InstanceKlass::cast(k)->allocate_instance(CHECK); + _instance = OopHandle(Universe::vm_global(), obj); + } + } + + oop instance() { + return _instance.resolve(); + } + +#if INCLUDE_CDS_JAVA_HEAP + void store_in_cds() { + _archived_root_index = HeapShared::archive_exception_instance(instance()); + } + + void load_from_cds() { + if (_archived_root_index >= 0) { + oop obj = HeapShared::get_root(_archived_root_index); + assert(obj != nullptr, "must be"); + _instance = OopHandle(Universe::vm_global(), obj); + } + } + + void serialize(SerializeClosure *f) { + f->do_int(&_archived_root_index); + } +#endif +}; + +static BuiltinException _null_ptr_exception; +static BuiltinException _arithmetic_exception; +static BuiltinException _virtual_machine_error; + objArrayOop Universe::the_empty_class_array () { return (objArrayOop)_the_empty_class_array.resolve(); } @@ -199,9 +241,9 @@ void Universe::set_system_thread_group(oop group) { _system_thread_group = OopHa oop Universe::the_null_string() { return _the_null_string.resolve(); } oop Universe::the_min_jint_string() { return _the_min_jint_string.resolve(); } -oop Universe::null_ptr_exception_instance() { return _null_ptr_exception_instance.resolve(); } -oop Universe::arithmetic_exception_instance() { return _arithmetic_exception_instance.resolve(); } -oop Universe::virtual_machine_error_instance() { return _virtual_machine_error_instance.resolve(); } +oop Universe::null_ptr_exception_instance() { return _null_ptr_exception.instance(); } +oop Universe::arithmetic_exception_instance() { return _arithmetic_exception.instance(); } +oop Universe::virtual_machine_error_instance() { return _virtual_machine_error.instance(); } oop Universe::the_null_sentinel() { return _the_null_sentinel.resolve(); } @@ -254,7 +296,13 @@ void Universe::set_archived_basic_type_mirror_index(BasicType t, int index) { _archived_basic_type_mirror_indices[t] = index; } -void Universe::update_archived_basic_type_mirrors() { +void Universe::archive_exception_instances() { + _null_ptr_exception.store_in_cds(); + _arithmetic_exception.store_in_cds(); + _virtual_machine_error.store_in_cds(); +} + +void Universe::load_archived_object_instances() { if (ArchiveHeapLoader::is_in_use()) { for (int i = T_BOOLEAN; i < T_VOID+1; i++) { int index = _archived_basic_type_mirror_indices[i]; @@ -264,6 +312,10 @@ void Universe::update_archived_basic_type_mirrors() { _basic_type_mirrors[i] = OopHandle(vm_global(), mirror_oop); } } + + _null_ptr_exception.load_from_cds(); + _arithmetic_exception.load_from_cds(); + _virtual_machine_error.load_from_cds(); } } #endif @@ -275,8 +327,11 @@ void Universe::serialize(SerializeClosure* f) { f->do_int(&_archived_basic_type_mirror_indices[i]); // if f->reading(): We can't call HeapShared::get_root() yet, as the heap // contents may need to be relocated. _basic_type_mirrors[i] will be - // updated later in Universe::update_archived_basic_type_mirrors(). + // updated later in Universe::load_archived_object_instances(). } + _null_ptr_exception.serialize(f); + _arithmetic_exception.serialize(f); + _virtual_machine_error.serialize(f); #endif f->do_ptr(&_fillerArrayKlassObj); @@ -1021,27 +1076,19 @@ bool universe_post_init() { Universe::_delayed_stack_overflow_error_message = OopHandle(Universe::vm_global(), instance); } - // Setup preallocated NullPointerException - // (this is currently used for a cheap & dirty solution in compiler exception handling) - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false); - instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false); - Universe::_null_ptr_exception_instance = OopHandle(Universe::vm_global(), instance); - - // Setup preallocated ArithmeticException - // (this is currently used for a cheap & dirty solution in compiler exception handling) - k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ArithmeticException(), true, CHECK_false); - instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false); - Universe::_arithmetic_exception_instance = OopHandle(Universe::vm_global(), instance); + // Setup preallocated NullPointerException/ArithmeticException + // (used for a cheap & dirty solution in compiler exception handling) + _null_ptr_exception.init_if_empty(vmSymbols::java_lang_NullPointerException(), CHECK_false); + _arithmetic_exception.init_if_empty(vmSymbols::java_lang_ArithmeticException(), CHECK_false); // Virtual Machine Error for when we get into a situation we can't resolve - k = vmClasses::VirtualMachineError_klass(); + Klass* k = vmClasses::VirtualMachineError_klass(); bool linked = InstanceKlass::cast(k)->link_class_or_fail(CHECK_false); if (!linked) { tty->print_cr("Unable to link/verify VirtualMachineError class"); return false; // initialization failed } - instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false); - Universe::_virtual_machine_error_instance = OopHandle(Universe::vm_global(), instance); + _virtual_machine_error.init_if_empty(vmSymbols::java_lang_VirtualMachineError(), CHECK_false); Handle msg = java_lang_String::create_from_str("/ by zero", CHECK_false); java_lang_Throwable::set_message(Universe::arithmetic_exception_instance(), msg()); diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp index 87faf8973ae..f56889559b8 100644 --- a/src/hotspot/share/memory/universe.hpp +++ b/src/hotspot/share/memory/universe.hpp @@ -106,10 +106,6 @@ class Universe: AllStatic { static OopHandle _msg_metaspace; static OopHandle _msg_class_metaspace; - static OopHandle _null_ptr_exception_instance; // preallocated exception object - static OopHandle _arithmetic_exception_instance; // preallocated exception object - static OopHandle _virtual_machine_error_instance; // preallocated exception object - // References waiting to be transferred to the ReferenceHandler static OopHandle _reference_pending_list; @@ -211,9 +207,10 @@ class Universe: AllStatic { static oop java_mirror(BasicType t); + static void load_archived_object_instances() NOT_CDS_JAVA_HEAP_RETURN; #if INCLUDE_CDS_JAVA_HEAP static void set_archived_basic_type_mirror_index(BasicType t, int index); - static void update_archived_basic_type_mirrors(); + static void archive_exception_instances(); #endif static oop main_thread_group();