< prev index next >
src/hotspot/share/prims/methodHandles.cpp
Print this page
rev 49420 : 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull
Reviewed-by: lfoltan, acorn
*** 302,312 ****
flags |= CALLER_SENSITIVE;
}
Handle resolved_method = info.resolved_method_name();
assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m(),
! "Should not change after link resolultion");
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags (mname_oop, flags);
java_lang_invoke_MemberName::set_method (mname_oop, resolved_method());
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); // vtable/itable index
--- 302,312 ----
flags |= CALLER_SENSITIVE;
}
Handle resolved_method = info.resolved_method_name();
assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m(),
! "Should not change after link resolution");
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags (mname_oop, flags);
java_lang_invoke_MemberName::set_method (mname_oop, resolved_method());
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); // vtable/itable index
*** 678,688 ****
// An unresolved member name is a mere symbolic reference.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
! Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller, TRAPS) {
Handle empty;
assert(java_lang_invoke_MemberName::is_instance(mname()), "");
if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
// Already resolved.
--- 678,689 ----
// An unresolved member name is a mere symbolic reference.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
! Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
! bool speculative_resolve, TRAPS) {
Handle empty;
assert(java_lang_invoke_MemberName::is_instance(mname()), "");
if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
// Already resolved.
*** 777,786 ****
--- 778,790 ----
link_info, false, THREAD);
} else {
assert(false, "ref_kind=%d", ref_kind);
}
if (HAS_PENDING_EXCEPTION) {
+ if (speculative_resolve) {
+ CLEAR_PENDING_EXCEPTION;
+ }
return empty;
}
}
if (result.resolved_appendix().not_null()) {
// The resolved MemberName must not be accompanied by an appendix argument,
*** 802,811 ****
--- 806,818 ----
LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
} else {
break; // will throw after end of switch
}
if (HAS_PENDING_EXCEPTION) {
+ if (speculative_resolve) {
+ CLEAR_PENDING_EXCEPTION;
+ }
return empty;
}
}
assert(result.is_statically_bound(), "");
result.set_resolved_method_name(CHECK_(empty));
*** 818,827 ****
--- 825,837 ----
{
assert(!HAS_PENDING_EXCEPTION, "");
LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check);
LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
if (HAS_PENDING_EXCEPTION) {
+ if (speculative_resolve) {
+ CLEAR_PENDING_EXCEPTION;
+ }
return empty;
}
}
oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind));
return Handle(THREAD, mname2);
*** 1183,1193 ****
MethodHandles::expand_MemberName(mname, 0, CHECK);
}
JVM_END
// void resolve(MemberName self, Class<?> caller)
! JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
// The trusted Java code that calls this method should already have performed
// access checks on behalf of the given caller. But, we can verify this.
--- 1193,1204 ----
MethodHandles::expand_MemberName(mname, 0, CHECK);
}
JVM_END
// void resolve(MemberName self, Class<?> caller)
! JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh,
! jboolean speculative_resolve)) {
if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
// The trusted Java code that calls this method should already have performed
// access checks on behalf of the given caller. But, we can verify this.
*** 1211,1228 ****
}
}
Klass* caller = caller_jh == NULL ? NULL :
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
! Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
if (resolved.is_null()) {
int flags = java_lang_invoke_MemberName::flags(mname());
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format");
}
if ((flags & ALL_KINDS) == IS_FIELD) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
} else if ((flags & ALL_KINDS) == IS_METHOD ||
(flags & ALL_KINDS) == IS_CONSTRUCTOR) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
--- 1222,1244 ----
}
}
Klass* caller = caller_jh == NULL ? NULL :
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
! Handle resolved = MethodHandles::resolve_MemberName(mname, caller, speculative_resolve,
! CHECK_NULL);
if (resolved.is_null()) {
int flags = java_lang_invoke_MemberName::flags(mname());
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format");
}
+ if (speculative_resolve) {
+ assert(!HAS_PENDING_EXCEPTION, "");
+ return NULL;
+ }
if ((flags & ALL_KINDS) == IS_FIELD) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
} else if ((flags & ALL_KINDS) == IS_METHOD ||
(flags & ALL_KINDS) == IS_CONSTRUCTOR) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
*** 1510,1520 ****
// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod MHN_methods[] = {
{CC "init", CC "(" MEM "" OBJ ")V", FN_PTR(MHN_init_Mem)},
{CC "expand", CC "(" MEM ")V", FN_PTR(MHN_expand_Mem)},
! {CC "resolve", CC "(" MEM "" CLS ")" MEM, FN_PTR(MHN_resolve_Mem)},
// static native int getNamedCon(int which, Object[] name)
{CC "getNamedCon", CC "(I[" OBJ ")I", FN_PTR(MHN_getNamedCon)},
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
{CC "getMembers", CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
--- 1526,1536 ----
// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod MHN_methods[] = {
{CC "init", CC "(" MEM "" OBJ ")V", FN_PTR(MHN_init_Mem)},
{CC "expand", CC "(" MEM ")V", FN_PTR(MHN_expand_Mem)},
! {CC "resolve", CC "(" MEM "" CLS "Z)" MEM, FN_PTR(MHN_resolve_Mem)},
// static native int getNamedCon(int which, Object[] name)
{CC "getNamedCon", CC "(I[" OBJ ")I", FN_PTR(MHN_getNamedCon)},
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
{CC "getMembers", CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
< prev index next >