< prev index next >
src/hotspot/share/runtime/sharedRuntime.cpp
Print this page
rev 49172 : 8197405: Improve messages of AbstractMethodErrors and IncompatibleClassChangeErrors.
Reviewed-by: coleenp, dholmes, mdoerr, njian
@@ -836,13 +836,19 @@
if (vt_stub == NULL) return NULL;
if (vt_stub->is_abstract_method_error(pc)) {
assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
Events::log_exception(thread, "AbstractMethodError at " INTPTR_FORMAT, p2i(pc));
- return StubRoutines::throw_AbstractMethodError_entry();
+ // Instead of throwing the abstract method error here directly, we re-resolve
+ // and will throw the AbstractMethodError during resolve. As a result, we'll
+ // get a more detailed error message.
+ return SharedRuntime::get_handle_wrong_method_stub();
} else {
Events::log_exception(thread, "NullPointerException at vtable entry " INTPTR_FORMAT, p2i(pc));
+ // Assert that the signal comes from the expected location in stub code.
+ assert(vt_stub->is_null_pointer_exception(pc),
+ "obtained signal from unexpected location in stub code");
return StubRoutines::throw_NullPointerException_at_call_entry();
}
} else {
CodeBlob* cb = CodeCache::find_blob(pc);
@@ -1451,11 +1457,33 @@
return callee_method->verified_code_entry();
JRT_END
// Handle abstract method call
JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method_abstract(JavaThread* thread))
- return StubRoutines::throw_AbstractMethodError_entry();
+ // Verbose error message for AbstractMethodError.
+ // Get the called method from the invoke bytecode.
+ vframeStream vfst(thread, true);
+ assert(!vfst.at_end(), "Java frame must exist");
+ methodHandle caller(vfst.method());
+ Bytecode_invoke invoke(caller, vfst.bci());
+ DEBUG_ONLY( invoke.verify(); )
+
+ // Find the compiled caller frame.
+ RegisterMap reg_map(thread);
+ frame stubFrame = thread->last_frame();
+ assert(stubFrame.is_runtime_frame(), "must be");
+ frame callerFrame = stubFrame.sender(®_map);
+ assert(callerFrame.is_compiled_frame(), "must be");
+
+ // Install exception and return forward entry.
+ JRT_BLOCK
+ methodHandle callee = invoke.static_target(thread);
+ assert(!callee.is_null() && invoke.has_receiver(), "or we should not be here");
+ oop recv = callerFrame.retrieve_receiver(®_map);
+ LinkResolver::throw_abstract_method_error(callee, recv->klass(), thread);
+ JRT_BLOCK_END
+ return StubRoutines::forward_exception_entry();
JRT_END
// resolve a static call and patch code
JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_static_call_C(JavaThread *thread ))
< prev index next >