src/share/vm/prims/methodHandles.cpp

changeset 2760
328926869b15
parent 2742
ed69575596ac
child 2806
2a23b1b5a0a8
     1.1 --- a/src/share/vm/prims/methodHandles.cpp	Sat Apr 09 21:16:12 2011 -0700
     1.2 +++ b/src/share/vm/prims/methodHandles.cpp	Sat Apr 09 22:55:25 2011 -0700
     1.3 @@ -928,6 +928,7 @@
     1.4  };
     1.5  
     1.6  static bool is_always_null_type(klassOop klass) {
     1.7 +  if (klass == NULL)  return false;  // safety
     1.8    if (!Klass::cast(klass)->oop_is_instance())  return false;
     1.9    instanceKlass* ik = instanceKlass::cast(klass);
    1.10    // Must be on the boot class path:
    1.11 @@ -944,6 +945,8 @@
    1.12  }
    1.13  
    1.14  bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
    1.15 +  if (dst == NULL)  return true;
    1.16 +  if (src == NULL)  return (dst != SystemDictionary::Object_klass());
    1.17    if (src == dst || dst == SystemDictionary::Object_klass())
    1.18      return false;                               // quickest checks
    1.19    Klass* srck = Klass::cast(src);
    1.20 @@ -1026,10 +1029,15 @@
    1.21                                              int first_ptype_pos,
    1.22                                              KlassHandle insert_ptype,
    1.23                                              TRAPS) {
    1.24 +  Handle mhi_type;
    1.25 +  if (m->is_method_handle_invoke()) {
    1.26 +    // use this more exact typing instead of the symbolic signature:
    1.27 +    mhi_type = Handle(THREAD, m->method_handle_type());
    1.28 +  }
    1.29    objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype()));
    1.30    int pnum = first_ptype_pos;
    1.31    int pmax = ptypes->length();
    1.32 -  int mnum = 0;                 // method argument
    1.33 +  int anum = 0;                 // method argument
    1.34    const char* err = NULL;
    1.35    ResourceMark rm(THREAD);
    1.36    for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
    1.37 @@ -1048,47 +1056,70 @@
    1.38        else
    1.39          ptype_oop = insert_ptype->java_mirror();
    1.40        pnum += 1;
    1.41 -      mnum += 1;
    1.42 +      anum += 1;
    1.43      }
    1.44 -    klassOop  pklass = NULL;
    1.45 -    BasicType ptype  = T_OBJECT;
    1.46 -    if (ptype_oop != NULL)
    1.47 -      ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass);
    1.48 -    else
    1.49 -      // null does not match any non-reference; use Object to report the error
    1.50 -      pklass = SystemDictionary::Object_klass();
    1.51 -    klassOop  mklass = NULL;
    1.52 -    BasicType mtype  = ss.type();
    1.53 -    if (mtype == T_ARRAY)  mtype = T_OBJECT; // fold all refs to T_OBJECT
    1.54 -    if (mtype == T_OBJECT) {
    1.55 -      if (ptype_oop == NULL) {
    1.56 +    KlassHandle pklass;
    1.57 +    BasicType   ptype = T_OBJECT;
    1.58 +    bool   have_ptype = false;
    1.59 +    // missing ptype_oop does not match any non-reference; use Object to report the error
    1.60 +    pklass = SystemDictionaryHandles::Object_klass();
    1.61 +    if (ptype_oop != NULL) {
    1.62 +      have_ptype = true;
    1.63 +      klassOop pklass_oop = NULL;
    1.64 +      ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop);
    1.65 +      pklass = KlassHandle(THREAD, pklass_oop);
    1.66 +    }
    1.67 +    ptype_oop = NULL; //done with this
    1.68 +    KlassHandle aklass;
    1.69 +    BasicType   atype = ss.type();
    1.70 +    if (atype == T_ARRAY)  atype = T_OBJECT; // fold all refs to T_OBJECT
    1.71 +    if (atype == T_OBJECT) {
    1.72 +      if (!have_ptype) {
    1.73          // null matches any reference
    1.74          continue;
    1.75        }
    1.76 -      KlassHandle pklass_handle(THREAD, pklass); pklass = NULL;
    1.77 -      // If we fail to resolve types at this point, we will throw an error.
    1.78 -      Symbol* name = ss.as_symbol(CHECK);
    1.79 -      instanceKlass* mk = instanceKlass::cast(m->method_holder());
    1.80 -      Handle loader(THREAD, mk->class_loader());
    1.81 -      Handle domain(THREAD, mk->protection_domain());
    1.82 -      mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
    1.83 -      pklass = pklass_handle();
    1.84 -      if (mklass == NULL && pklass != NULL &&
    1.85 -          Klass::cast(pklass)->name() == name &&
    1.86 -          m->is_method_handle_invoke()) {
    1.87 -        // Assume a match.  We can't really decode the signature of MH.invoke*.
    1.88 -        continue;
    1.89 +      if (mhi_type.is_null()) {
    1.90 +        // If we fail to resolve types at this point, we will usually throw an error.
    1.91 +        TempNewSymbol name = ss.as_symbol_or_null();
    1.92 +        if (name != NULL) {
    1.93 +          instanceKlass* mk = instanceKlass::cast(m->method_holder());
    1.94 +          Handle loader(THREAD, mk->class_loader());
    1.95 +          Handle domain(THREAD, mk->protection_domain());
    1.96 +          klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
    1.97 +          if (aklass_oop != NULL)
    1.98 +            aklass = KlassHandle(THREAD, aklass_oop);
    1.99 +        }
   1.100 +      } else {
   1.101 +        // for method handle invokers we don't look at the name in the signature
   1.102 +        oop atype_oop;
   1.103 +        if (ss.at_return_type())
   1.104 +          atype_oop = java_lang_invoke_MethodType::rtype(mhi_type());
   1.105 +        else
   1.106 +          atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1);
   1.107 +        klassOop aklass_oop = NULL;
   1.108 +        atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop);
   1.109 +        aklass = KlassHandle(THREAD, aklass_oop);
   1.110        }
   1.111      }
   1.112      if (!ss.at_return_type()) {
   1.113 -      err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum);
   1.114 +      err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum);
   1.115      } else {
   1.116 -      err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal!
   1.117 +      err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal!
   1.118      }
   1.119      if (err != NULL)  break;
   1.120    }
   1.121  
   1.122    if (err != NULL) {
   1.123 +#ifndef PRODUCT
   1.124 +    if (PrintMiscellaneous && (Verbose || WizardMode)) {
   1.125 +      tty->print("*** verify_method_signature failed: ");
   1.126 +      java_lang_invoke_MethodType::print_signature(mtype(), tty);
   1.127 +      tty->cr();
   1.128 +      tty->print_cr("    first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype());
   1.129 +      tty->print("    Failing method: ");
   1.130 +      m->print();
   1.131 +    }
   1.132 +#endif //PRODUCT
   1.133      THROW_MSG(vmSymbols::java_lang_InternalError(), err);
   1.134    }
   1.135  }
   1.136 @@ -1288,10 +1319,12 @@
   1.137    // format, format, format
   1.138    const char* src_name = type2name(src_type);
   1.139    const char* dst_name = type2name(dst_type);
   1.140 -  if (src_type == T_OBJECT)  src_name = Klass::cast(src_klass)->external_name();
   1.141 -  if (dst_type == T_OBJECT)  dst_name = Klass::cast(dst_klass)->external_name();
   1.142    if (src_name == NULL)  src_name = "unknown type";
   1.143    if (dst_name == NULL)  dst_name = "unknown type";
   1.144 +  if (src_type == T_OBJECT)
   1.145 +    src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class";
   1.146 +  if (dst_type == T_OBJECT)
   1.147 +    dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class";
   1.148  
   1.149    size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
   1.150    char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);

mercurial