8259403: Zero: crash with NULL MethodHandle receiver
Reviewed-by: coleenp
This commit is contained in:
parent
e93f08e2ac
commit
ff275b3764
src/hotspot
cpu/zero
share/interpreter
@ -70,35 +70,50 @@ oop MethodHandles::popFromStack(TRAPS) {
|
||||
|
||||
}
|
||||
|
||||
void MethodHandles::throw_AME(Klass* rcvr, Method* interface_method, TRAPS) {
|
||||
void MethodHandles::setup_frame_anchor(JavaThread* thread) {
|
||||
assert(!thread->has_last_Java_frame(), "Do not need to call this otherwise");
|
||||
|
||||
JavaThread *thread = THREAD->as_Java_thread();
|
||||
// Set up the frame anchor if it isn't already
|
||||
intptr_t *sp = thread->zero_stack()->sp();
|
||||
ZeroFrame *frame = thread->top_zero_frame();
|
||||
while (frame) {
|
||||
if (frame->is_interpreter_frame()) {
|
||||
interpreterState istate = frame->as_interpreter_frame()->interpreter_state();
|
||||
if (istate->self_link() == istate) break;
|
||||
}
|
||||
sp = ((intptr_t *) frame) + 1;
|
||||
frame = frame->next();
|
||||
}
|
||||
|
||||
assert(frame != NULL, "must be");
|
||||
thread->set_last_Java_frame(frame, sp);
|
||||
}
|
||||
|
||||
void MethodHandles::teardown_frame_anchor(JavaThread* thread) {
|
||||
thread->reset_last_Java_frame();
|
||||
}
|
||||
|
||||
void MethodHandles::throw_AME(Klass* rcvr, Method* interface_method, TRAPS) {
|
||||
JavaThread* thread = THREAD->as_Java_thread();
|
||||
bool has_last_Java_frame = thread->has_last_Java_frame();
|
||||
if (!has_last_Java_frame) {
|
||||
intptr_t *sp = thread->zero_stack()->sp();
|
||||
ZeroFrame *frame = thread->top_zero_frame();
|
||||
while (frame) {
|
||||
if (frame->is_interpreter_frame()) {
|
||||
interpreterState istate =
|
||||
frame->as_interpreter_frame()->interpreter_state();
|
||||
if (istate->self_link() == istate)
|
||||
break;
|
||||
}
|
||||
|
||||
sp = ((intptr_t *) frame) + 1;
|
||||
frame = frame->next();
|
||||
}
|
||||
|
||||
assert(frame != NULL, "must be");
|
||||
thread->set_last_Java_frame(frame, sp);
|
||||
setup_frame_anchor(thread);
|
||||
}
|
||||
InterpreterRuntime::throw_AbstractMethodErrorVerbose(thread, rcvr, interface_method);
|
||||
// Reset the frame anchor if necessary
|
||||
if (!has_last_Java_frame) {
|
||||
thread->reset_last_Java_frame();
|
||||
teardown_frame_anchor(thread);
|
||||
}
|
||||
}
|
||||
|
||||
void MethodHandles::throw_NPE(TRAPS) {
|
||||
JavaThread* thread = THREAD->as_Java_thread();
|
||||
bool has_last_Java_frame = thread->has_last_Java_frame();
|
||||
if (!has_last_Java_frame) {
|
||||
setup_frame_anchor(thread);
|
||||
}
|
||||
InterpreterRuntime::throw_NullPointerException(thread);
|
||||
if (!has_last_Java_frame) {
|
||||
teardown_frame_anchor(thread);
|
||||
}
|
||||
}
|
||||
|
||||
int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) {
|
||||
@ -110,7 +125,14 @@ int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUS
|
||||
|
||||
// 'this' is a MethodHandle. We resolve the target method by accessing this.form.vmentry.vmtarget.
|
||||
int numArgs = method->size_of_parameters();
|
||||
oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form
|
||||
|
||||
oop recv = STACK_OBJECT(-numArgs);
|
||||
if (recv == NULL) {
|
||||
throw_NPE(THREAD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
oop lform1 = java_lang_invoke_MethodHandle::form(recv); // this.form
|
||||
oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1);
|
||||
Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmEntry1);
|
||||
|
||||
@ -150,6 +172,10 @@ int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t
|
||||
|
||||
int numArgs = target->size_of_parameters();
|
||||
oop recv = STACK_OBJECT(-numArgs);
|
||||
if (recv == NULL) {
|
||||
throw_NPE(THREAD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
InstanceKlass* klass_part = InstanceKlass::cast(recv->klass());
|
||||
itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable();
|
||||
@ -187,8 +213,14 @@ int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UN
|
||||
// Resolve target method by looking up in the receiver object's vtable.
|
||||
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry);
|
||||
Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
|
||||
|
||||
int numArgs = target->size_of_parameters();
|
||||
oop recv = STACK_OBJECT(-numArgs);
|
||||
if (recv == NULL) {
|
||||
throw_NPE(THREAD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Klass* clazz = recv->klass();
|
||||
Klass* klass_part = InstanceKlass::cast(clazz);
|
||||
ResourceMark rm(THREAD);
|
||||
|
@ -32,7 +32,10 @@ enum /* platform_dependent_constants */ {
|
||||
private:
|
||||
static oop popFromStack(TRAPS);
|
||||
static void invoke_target(Method* method, TRAPS);
|
||||
static void setup_frame_anchor(JavaThread* thread);
|
||||
static void teardown_frame_anchor(JavaThread* thread);
|
||||
static void throw_AME(Klass* rcvr, Method* interface_method, TRAPS);
|
||||
static void throw_NPE(TRAPS);
|
||||
static int method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS);
|
||||
static int method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS);
|
||||
static int method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS);
|
||||
|
@ -632,6 +632,10 @@ JRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose(Ja
|
||||
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
JRT_END
|
||||
|
||||
JRT_ENTRY(void, InterpreterRuntime::throw_NullPointerException(JavaThread* thread))
|
||||
THROW(vmSymbols::java_lang_NullPointerException());
|
||||
JRT_END
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Fields
|
||||
//
|
||||
|
@ -82,6 +82,8 @@ class InterpreterRuntime: AllStatic {
|
||||
static void throw_delayed_StackOverflowError(JavaThread* thread);
|
||||
static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread, arrayOopDesc* a, jint index);
|
||||
static void throw_ClassCastException(JavaThread* thread, oopDesc* obj);
|
||||
static void throw_NullPointerException(JavaThread* thread);
|
||||
|
||||
static void create_exception(JavaThread* thread, char* name, char* message);
|
||||
static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
|
||||
static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception);
|
||||
|
Loading…
x
Reference in New Issue
Block a user