Skip to content

Commit 269cd38

Browse files
committedSep 17, 2024
8338566: Lazy creation of exception instances is not thread safe
Reviewed-by: shade, kvn, dlong
1 parent 8b6e277 commit 269cd38

File tree

6 files changed

+47
-68
lines changed

6 files changed

+47
-68
lines changed
 

‎src/hotspot/share/cds/heapShared.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,9 @@ void HeapShared::check_default_subgraph_classes() {
13221322
name == vmSymbols::java_lang_ArithmeticException() ||
13231323
name == vmSymbols::java_lang_NullPointerException() ||
13241324
name == vmSymbols::java_lang_InternalError() ||
1325+
name == vmSymbols::java_lang_ArrayIndexOutOfBoundsException() ||
1326+
name == vmSymbols::java_lang_ArrayStoreException() ||
1327+
name == vmSymbols::java_lang_ClassCastException() ||
13251328
name == vmSymbols::object_array_signature() ||
13261329
name == vmSymbols::byte_array_signature() ||
13271330
name == vmSymbols::char_array_signature(),

‎src/hotspot/share/ci/ciEnv.cpp

+9-55
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,6 @@ ciSymbol* ciEnv::_unloaded_cisymbol = nullptr;
100100
ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = nullptr;
101101
ciObjArrayKlass* ciEnv::_unloaded_ciobjarrayklass = nullptr;
102102

103-
jobject ciEnv::_ArrayIndexOutOfBoundsException_handle = nullptr;
104-
jobject ciEnv::_ArrayStoreException_handle = nullptr;
105-
jobject ciEnv::_ClassCastException_handle = nullptr;
106-
107103
#ifndef PRODUCT
108104
static bool firstEnv = true;
109105
#endif /* PRODUCT */
@@ -158,10 +154,16 @@ ciEnv::ciEnv(CompileTask* task)
158154
o = Universe::arithmetic_exception_instance();
159155
assert(o != nullptr, "should have been initialized");
160156
_ArithmeticException_instance = get_object(o)->as_instance();
157+
o = Universe::array_index_out_of_bounds_exception_instance();
158+
assert(o != nullptr, "should have been initialized");
159+
_ArrayIndexOutOfBoundsException_instance = get_object(o)->as_instance();
160+
o = Universe::array_store_exception_instance();
161+
assert(o != nullptr, "should have been initialized");
162+
_ArrayStoreException_instance = get_object(o)->as_instance();
163+
o = Universe::class_cast_exception_instance();
164+
assert(o != nullptr, "should have been initialized");
165+
_ClassCastException_instance = get_object(o)->as_instance();
161166

162-
_ArrayIndexOutOfBoundsException_instance = nullptr;
163-
_ArrayStoreException_instance = nullptr;
164-
_ClassCastException_instance = nullptr;
165167
_the_null_string = nullptr;
166168
_the_min_jint_string = nullptr;
167169

@@ -363,29 +365,6 @@ void ciEnv::cache_dtrace_flags() {
363365
_dtrace_alloc_probes = DTraceAllocProbes;
364366
}
365367

366-
// ------------------------------------------------------------------
367-
// helper for lazy exception creation
368-
ciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) {
369-
VM_ENTRY_MARK;
370-
if (handle == nullptr) {
371-
// Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance.
372-
InstanceKlass* ik = SystemDictionary::find_instance_klass(THREAD, name, Handle(), Handle());
373-
jobject objh = nullptr;
374-
if (ik != nullptr) {
375-
oop obj = ik->allocate_instance(THREAD);
376-
if (!HAS_PENDING_EXCEPTION)
377-
objh = JNIHandles::make_global(Handle(THREAD, obj));
378-
}
379-
if (HAS_PENDING_EXCEPTION) {
380-
CLEAR_PENDING_EXCEPTION;
381-
} else {
382-
handle = objh;
383-
}
384-
}
385-
oop obj = JNIHandles::resolve(handle);
386-
return obj == nullptr? nullptr: get_object(obj)->as_instance();
387-
}
388-
389368
ciInstanceKlass* ciEnv::get_box_klass_for_primitive_type(BasicType type) {
390369
switch (type) {
391370
case T_BOOLEAN: return Boolean_klass();
@@ -403,31 +382,6 @@ ciInstanceKlass* ciEnv::get_box_klass_for_primitive_type(BasicType type) {
403382
}
404383
}
405384

406-
ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() {
407-
if (_ArrayIndexOutOfBoundsException_instance == nullptr) {
408-
_ArrayIndexOutOfBoundsException_instance
409-
= get_or_create_exception(_ArrayIndexOutOfBoundsException_handle,
410-
vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
411-
}
412-
return _ArrayIndexOutOfBoundsException_instance;
413-
}
414-
ciInstance* ciEnv::ArrayStoreException_instance() {
415-
if (_ArrayStoreException_instance == nullptr) {
416-
_ArrayStoreException_instance
417-
= get_or_create_exception(_ArrayStoreException_handle,
418-
vmSymbols::java_lang_ArrayStoreException());
419-
}
420-
return _ArrayStoreException_instance;
421-
}
422-
ciInstance* ciEnv::ClassCastException_instance() {
423-
if (_ClassCastException_instance == nullptr) {
424-
_ClassCastException_instance
425-
= get_or_create_exception(_ClassCastException_handle,
426-
vmSymbols::java_lang_ClassCastException());
427-
}
428-
return _ClassCastException_instance;
429-
}
430-
431385
ciInstance* ciEnv::the_null_string() {
432386
if (_the_null_string == nullptr) {
433387
VM_ENTRY_MARK;

‎src/hotspot/share/ci/ciEnv.hpp

+12-11
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@ class ciEnv : StackObj {
9494
static ciInstanceKlass* _unloaded_ciinstance_klass;
9595
static ciObjArrayKlass* _unloaded_ciobjarrayklass;
9696

97-
static jobject _ArrayIndexOutOfBoundsException_handle;
98-
static jobject _ArrayStoreException_handle;
99-
static jobject _ClassCastException_handle;
100-
10197
ciInstance* _NullPointerException_instance;
10298
ciInstance* _ArithmeticException_instance;
10399
ciInstance* _ArrayIndexOutOfBoundsException_instance;
@@ -230,8 +226,6 @@ class ciEnv : StackObj {
230226

231227
ciMethod* get_method_from_handle(Method* method);
232228

233-
ciInstance* get_or_create_exception(jobject& handle, Symbol* name);
234-
235229
// Get a ciMethod representing either an unfound method or
236230
// a method with an unloaded holder. Ensures uniqueness of
237231
// the result.
@@ -402,11 +396,18 @@ class ciEnv : StackObj {
402396
assert(_ArithmeticException_instance != nullptr, "initialization problem");
403397
return _ArithmeticException_instance;
404398
}
405-
406-
// Lazy constructors:
407-
ciInstance* ArrayIndexOutOfBoundsException_instance();
408-
ciInstance* ArrayStoreException_instance();
409-
ciInstance* ClassCastException_instance();
399+
ciInstance* ArrayIndexOutOfBoundsException_instance() {
400+
assert(_ArrayIndexOutOfBoundsException_instance != nullptr, "initialization problem");
401+
return _ArrayIndexOutOfBoundsException_instance;
402+
}
403+
ciInstance* ArrayStoreException_instance() {
404+
assert(_ArrayStoreException_instance != nullptr, "initialization problem");
405+
return _ArrayStoreException_instance;
406+
}
407+
ciInstance* ClassCastException_instance() {
408+
assert(_ClassCastException_instance != nullptr, "initialization problem");
409+
return _ClassCastException_instance;
410+
}
410411

411412
ciInstance* the_null_string();
412413
ciInstance* the_min_jint_string();

‎src/hotspot/share/memory/universe.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ class BuiltinException {
229229
static BuiltinException _null_ptr_exception;
230230
static BuiltinException _arithmetic_exception;
231231
static BuiltinException _internal_error;
232+
static BuiltinException _array_index_out_of_bounds_exception;
233+
static BuiltinException _array_store_exception;
234+
static BuiltinException _class_cast_exception;
232235

233236
objArrayOop Universe::the_empty_class_array () {
234237
return (objArrayOop)_the_empty_class_array.resolve();
@@ -246,6 +249,9 @@ oop Universe::the_min_jint_string() { return _the_min_jint_string.
246249
oop Universe::null_ptr_exception_instance() { return _null_ptr_exception.instance(); }
247250
oop Universe::arithmetic_exception_instance() { return _arithmetic_exception.instance(); }
248251
oop Universe::internal_error_instance() { return _internal_error.instance(); }
252+
oop Universe::array_index_out_of_bounds_exception_instance() { return _array_index_out_of_bounds_exception.instance(); }
253+
oop Universe::array_store_exception_instance() { return _array_store_exception.instance(); }
254+
oop Universe::class_cast_exception_instance() { return _class_cast_exception.instance(); }
249255

250256
oop Universe::the_null_sentinel() { return _the_null_sentinel.resolve(); }
251257

@@ -302,6 +308,9 @@ void Universe::archive_exception_instances() {
302308
_null_ptr_exception.store_in_cds();
303309
_arithmetic_exception.store_in_cds();
304310
_internal_error.store_in_cds();
311+
_array_index_out_of_bounds_exception.store_in_cds();
312+
_array_store_exception.store_in_cds();
313+
_class_cast_exception.store_in_cds();
305314
}
306315

307316
void Universe::load_archived_object_instances() {
@@ -318,6 +327,9 @@ void Universe::load_archived_object_instances() {
318327
_null_ptr_exception.load_from_cds();
319328
_arithmetic_exception.load_from_cds();
320329
_internal_error.load_from_cds();
330+
_array_index_out_of_bounds_exception.load_from_cds();
331+
_array_store_exception.load_from_cds();
332+
_class_cast_exception.load_from_cds();
321333
}
322334
}
323335
#endif
@@ -334,6 +346,9 @@ void Universe::serialize(SerializeClosure* f) {
334346
_null_ptr_exception.serialize(f);
335347
_arithmetic_exception.serialize(f);
336348
_internal_error.serialize(f);
349+
_array_index_out_of_bounds_exception.serialize(f);
350+
_array_store_exception.serialize(f);
351+
_class_cast_exception.serialize(f);
337352
#endif
338353

339354
f->do_ptr(&_fillerArrayKlass);
@@ -1083,10 +1098,12 @@ bool universe_post_init() {
10831098
Universe::_delayed_stack_overflow_error_message = OopHandle(Universe::vm_global(), instance);
10841099
}
10851100

1086-
// Setup preallocated NullPointerException/ArithmeticException
1087-
// (used for a cheap & dirty solution in compiler exception handling)
1101+
// Setup preallocated exceptions used for a cheap & dirty solution in compiler exception handling
10881102
_null_ptr_exception.init_if_empty(vmSymbols::java_lang_NullPointerException(), CHECK_false);
10891103
_arithmetic_exception.init_if_empty(vmSymbols::java_lang_ArithmeticException(), CHECK_false);
1104+
_array_index_out_of_bounds_exception.init_if_empty(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), CHECK_false);
1105+
_array_store_exception.init_if_empty(vmSymbols::java_lang_ArrayStoreException(), CHECK_false);
1106+
_class_cast_exception.init_if_empty(vmSymbols::java_lang_ClassCastException(), CHECK_false);
10901107

10911108
// Virtual Machine Error for when we get into a situation we can't resolve
10921109
Klass* k = vmClasses::InternalError_klass();

‎src/hotspot/share/memory/universe.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ class Universe: AllStatic {
230230
static oop null_ptr_exception_instance();
231231
static oop arithmetic_exception_instance();
232232
static oop internal_error_instance();
233+
static oop array_index_out_of_bounds_exception_instance();
234+
static oop array_store_exception_instance();
235+
static oop class_cast_exception_instance();
233236
static oop vm_exception() { return internal_error_instance(); }
234237

235238
static Array<Klass*>* the_array_interfaces_array() { return _the_array_interfaces_array; }

‎src/hotspot/share/runtime/threads.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
393393
initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK);
394394
initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK);
395395
initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK);
396+
initialize_class(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), CHECK);
396397
initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK);
397398
initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK);
398399
initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK);

0 commit comments

Comments
 (0)
Please sign in to comment.