8197405: Improve messages of AbstractMethodErrors and IncompatibleClassChangeErrors

Reviewed-by: coleenp, dholmes, mdoerr, njian
This commit is contained in:
Goetz Lindenmaier 2018-02-08 09:23:49 +01:00
parent 10259cf594
commit 507c62fc76
35 changed files with 1981 additions and 79 deletions

View file

@ -839,9 +839,15 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
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 {
@ -1454,7 +1460,29 @@ 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(&reg_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(&reg_map);
LinkResolver::throw_abstract_method_error(callee, recv->klass(), thread);
JRT_BLOCK_END
return StubRoutines::forward_exception_entry();
JRT_END