Skip to content

Commit 73c9088

Browse files
committed
8249451: Unconditional exceptions clearing logic in compiler code should honor Async Exceptions.
Reviewed-by: dholmes, iveresov
1 parent 3ef2efb commit 73c9088

21 files changed

+179
-114
lines changed

src/hotspot/share/c1/c1_Runtime1.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,7 @@ static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, Meth
465465
}
466466
bci = branch_bci + offset;
467467
}
468-
assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
469468
osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, nm, THREAD);
470-
assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
471469
return osr_nm;
472470
}
473471

@@ -1416,6 +1414,7 @@ JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* thread))
14161414
// that simply means we won't have an MDO to update.
14171415
Method::build_interpreter_method_data(m, THREAD);
14181416
if (HAS_PENDING_EXCEPTION) {
1417+
// Only metaspace OOM is expected. No Java code executed.
14191418
assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
14201419
CLEAR_PENDING_EXCEPTION;
14211420
}

src/hotspot/share/classfile/javaClasses.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4792,6 +4792,27 @@ void java_lang_reflect_RecordComponent::set_typeAnnotations(oop element, oop val
47924792
element->obj_field_put(_typeAnnotations_offset, value);
47934793
}
47944794

4795+
// java_lang_InternalError
4796+
int java_lang_InternalError::_during_unsafe_access_offset;
4797+
4798+
void java_lang_InternalError::set_during_unsafe_access(oop internal_error) {
4799+
internal_error->bool_field_put(_during_unsafe_access_offset, true);
4800+
}
4801+
4802+
jboolean java_lang_InternalError::during_unsafe_access(oop internal_error) {
4803+
return internal_error->bool_field(_during_unsafe_access_offset);
4804+
}
4805+
4806+
void java_lang_InternalError::compute_offsets() {
4807+
INTERNALERROR_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
4808+
}
4809+
4810+
#if INCLUDE_CDS
4811+
void java_lang_InternalError::serialize_offsets(SerializeClosure* f) {
4812+
INTERNALERROR_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
4813+
}
4814+
#endif
4815+
47954816
#define DO_COMPUTE_OFFSETS(k) k::compute_offsets();
47964817

47974818
// Compute field offsets of all the classes in this file

src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class RecordComponent;
4747
f(java_lang_Throwable) \
4848
f(java_lang_Thread) \
4949
f(java_lang_ThreadGroup) \
50+
f(java_lang_InternalError) \
5051
f(java_lang_AssertionStatusDirectives) \
5152
f(java_lang_ref_SoftReference) \
5253
f(java_lang_invoke_MethodHandle) \
@@ -1651,6 +1652,22 @@ class java_lang_Byte_ByteCache : AllStatic {
16511652
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
16521653
};
16531654

