Skip to content

Commit

Permalink
8329135: Store Universe::*exception_instance() in CDS archive
Browse files Browse the repository at this point in the history
Reviewed-by: vlivanov, ccheung
  • Loading branch information
iklam committed Apr 2, 2024
1 parent a85c849 commit d3fc8df
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 35 deletions.
21 changes: 16 additions & 5 deletions src/hotspot/share/cds/heapShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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");
}
}
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/cds/heapShared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ class HeapShared: AllStatic {
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();
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/share/cds/metaspaceShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
93 changes: 70 additions & 23 deletions src/hotspot/share/memory/universe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Klass*>* Universe::_the_array_interfaces_array = nullptr;
Expand Down Expand Up @@ -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();
}
Expand All @@ -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(); }

Expand Down Expand Up @@ -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];
Expand All @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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());
Expand Down
7 changes: 2 additions & 5 deletions src/hotspot/share/memory/universe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
Expand Down

1 comment on commit d3fc8df

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.