diff --git a/src/hotspot/share/gc/shared/memAllocator.hpp b/src/hotspot/share/gc/shared/memAllocator.hpp index f299dd633e5..a0450af4450 100644 --- a/src/hotspot/share/gc/shared/memAllocator.hpp +++ b/src/hotspot/share/gc/shared/memAllocator.hpp @@ -125,23 +125,17 @@ class InternalOOMEMark: public StackObj { public: explicit InternalOOMEMark(JavaThread* thread) { - if (thread != nullptr) { - _outer = thread->is_in_internal_oome_mark(); - thread->set_is_in_internal_oome_mark(true); - _thread = thread; - } else { - _outer = false; - _thread = nullptr; - } + assert(thread != nullptr, "nullptr is not supported"); + _outer = thread->is_in_internal_oome_mark(); + thread->set_is_in_internal_oome_mark(true); + _thread = thread; } ~InternalOOMEMark() { - if (_thread != nullptr) { - // Check that only InternalOOMEMark sets - // JavaThread::_is_in_internal_oome_mark - assert(_thread->is_in_internal_oome_mark(), "must be"); - _thread->set_is_in_internal_oome_mark(_outer); - } + // Check that only InternalOOMEMark sets + // JavaThread::_is_in_internal_oome_mark + assert(_thread->is_in_internal_oome_mark(), "must be"); + _thread->set_is_in_internal_oome_mark(_outer); } JavaThread* thread() const { return _thread; } diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 99f427ee168..9dc0e381df9 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -102,7 +102,7 @@ class RetryableAllocationMark { private: InternalOOMEMark _iom; public: - RetryableAllocationMark(JavaThread* thread, bool activate) : _iom(activate ? thread : nullptr) {} + RetryableAllocationMark(JavaThread* thread) : _iom(thread) {} ~RetryableAllocationMark() { JavaThread* THREAD = _iom.thread(); // For exception macros. if (THREAD != nullptr) { @@ -117,34 +117,29 @@ class RetryableAllocationMark { } }; -JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_instance_common(JavaThread* current, Klass* klass, bool null_on_fail)) +JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_instance_or_null(JavaThread* current, Klass* klass)) JRT_BLOCK; assert(klass->is_klass(), "not a class"); Handle holder(current, klass->klass_holder()); // keep the klass alive InstanceKlass* h = InstanceKlass::cast(klass); { - RetryableAllocationMark ram(current, null_on_fail); + RetryableAllocationMark ram(current); h->check_valid_for_instantiation(true, CHECK); - oop obj; - if (null_on_fail) { - if (!h->is_initialized()) { - // Cannot re-execute class initialization without side effects - // so return without attempting the initialization - return; - } - } else { - // make sure klass is initialized - h->initialize(CHECK); + if (!h->is_initialized()) { + // Cannot re-execute class initialization without side effects + // so return without attempting the initialization + current->set_vm_result(nullptr); + return; } // allocate instance and return via TLS - obj = h->allocate_instance(CHECK); + oop obj = h->allocate_instance(CHECK); current->set_vm_result(obj); } JRT_BLOCK_END; SharedRuntime::on_slowpath_allocation_exit(current); JRT_END -JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array_common(JavaThread* current, Klass* array_klass, jint length, bool null_on_fail)) +JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array_or_null(JavaThread* current, Klass* array_klass, jint length)) JRT_BLOCK; // Note: no handle for klass needed since they are not used // anymore after new_objArray() and no GC can happen before. @@ -153,27 +148,21 @@ JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array_common(JavaThread* current, Klass* oop obj; if (array_klass->is_typeArray_klass()) { BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type(); - RetryableAllocationMark ram(current, null_on_fail); + RetryableAllocationMark ram(current); obj = oopFactory::new_typeArray(elt_type, length, CHECK); } else { Handle holder(current, array_klass->klass_holder()); // keep the klass alive Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass(); - RetryableAllocationMark ram(current, null_on_fail); + RetryableAllocationMark ram(current); obj = oopFactory::new_objArray(elem_klass, length, CHECK); } // This is pretty rare but this runtime patch is stressful to deoptimization // if we deoptimize here so force a deopt to stress the path. if (DeoptimizeALot) { static int deopts = 0; - // Alternate between deoptimizing and raising an error (which will also cause a deopt) if (deopts++ % 2 == 0) { - if (null_on_fail) { - // Drop the allocation - obj = nullptr; - } else { - ResourceMark rm(current); - THROW(vmSymbols::java_lang_OutOfMemoryError()); - } + // Drop the allocation + obj = nullptr; } else { deopt_caller(); } @@ -183,42 +172,38 @@ JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array_common(JavaThread* current, Klass* SharedRuntime::on_slowpath_allocation_exit(current); JRT_END -JRT_ENTRY(void, JVMCIRuntime::new_multi_array_common(JavaThread* current, Klass* klass, int rank, jint* dims, bool null_on_fail)) +JRT_ENTRY(void, JVMCIRuntime::new_multi_array_or_null(JavaThread* current, Klass* klass, int rank, jint* dims)) assert(klass->is_klass(), "not a class"); assert(rank >= 1, "rank must be nonzero"); Handle holder(current, klass->klass_holder()); // keep the klass alive - RetryableAllocationMark ram(current, null_on_fail); + RetryableAllocationMark ram(current); oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK); current->set_vm_result(obj); JRT_END -JRT_ENTRY(void, JVMCIRuntime::dynamic_new_array_common(JavaThread* current, oopDesc* element_mirror, jint length, bool null_on_fail)) - RetryableAllocationMark ram(current, null_on_fail); +JRT_ENTRY(void, JVMCIRuntime::dynamic_new_array_or_null(JavaThread* current, oopDesc* element_mirror, jint length)) + RetryableAllocationMark ram(current); oop obj = Reflection::reflect_new_array(element_mirror, length, CHECK); current->set_vm_result(obj); JRT_END -JRT_ENTRY(void, JVMCIRuntime::dynamic_new_instance_common(JavaThread* current, oopDesc* type_mirror, bool null_on_fail)) +JRT_ENTRY(void, JVMCIRuntime::dynamic_new_instance_or_null(JavaThread* current, oopDesc* type_mirror)) InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(type_mirror)); if (klass == nullptr) { ResourceMark rm(current); THROW(vmSymbols::java_lang_InstantiationException()); } - RetryableAllocationMark ram(current, null_on_fail); + RetryableAllocationMark ram(current); // Create new instance (the receiver) klass->check_valid_for_instantiation(false, CHECK); - if (null_on_fail) { - if (!klass->is_initialized()) { - // Cannot re-execute class initialization without side effects - // so return without attempting the initialization - return; - } - } else { - // Make sure klass gets initialized - klass->initialize(CHECK); + if (!klass->is_initialized()) { + // Cannot re-execute class initialization without side effects + // so return without attempting the initialization + current->set_vm_result(nullptr); + return; } oop obj = klass->allocate_instance(CHECK); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index 6a920eb8c70..123cfde15ac 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -504,34 +504,16 @@ class JVMCIRuntime: public CHeapObj { static BasicType kindToBasicType(const Handle& kind, TRAPS); - static void new_instance_common(JavaThread* current, Klass* klass, bool null_on_fail); - static void new_array_common(JavaThread* current, Klass* klass, jint length, bool null_on_fail); - static void new_multi_array_common(JavaThread* current, Klass* klass, int rank, jint* dims, bool null_on_fail); - static void dynamic_new_array_common(JavaThread* current, oopDesc* element_mirror, jint length, bool null_on_fail); - static void dynamic_new_instance_common(JavaThread* current, oopDesc* type_mirror, bool null_on_fail); - // The following routines are called from compiled JVMCI code - // When allocation fails, these stubs: - // 1. Exercise -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError handling and also - // post a JVMTI_EVENT_RESOURCE_EXHAUSTED event if the failure is an OutOfMemroyError - // 2. Return null with a pending exception. - // Compiled code must ensure these stubs are not called twice for the same allocation - // site due to the non-repeatable side effects in the case of OOME. - static void new_instance(JavaThread* current, Klass* klass) { new_instance_common(current, klass, false); } - static void new_array(JavaThread* current, Klass* klass, jint length) { new_array_common(current, klass, length, false); } - static void new_multi_array(JavaThread* current, Klass* klass, int rank, jint* dims) { new_multi_array_common(current, klass, rank, dims, false); } - static void dynamic_new_array(JavaThread* current, oopDesc* element_mirror, jint length) { dynamic_new_array_common(current, element_mirror, length, false); } - static void dynamic_new_instance(JavaThread* current, oopDesc* type_mirror) { dynamic_new_instance_common(current, type_mirror, false); } - - // When allocation fails, these stubs return null and have no pending exception. Compiled code - // can use these stubs if a failed allocation will be retried (e.g., by deoptimizing and - // re-executing in the interpreter). - static void new_instance_or_null(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, true); } - static void new_array_or_null(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, true); } - static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, true); } - static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, true); } - static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, true); } + // When allocation fails, these stubs return null and have no pending OutOfMemoryError exception. + // Compiled code can use these stubs if a failed allocation will be retried (e.g., by deoptimizing + // and re-executing in the interpreter). + static void new_instance_or_null(JavaThread* thread, Klass* klass); + static void new_array_or_null(JavaThread* thread, Klass* klass, jint length); + static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims); + static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length); + static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror); static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3); static jint identity_hash_code(JavaThread* current, oopDesc* obj); diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index cadbba27f6e..035c1dd1ce9 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -251,6 +251,8 @@ nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ + nonstatic_field(Klass, _bitmap, uintx) \ + nonstatic_field(Klass, _hash_slot, uint8_t) \ \ nonstatic_field(LocalVariableTableElement, start_bci, u2) \ nonstatic_field(LocalVariableTableElement, length, u2) \ @@ -381,6 +383,7 @@ static_field(StubRoutines, _bigIntegerRightShiftWorker, address) \ static_field(StubRoutines, _bigIntegerLeftShiftWorker, address) \ static_field(StubRoutines, _cont_thaw, address) \ + static_field(StubRoutines, _lookup_secondary_supers_table_slow_path_stub, address) \ \ nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \ nonstatic_field(Thread, _allocated_bytes, jlong) \ @@ -800,39 +803,33 @@ declare_function(Deoptimization::uncommon_trap) \ declare_function(Deoptimization::unpack_frames) \ \ - declare_function(JVMCIRuntime::new_instance) \ - declare_function(JVMCIRuntime::new_array) \ - declare_function(JVMCIRuntime::new_multi_array) \ - declare_function(JVMCIRuntime::dynamic_new_array) \ - declare_function(JVMCIRuntime::dynamic_new_instance) \ - \ - declare_function(JVMCIRuntime::new_instance_or_null) \ - declare_function(JVMCIRuntime::new_array_or_null) \ - declare_function(JVMCIRuntime::new_multi_array_or_null) \ - declare_function(JVMCIRuntime::dynamic_new_array_or_null) \ - declare_function(JVMCIRuntime::dynamic_new_instance_or_null) \ - \ - declare_function(JVMCIRuntime::invoke_static_method_one_arg) \ - \ - declare_function(JVMCIRuntime::vm_message) \ - declare_function(JVMCIRuntime::identity_hash_code) \ - declare_function(JVMCIRuntime::exception_handler_for_pc) \ - declare_function(JVMCIRuntime::monitorenter) \ - declare_function(JVMCIRuntime::monitorexit) \ - declare_function(JVMCIRuntime::object_notify) \ - declare_function(JVMCIRuntime::object_notifyAll) \ - declare_function(JVMCIRuntime::throw_and_post_jvmti_exception) \ - declare_function(JVMCIRuntime::throw_klass_external_name_exception) \ - declare_function(JVMCIRuntime::throw_class_cast_exception) \ - declare_function(JVMCIRuntime::log_primitive) \ - declare_function(JVMCIRuntime::log_object) \ - declare_function(JVMCIRuntime::log_printf) \ - declare_function(JVMCIRuntime::vm_error) \ - declare_function(JVMCIRuntime::load_and_clear_exception) \ - G1GC_ONLY(declare_function(JVMCIRuntime::write_barrier_pre)) \ - G1GC_ONLY(declare_function(JVMCIRuntime::write_barrier_post)) \ - declare_function(JVMCIRuntime::validate_object) \ - \ + declare_function(JVMCIRuntime::new_instance_or_null) \ + declare_function(JVMCIRuntime::new_array_or_null) \ + declare_function(JVMCIRuntime::new_multi_array_or_null) \ + declare_function(JVMCIRuntime::dynamic_new_array_or_null) \ + declare_function(JVMCIRuntime::dynamic_new_instance_or_null) \ + \ + declare_function(JVMCIRuntime::invoke_static_method_one_arg) \ + \ + declare_function(JVMCIRuntime::vm_message) \ + declare_function(JVMCIRuntime::identity_hash_code) \ + declare_function(JVMCIRuntime::exception_handler_for_pc) \ + declare_function(JVMCIRuntime::monitorenter) \ + declare_function(JVMCIRuntime::monitorexit) \ + declare_function(JVMCIRuntime::object_notify) \ + declare_function(JVMCIRuntime::object_notifyAll) \ + declare_function(JVMCIRuntime::throw_and_post_jvmti_exception) \ + declare_function(JVMCIRuntime::throw_klass_external_name_exception) \ + declare_function(JVMCIRuntime::throw_class_cast_exception) \ + declare_function(JVMCIRuntime::log_primitive) \ + declare_function(JVMCIRuntime::log_object) \ + declare_function(JVMCIRuntime::log_printf) \ + declare_function(JVMCIRuntime::vm_error) \ + declare_function(JVMCIRuntime::load_and_clear_exception) \ + G1GC_ONLY(declare_function(JVMCIRuntime::write_barrier_pre)) \ + G1GC_ONLY(declare_function(JVMCIRuntime::write_barrier_post)) \ + declare_function(JVMCIRuntime::validate_object) \ + \ declare_function(JVMCIRuntime::test_deoptimize_call_int)