1655+
1656+
// Interface to java.lang.InternalError objects
1657+
1658+
#define INTERNALERROR_INJECTED_FIELDS(macro) \
1659+
macro(java_lang_InternalError, during_unsafe_access, bool_signature, false)
1660+
1661+
class java_lang_InternalError : AllStatic {
1662+
private:
1663+
static int _during_unsafe_access_offset;
1664+
public:
1665+
static jboolean during_unsafe_access(oop internal_error);
1666+
static void set_during_unsafe_access(oop internal_error);
1667+
static void compute_offsets();
1668+
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
1669+
};
1670+
16541671
// Use to declare fields that need to be injected into Java classes
16551672
// for the JVM to use. The name_index and signature_index are
16561673
// declared in vmSymbols. The may_be_java flag is used to declare
@@ -1690,7 +1707,9 @@ class InjectedField {
16901707
MEMBERNAME_INJECTED_FIELDS(macro) \
16911708
CALLSITECONTEXT_INJECTED_FIELDS(macro) \
16921709
STACKFRAMEINFO_INJECTED_FIELDS(macro) \
1693-
MODULE_INJECTED_FIELDS(macro)
1710+
MODULE_INJECTED_FIELDS(macro) \
1711+
INTERNALERROR_INJECTED_FIELDS(macro)
1712+
16941713

16951714
// Interface to hard-coded offset checking
16961715

src/hotspot/share/classfile/systemDictionary.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class TableStatistics;
126126
do_klass(ClassCastException_klass, java_lang_ClassCastException ) \
127127
do_klass(ArrayStoreException_klass, java_lang_ArrayStoreException ) \
128128
do_klass(VirtualMachineError_klass, java_lang_VirtualMachineError ) \
129+
do_klass(InternalError_klass, java_lang_InternalError ) \
129130
do_klass(OutOfMemoryError_klass, java_lang_OutOfMemoryError ) \
130131
do_klass(StackOverflowError_klass, java_lang_StackOverflowError ) \
131132
do_klass(IllegalMonitorStateException_klass, java_lang_IllegalMonitorStateException ) \

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@
461461
template(big_endian_name, "BIG_ENDIAN") \
462462
template(use_unaligned_access_name, "UNALIGNED_ACCESS") \
463463
template(data_cache_line_flush_size_name, "DATA_CACHE_LINE_FLUSH_SIZE") \
464+
template(during_unsafe_access_name, "during_unsafe_access") \
464465
\
465466
/* name symbols needed by intrinsics */ \
466467
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \

src/hotspot/share/compiler/compilationPolicy.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void CompilationPolicy::compile_if_required(const methodHandle& selected_method,
106106
}
107107
CompileBroker::compile_method(selected_method, InvocationEntryBci,
108108
CompilationPolicy::policy()->initial_compile_level(selected_method),
109-
methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
109+
methodHandle(), 0, CompileTask::Reason_MustBeCompiled, THREAD);
110110
}
111111
}
112112

@@ -379,10 +379,10 @@ bool SimpleCompPolicy::is_mature(Method* method) {
379379
}
380380

381381
nmethod* SimpleCompPolicy::event(const methodHandle& method, const methodHandle& inlinee, int branch_bci,
382-
int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
382+
int bci, CompLevel comp_level, CompiledMethod* nm, TRAPS) {
383383
assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
384384
NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
385-
if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
385+
if (JvmtiExport::can_post_interpreter_events() && THREAD->as_Java_thread()->is_interp_only_mode()) {
386386
// If certain JVMTI events (e.g. frame pop event) are requested then the
387387
// thread is forced to remain in interpreted code. This is
388388
// implemented partly by a check in the run_compiled_code
@@ -408,7 +408,7 @@ nmethod* SimpleCompPolicy::event(const methodHandle& method, const methodHandle&
408408
// when code cache is full, compilation gets switched off, UseCompiler
409409
// is set to false
410410
if (!method->has_compiled_code() && UseCompiler) {
411-
method_invocation_event(method, thread);
411+
method_invocation_event(method, THREAD);
412412
} else {
413413
// Force counter overflow on method entry, even if no compilation
414414
// happened. (The method_invocation_event call does this also.)
@@ -424,7 +424,7 @@ nmethod* SimpleCompPolicy::event(const methodHandle& method, const methodHandle&
424424
NOT_PRODUCT(trace_osr_request(method, osr_nm, bci));
425425
// when code cache is full, we should not compile any more...
426426
if (osr_nm == NULL && UseCompiler) {
427-
method_back_branch_event(method, bci, thread);
427+
method_back_branch_event(method, bci, THREAD);
428428
osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
429429
}
430430
if (osr_nm == NULL) {
@@ -479,25 +479,25 @@ void SimpleCompPolicy::trace_osr_request(const methodHandle& method, nmethod* os
479479
}
480480
#endif // !PRODUCT
481481

482-
void SimpleCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) {
482+
void SimpleCompPolicy::method_invocation_event(const methodHandle& m, TRAPS) {
483483
const int comp_level = CompLevel_highest_tier;
484484
const int hot_count = m->invocation_count();
485485
reset_counter_for_invocation_event(m);
486486

487487
if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
488488
CompiledMethod* nm = m->code();
489489
if (nm == NULL ) {
490-
CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, CompileTask::Reason_InvocationCount, thread);
490+
CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, CompileTask::Reason_InvocationCount, THREAD);
491491
}
492492
}
493493
}
494494

495-
void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
495+
void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, TRAPS) {
496496
const int comp_level = CompLevel_highest_tier;
497497
const int hot_count = m->backedge_count();
498498

499499
if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
500-
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, thread);
500+
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, THREAD);
501501
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
502502
}
503503
}

