< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page

        

@@ -133,10 +133,14 @@
     flags |= IS_CONSTRUCTOR;
   }
   return flags;
 }
 
+int MethodHandles::flags_to_ref_kind(int flags) {
+  return (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+}
+
 Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
   Handle empty;
   Handle type(THREAD, java_lang_invoke_MemberName::type(mname()));
   if (!java_lang_String::is_instance_inlined(type())) {
     return type; // already resolved

@@ -678,10 +682,39 @@
 // 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;
+  Handle resolved = MethodHandles::resolve_MemberName_helper(mname, caller, THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    if (PENDING_EXCEPTION->is_a(SystemDictionary::ClassNotFoundException_klass())) {
+      // Convert CNFE to NCDFE and don't worry about it on JDK side.
+      Handle e(THREAD, PENDING_EXCEPTION);
+      CLEAR_PENDING_EXCEPTION;
+      THROW_CAUSE_(vmSymbols::java_lang_NoClassDefFoundError(), e, empty);
+    }
+    return empty;
+  }
+  if (resolved.is_null()) {
+    int flags = java_lang_invoke_MemberName::flags(mname());
+    int ref_kind = flags_to_ref_kind(flags);
+    if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
+      THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty);
+    } else if ((flags & ALL_KINDS) == IS_FIELD) {
+      THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed", empty);
+    } else if ((flags & ALL_KINDS) == IS_METHOD ||
+               (flags & ALL_KINDS) == IS_CONSTRUCTOR) {
+      THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed", empty);
+    } else {
+      THROW_MSG_(vmSymbols::java_lang_LinkageError(), "resolution failed", empty);
+    }
+  }
+  return resolved;
+}
+
+Handle MethodHandles::resolve_MemberName_helper(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.
     DEBUG_ONLY(int vmindex = java_lang_invoke_MemberName::vmindex(mname()));

@@ -691,11 +724,11 @@
 
   Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
   Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
   Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
   int    flags    =       java_lang_invoke_MemberName::flags(mname());
-  int    ref_kind =       (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+  int    ref_kind =       flags_to_ref_kind(flags);
   if (!ref_kind_is_valid(ref_kind)) {
     THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty);
   }
 
   DEBUG_ONLY(int old_vmindex);

@@ -1210,27 +1243,14 @@
   }
 
   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");
+    // Resolution failure should already trigger an exception.
+    THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "empty");
     }
-    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");
-    } else {
-      THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
-    }
-  }
-
   return JNIHandles::make_local(THREAD, resolved());
 }
 JVM_END
 
 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
< prev index next >