< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page

        

@@ -118,31 +118,31 @@
 
 // MemberName support
 
 // import java_lang_invoke_MemberName.*
 enum {
-  IS_METHOD            = java_lang_invoke_MemberName::MN_IS_METHOD,
-  IS_CONSTRUCTOR       = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
-  IS_FIELD             = java_lang_invoke_MemberName::MN_IS_FIELD,
-  IS_TYPE              = java_lang_invoke_MemberName::MN_IS_TYPE,
-  CALLER_SENSITIVE     = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
-  REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
-  REFERENCE_KIND_MASK  = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
-  SEARCH_SUPERCLASSES  = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
-  SEARCH_INTERFACES    = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
-  ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
+  IS_METHOD             = java_lang_invoke_MemberName::MN_IS_METHOD,
+  IS_OBJECT_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_OBJECT_CONSTRUCTOR,
+  IS_FIELD              = java_lang_invoke_MemberName::MN_IS_FIELD,
+  IS_TYPE               = java_lang_invoke_MemberName::MN_IS_TYPE,
+  CALLER_SENSITIVE      = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
+  REFERENCE_KIND_SHIFT  = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
+  REFERENCE_KIND_MASK   = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
+  SEARCH_SUPERCLASSES   = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
+  SEARCH_INTERFACES     = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
+  ALL_KINDS      = IS_METHOD | IS_OBJECT_CONSTRUCTOR | IS_FIELD | IS_TYPE
 };
 
 int MethodHandles::ref_kind_to_flags(int ref_kind) {
   assert(ref_kind_is_valid(ref_kind), "%d", ref_kind);
   int flags = (ref_kind << REFERENCE_KIND_SHIFT);
   if (ref_kind_is_field(ref_kind)) {
     flags |= IS_FIELD;
   } else if (ref_kind_is_method(ref_kind)) {
     flags |= IS_METHOD;
   } else if (ref_kind == JVM_REF_newInvokeSpecial) {
-    flags |= IS_CONSTRUCTOR;
+    flags |= IS_OBJECT_CONSTRUCTOR;
   }
   return flags;
 }
 
 Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {

@@ -157,11 +157,11 @@
   }
   Handle resolved;
   int flags = java_lang_invoke_MemberName::flags(mname());
   switch (flags & ALL_KINDS) {
     case IS_METHOD:
-    case IS_CONSTRUCTOR:
+    case IS_OBJECT_CONSTRUCTOR:
       resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
       break;
     case IS_FIELD:
       resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
       break;

@@ -299,12 +299,12 @@
 
   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()) {
-      flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
+    } else if (m->is_object_constructor()) {
+      flags |= IS_OBJECT_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.
       flags |= IS_METHOD      | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);

@@ -337,10 +337,16 @@
 }
 
 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
   int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
   flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
+  if (fd.is_flattenable()) {
+    flags |= JVM_ACC_FIELD_FLATTENABLE;
+  }
+    if (fd.is_flattened()) {
+    flags |= JVM_ACC_FIELD_FLATTENED;
+  }
   if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
   int vmindex        = fd.offset();  // determines the field uniquely when combined with static bit
 
   oop mname_oop = mname();
   java_lang_invoke_MemberName::set_flags  (mname_oop, flags);

@@ -571,11 +577,11 @@
   } else if (sig->char_at(0) != '(') {
     BasicType bt = char2type(sig->char_at(0));
     if (is_subword_type(bt)) {
       bsig = vmSymbols::int_signature();
     } else {
-      assert(bt == T_OBJECT || bt == T_ARRAY, "is_basic_type_signature was false");
+      assert(bt == T_OBJECT || bt == T_ARRAY || bt == T_VALUETYPE, "is_basic_type_signature was false");
       bsig = vmSymbols::object_signature();
     }
   } else {
     ResourceMark rm;
     stringStream buffer(128);

@@ -590,11 +596,11 @@
         buffer.put(')');
       }
       if (arg_pos == keep_arg_pos) {
         buffer.write((char*) ss.raw_bytes(),
                      (int)   ss.raw_length());
-      } else if (bt == T_OBJECT || bt == T_ARRAY) {
+      } else if (bt == T_OBJECT || bt == T_ARRAY || bt == T_VALUETYPE) {
         buffer.write(OBJ_SIG, OBJ_SIG_LEN);
       } else {
         if (is_subword_type(bt))
           bt = T_INT;
         buffer.put(type2char(bt));

@@ -829,20 +835,23 @@
       }
       result.set_resolved_method_name(CHECK_(empty));
       oop mname2 = init_method_MemberName(mname, result);
       return Handle(THREAD, mname2);
     }
-  case IS_CONSTRUCTOR:
+  case IS_OBJECT_CONSTRUCTOR:
     {
       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;
           }

@@ -898,11 +907,11 @@
 
   if (have_defc && have_name && have_type)  return;  // nothing needed
 
   switch (flags & ALL_KINDS) {
   case IS_METHOD:
-  case IS_CONSTRUCTOR:
+  case IS_OBJECT_CONSTRUCTOR:
     {
       Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
       if (vmtarget == NULL) {
         THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
       }

@@ -980,11 +989,11 @@
   if (sig != NULL) {
     if (sig->utf8_length() == 0)  return 0; // a match is not possible
     if (sig->char_at(0) == '(')
       match_flags &= ~(IS_FIELD | IS_TYPE);
     else
-      match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD);
+      match_flags &= ~(IS_OBJECT_CONSTRUCTOR | IS_METHOD);
   }
 
   if ((match_flags & IS_TYPE) != 0) {
     // NYI, and Core Reflection works quite well for this query
   }

@@ -1010,45 +1019,45 @@
         match_flags = 0; break; // got tired of looking at overflow
       }
     }
   }
 
-  if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
+  if ((match_flags & (IS_METHOD | IS_OBJECT_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;
-    // fix name so that it captures the intention of IS_CONSTRUCTOR
+    bool ctor_ok = true, sfac_ok = true;
+    // fix name so that it captures the intention of IS_OBJECT_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
       }
-    } else if (!(match_flags & IS_CONSTRUCTOR)) {
+      sfac_ok = false;
+    } else if (!(match_flags & IS_OBJECT_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++));

@@ -1144,11 +1153,11 @@
 //
 
 #ifndef PRODUCT
 #define EACH_NAMED_CON(template, requirement) \
     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
-    template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
+    template(java_lang_invoke_MemberName,MN_IS_OBJECT_CONSTRUCTOR) \
     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
     template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \

@@ -1269,11 +1278,11 @@
       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) {
+               (flags & ALL_KINDS) == IS_OBJECT_CONSTRUCTOR) {
       THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
     } else {
       THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
     }
   }
< prev index next >