< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page
rev 55090 : secret-sfac

@@ -295,11 +295,11 @@
 
   case CallInfo::direct_call:
     vmindex = Method::nonvirtual_vtable_index;
     if (m->is_static()) {
       flags |= IS_METHOD      | (JVM_REF_invokeStatic  << REFERENCE_KIND_SHIFT);
-    } else if (m->is_initializer()) {
+    } else if (m->is_object_constructor()) {
       flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
     } else {
       // "special" reflects that this is a direct call, not that it
       // necessarily originates from an invokespecial. We can also do
       // direct calls for private and/or final non-static methods.

@@ -837,14 +837,17 @@
     {
       CallInfo result;
       LinkInfo link_info(defc, name, type, caller, access_check);
       {
         assert(!HAS_PENDING_EXCEPTION, "");
-        if (name == vmSymbols::object_initializer_name()) {
+        if (name != vmSymbols::object_initializer_name()) {
+          break;                // will throw after end of switch
+        } else if (type->is_void_method_signature()) {
           LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
         } else {
-          break;                // will throw after end of switch
+          // LinkageError unless  it returns something reasonable
+          LinkResolver::resolve_static_call(result, link_info, false, THREAD);
         }
         if (HAS_PENDING_EXCEPTION) {
           if (speculative_resolve) {
             CLEAR_PENDING_EXCEPTION;
           }

@@ -1017,40 +1020,40 @@
   if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
     // watch out for these guys:
     Symbol* init_name   = vmSymbols::object_initializer_name();
     Symbol* clinit_name = vmSymbols::class_initializer_name();
     if (name == clinit_name)  clinit_name = NULL; // hack for exposing <clinit>
-    bool negate_name_test = false;
+    bool ctor_ok = true, sfac_ok = true;
     // fix name so that it captures the intention of IS_CONSTRUCTOR
     if (!(match_flags & IS_METHOD)) {
       // constructors only
       if (name == NULL) {
         name = init_name;
       } else if (name != init_name) {
         return 0;               // no constructors of this method name
       }
+      sfac_ok = false;
     } else if (!(match_flags & IS_CONSTRUCTOR)) {
       // methods only
-      if (name == NULL) {
-        name = init_name;
-        negate_name_test = true; // if we see the name, we *omit* the entry
-      } else if (name == init_name) {
-        return 0;               // no methods of this constructor name
-      }
+      ctor_ok = false;  // but sfac_ok is true, so we might find <init>
     } else {
       // caller will accept either sort; no need to adjust name
     }
     InstanceKlass* ik = InstanceKlass::cast(k);
     for (MethodStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) {
       Method* m = st.method();
       Symbol* m_name = m->name();
       if (m_name == clinit_name)
         continue;
-      if (name != NULL && ((m_name != name) ^ negate_name_test))
+      if (name != NULL && m_name != name)
           continue;
       if (sig != NULL && m->signature() != sig)
         continue;
+      if (m_name == init_name) {  // might be either ctor or sfac
+        if (m->is_object_constructor()  && !ctor_ok)  continue;
+        if (m->is_static_init_factory() && !sfac_ok)  continue;
+      }
       // passed the filters
       if (rskip > 0) {
         --rskip;
       } else if (rfill < rlimit) {
         Handle result(thread, results->obj_at(rfill++));
< prev index next >