< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page
*** 124,35 ***
  
  // 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,
    TRUSTED_FINAL        = java_lang_invoke_MemberName::MN_TRUSTED_FINAL,
!   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,
!   LM_UNCONDITIONAL     = java_lang_invoke_MemberName::MN_UNCONDITIONAL_MODE,
!   LM_MODULE            = java_lang_invoke_MemberName::MN_MODULE_MODE,
!   LM_TRUSTED           = java_lang_invoke_MemberName::MN_TRUSTED_MODE,
!   ALL_KINDS      = IS_METHOD | IS_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;
    }
    return flags;
  }
  
  Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
--- 124,35 ---
  
  // MemberName support
  
  // import java_lang_invoke_MemberName.*
  enum {
!   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,
    TRUSTED_FINAL        = java_lang_invoke_MemberName::MN_TRUSTED_FINAL,
!   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,
!   LM_UNCONDITIONAL      = java_lang_invoke_MemberName::MN_UNCONDITIONAL_MODE,
!   LM_MODULE             = java_lang_invoke_MemberName::MN_MODULE_MODE,
!   LM_TRUSTED            = java_lang_invoke_MemberName::MN_TRUSTED_MODE,
!   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_OBJECT_CONSTRUCTOR;
    }
    return flags;
  }
  
  Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {

*** 167,11 ***
    }
    Handle resolved;
    int flags = java_lang_invoke_MemberName::flags(mname());
    switch (flags & ALL_KINDS) {
      case IS_METHOD:
!     case IS_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;
--- 167,11 ---
    }
    Handle resolved;
    int flags = java_lang_invoke_MemberName::flags(mname());
    switch (flags & ALL_KINDS) {
      case IS_METHOD:
!     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;

*** 309,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 {
        // "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);
--- 309,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_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);

*** 348,10 ***
--- 348,13 ---
  
  oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
    InstanceKlass* ik = fd.field_holder();
    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_inlined()) {
+     flags |= JVM_ACC_FIELD_INLINED;
+   }
    if (fd.is_trusted_final()) flags |= TRUSTED_FINAL;
    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();

*** 802,20 ***
        }
        result.set_resolved_method_name(CHECK_(empty));
        oop mname2 = init_method_MemberName(mname, result);
        return Handle(THREAD, mname2);
      }
!   case IS_CONSTRUCTOR:
      {
        CallInfo result;
        LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
        {
          assert(!HAS_PENDING_EXCEPTION, "");
!         if (name == vmSymbols::object_initializer_name()) {
            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;
            }
--- 805,23 ---
        }
        result.set_resolved_method_name(CHECK_(empty));
        oop mname2 = init_method_MemberName(mname, result);
        return Handle(THREAD, mname2);
      }
!   case IS_OBJECT_CONSTRUCTOR:
      {
        CallInfo result;
        LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
        {
          assert(!HAS_PENDING_EXCEPTION, "");
!         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 {
!           // 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;
            }

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

*** 950,11 ***
    }
    if (sig != NULL) {
      if (sig->starts_with(JVM_SIGNATURE_FUNC))
        match_flags &= ~(IS_FIELD | IS_TYPE);
      else
!       match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD);
    }
  
    if ((match_flags & IS_TYPE) != 0) {
      // NYI, and Core Reflection works quite well for this query
    }
--- 956,11 ---
    }
    if (sig != NULL) {
      if (sig->starts_with(JVM_SIGNATURE_FUNC))
        match_flags &= ~(IS_FIELD | IS_TYPE);
      else
!       match_flags &= ~(IS_OBJECT_CONSTRUCTOR | IS_METHOD);
    }
  
    if ((match_flags & IS_TYPE) != 0) {
      // NYI, and Core Reflection works quite well for this query
    }

*** 980,45 ***
          match_flags = 0; break; // got tired of looking at overflow
        }
      }
    }
  
!   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;
!     // 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
        }
!     } 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
-       }
      } 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))
            continue;
        if (sig != NULL && m->signature() != sig)
          continue;
        // passed the filters
        if (rskip > 0) {
          --rskip;
        } else if (rfill < rlimit) {
          Handle result(THREAD, results->obj_at(rfill++));
--- 986,45 ---
          match_flags = 0; break; // got tired of looking at overflow
        }
      }
    }
  
!   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 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
        }
!       sfac_ok = false;
+     } else if (!(match_flags & IS_OBJECT_CONSTRUCTOR)) {
        // methods only
!       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)
            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++));

*** 1114,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_FIELD) \
      template(java_lang_invoke_MemberName,MN_IS_TYPE) \
      template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
      template(java_lang_invoke_MemberName,MN_TRUSTED_FINAL) \
      template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
--- 1120,11 ---
  //
  
  #ifndef PRODUCT
  #define EACH_NAMED_CON(template, requirement) \
      template(java_lang_invoke_MemberName,MN_IS_METHOD) \
!     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_TRUSTED_FINAL) \
      template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \

*** 1258,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) {
        THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
      } else {
        THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
      }
    }
--- 1264,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_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 >