src/hotspot/share/compiler/compilationPolicy.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class CompilationPolicy : public CHeapObj<mtCompiler> {
6363
virtual int compiler_count(CompLevel comp_level) = 0;
6464
// main notification entry, return a pointer to an nmethod if the OSR is required,
6565
// returns NULL otherwise.
66-
virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) = 0;
66+
virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, TRAPS) = 0;
6767
// safepoint() is called at the end of the safepoint
6868
virtual void do_safepoint_work() = 0;
6969
// reprofile request
@@ -90,8 +90,8 @@ class SimpleCompPolicy : public CompilationPolicy {
9090
static void trace_osr_completion(nmethod* osr_nm);
9191
void reset_counter_for_invocation_event(const methodHandle& method);
9292
void reset_counter_for_back_branch_event(const methodHandle& method);
93-
void method_invocation_event(const methodHandle& m, JavaThread* thread);
94-
void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
93+
void method_invocation_event(const methodHandle& m, TRAPS);
94+
void method_back_branch_event(const methodHandle& m, int bci, TRAPS);
9595
public:
9696
SimpleCompPolicy() : _compiler_count(0) { }
9797
virtual CompLevel initial_compile_level(const methodHandle& m) { return CompLevel_highest_tier; }
@@ -102,7 +102,7 @@ class SimpleCompPolicy : public CompilationPolicy {
102102
virtual bool is_mature(Method* method);
103103
virtual void initialize();
104104
virtual CompileTask* select_task(CompileQueue* compile_queue);
105-
virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
105+
virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, TRAPS);
106106
};
107107

108108

src/hotspot/share/compiler/compileBroker.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
12561256
int comp_level,
12571257
const methodHandle& hot_method, int hot_count,
12581258
CompileTask::CompileReason compile_reason,
1259-
Thread* THREAD) {
1259+
TRAPS) {
12601260
// Do nothing if compilebroker is not initalized or compiles are submitted on level none
12611261
if (!_initialized || comp_level == CompLevel_none) {
12621262
return NULL;
@@ -1266,6 +1266,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
12661266
assert(comp != NULL, "Ensure we have a compiler");
12671267

12681268
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp);
1269+
// CompileBroker::compile_method can trap and can have pending aysnc exception.
12691270
nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, directive, THREAD);
12701271
DirectivesStack::release(directive);
12711272
return nm;
@@ -1276,7 +1277,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
12761277
const methodHandle& hot_method, int hot_count,
12771278
CompileTask::CompileReason compile_reason,
12781279
DirectiveSet* directive,
1279-
Thread* THREAD) {
1280+
TRAPS) {
12801281

12811282
// make sure arguments make sense
12821283
assert(method->method_holder()->is_instance_klass(), "not an instance method");
@@ -1329,10 +1330,10 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
13291330
assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
13301331
// some prerequisites that are compiler specific
13311332
if (comp->is_c2()) {
1332-
method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
1333+
method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NONASYNC_NULL);
13331334
// Resolve all classes seen in the signature of the method
13341335
// we are compiling.
1335-
Method::load_signature_classes(method, CHECK_AND_CLEAR_NULL);
1336+
Method::load_signature_classes(method, CHECK_AND_CLEAR_NONASYNC_NULL);
13361337
}
13371338

13381339
// If the method is native, do the lookup in the thread requesting

src/hotspot/share/compiler/compileBroker.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ class CompileBroker: AllStatic {
303303
const methodHandle& hot_method,
304304
int hot_count,
305305
CompileTask::CompileReason compile_reason,
306-
Thread* thread);
306+
TRAPS);
307307

308308
static nmethod* compile_method(const methodHandle& method,
309309
int osr_bci,
@@ -312,7 +312,7 @@ class CompileBroker: AllStatic {
312312
int hot_count,
313313
CompileTask::CompileReason compile_reason,
314314
DirectiveSet* directive,
315-
Thread* thread);
315+
TRAPS);
316316

317317
// Acquire any needed locks and assign a compile id
318318
static uint assign_compile_id_unlocked(Thread* thread, const methodHandle& method, int osr_bci);

0 commit comments

Comments
 (0)