src/share/vm/prims/methodHandles.cpp

changeset 2903
fabcf26ee72f
parent 2895
167b70ff3abc
child 2919
2848194272f4
child 2920
a80577f854f9
     1.1 --- a/src/share/vm/prims/methodHandles.cpp	Thu May 12 10:33:17 2011 -0700
     1.2 +++ b/src/share/vm/prims/methodHandles.cpp	Thu May 12 14:04:48 2011 -0700
     1.3 @@ -1099,6 +1099,14 @@
     1.4    return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
     1.5  }
     1.6  
     1.7 +bool MethodHandles::is_float_fixed_reinterpretation_cast(BasicType src, BasicType dst) {
     1.8 +  if (src == T_FLOAT)   return dst == T_INT;
     1.9 +  if (src == T_INT)     return dst == T_FLOAT;
    1.10 +  if (src == T_DOUBLE)  return dst == T_LONG;
    1.11 +  if (src == T_LONG)    return dst == T_DOUBLE;
    1.12 +  return false;
    1.13 +}
    1.14 +
    1.15  bool MethodHandles::same_basic_type_for_arguments(BasicType src,
    1.16                                                    BasicType dst,
    1.17                                                    bool raw,
    1.18 @@ -1125,10 +1133,8 @@
    1.19        return true;            // remaining case: byte fits in short
    1.20    }
    1.21    // allow float/fixed reinterpretation casts
    1.22 -  if (src == T_FLOAT)   return dst == T_INT;
    1.23 -  if (src == T_INT)     return dst == T_FLOAT;
    1.24 -  if (src == T_DOUBLE)  return dst == T_LONG;
    1.25 -  if (src == T_LONG)    return dst == T_DOUBLE;
    1.26 +  if (is_float_fixed_reinterpretation_cast(src, dst))
    1.27 +    return true;
    1.28    return false;
    1.29  }
    1.30  
    1.31 @@ -1399,7 +1405,7 @@
    1.32                                                        int argnum,
    1.33                                                        bool raw) {
    1.34    const char* err = NULL;
    1.35 -  bool for_return = (argnum < 0);
    1.36 +  const bool for_return = (argnum < 0);
    1.37  
    1.38    // just in case:
    1.39    if (src_type == T_ARRAY)  src_type = T_OBJECT;
    1.40 @@ -1408,17 +1414,17 @@
    1.41    // Produce some nice messages if VerifyMethodHandles is turned on:
    1.42    if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) {
    1.43      if (src_type == T_OBJECT) {
    1.44 -      if (raw && dst_type == T_INT && is_always_null_type(src_klass))
    1.45 -        return NULL;    // OK to convert a null pointer to a garbage int
    1.46 -      err = ((argnum >= 0)
    1.47 +      if (raw && is_java_primitive(dst_type))
    1.48 +        return NULL;    // ref-to-prim discards ref and returns zero
    1.49 +      err = (!for_return
    1.50               ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s"
    1.51               : "type mismatch: returning a %s, but caller expects primitive %s");
    1.52      } else if (dst_type == T_OBJECT) {
    1.53 -      err = ((argnum >= 0)
    1.54 +      err = (!for_return
    1.55               ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s"
    1.56               : "type mismatch: returning a primitive %s, but caller expects %s");
    1.57      } else {
    1.58 -      err = ((argnum >= 0)
    1.59 +      err = (!for_return
    1.60               ? "type mismatch: passing a %s for method argument #%d, which expects %s"
    1.61               : "type mismatch: returning a %s, but caller expects %s");
    1.62      }
    1.63 @@ -1427,11 +1433,11 @@
    1.64      if (!class_cast_needed(dst_klass, src_klass)) {
    1.65        if (raw)
    1.66          return NULL;    // reverse cast is OK; the MH target is trusted to enforce it
    1.67 -      err = ((argnum >= 0)
    1.68 +      err = (!for_return
    1.69               ? "cast required: passing a %s for method argument #%d, which expects %s"
    1.70               : "cast required: returning a %s, but caller expects %s");
    1.71      } else {
    1.72 -      err = ((argnum >= 0)
    1.73 +      err = (!for_return
    1.74               ? "reference mismatch: passing a %s for method argument #%d, which expects %s"
    1.75               : "reference mismatch: returning a %s, but caller expects %s");
    1.76      }
    1.77 @@ -1452,7 +1458,7 @@
    1.78  
    1.79    size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
    1.80    char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
    1.81 -  if (argnum >= 0) {
    1.82 +  if (!for_return) {
    1.83      assert(strstr(err, "%d") != NULL, "");
    1.84      jio_snprintf(msg, msglen, err, src_name, argnum, dst_name);
    1.85    } else {
    1.86 @@ -2180,9 +2186,10 @@
    1.87  }
    1.88  
    1.89  void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
    1.90 -  int  argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
    1.91 -  jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
    1.92 -  jint conv_op    = adapter_conversion_op(conversion);
    1.93 +  Handle argument   = java_lang_invoke_AdapterMethodHandle::argument(mh());
    1.94 +  int    argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
    1.95 +  jint   conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
    1.96 +  jint   conv_op    = adapter_conversion_op(conversion);
    1.97  
    1.98    // adjust the adapter code to the internal EntryKind enumeration:
    1.99    EntryKind ek_orig = adapter_entry_kind(conv_op);
   1.100 @@ -2241,7 +2248,7 @@
   1.101          } else if (src == T_DOUBLE && dest == T_FLOAT) {
   1.102            ek_opt = _adapter_opt_d2f;
   1.103          } else {
   1.104 -          assert(false, "");
   1.105 +          goto throw_not_impl;        // runs user code, hence could block
   1.106          }
   1.107          break;
   1.108        case 1 *4+ 2:
   1.109 @@ -2250,11 +2257,11 @@
   1.110          } else if (src == T_FLOAT && dest == T_DOUBLE) {
   1.111            ek_opt = _adapter_opt_f2d;
   1.112          } else {
   1.113 -          assert(false, "");
   1.114 +          goto throw_not_impl;        // runs user code, hence could block
   1.115          }
   1.116          break;
   1.117        default:
   1.118 -        assert(false, "");
   1.119 +        goto throw_not_impl;        // runs user code, hence could block
   1.120          break;
   1.121        }
   1.122      }
   1.123 @@ -2271,7 +2278,7 @@
   1.124          ek_opt = _adapter_opt_unboxl;
   1.125          break;
   1.126        default:
   1.127 -        assert(false, "");
   1.128 +        goto throw_not_impl;
   1.129          break;
   1.130        }
   1.131      }
   1.132 @@ -2284,6 +2291,9 @@
   1.133        vminfo = argslot;
   1.134        ek_opt = _adapter_opt_collect_ref;
   1.135        ensure_vmlayout_field(target, CHECK);
   1.136 +      // for MethodHandleWalk:
   1.137 +      if (java_lang_invoke_AdapterMethodHandle::is_instance(argument()))
   1.138 +        ensure_vmlayout_field(argument, CHECK);
   1.139        if (!OptimizeMethodHandles)  break;
   1.140        switch (type2size[src]) {
   1.141        case 1:
   1.142 @@ -2311,7 +2321,7 @@
   1.143          ek_opt = _adapter_opt_collect_2_ref;
   1.144          break;
   1.145        default:
   1.146 -        assert(false, "");
   1.147 +        goto throw_not_impl;
   1.148          break;
   1.149        }
   1.150      }
   1.151 @@ -2335,7 +2345,7 @@
   1.152                    rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
   1.153          break;
   1.154        default:
   1.155 -        assert(false, "");
   1.156 +        goto throw_not_impl;
   1.157          break;
   1.158        }
   1.159      }
   1.160 @@ -2402,12 +2412,11 @@
   1.161    case _adapter_collect_args:
   1.162      {
   1.163        assert(UseRicochetFrames, "else don't come here");
   1.164 -      int elem_slots = argument_slot_count(
   1.165 -                           java_lang_invoke_MethodHandle::type(
   1.166 -                               java_lang_invoke_AdapterMethodHandle::argument(mh()) ) );
   1.167 +      int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
   1.168        // vminfo will be the location to insert the return value
   1.169        vminfo = argslot;
   1.170        ensure_vmlayout_field(target, CHECK);
   1.171 +      ensure_vmlayout_field(argument, CHECK);
   1.172  
   1.173        // general case:
   1.174        switch (dest) {
   1.175 @@ -2472,12 +2481,11 @@
   1.176    case _adapter_fold_args:
   1.177      {
   1.178        assert(UseRicochetFrames, "else don't come here");
   1.179 -      int elem_slots = argument_slot_count(
   1.180 -                           java_lang_invoke_MethodHandle::type(
   1.181 -                               java_lang_invoke_AdapterMethodHandle::argument(mh()) ) );
   1.182 +      int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
   1.183        // vminfo will be the location to insert the return value
   1.184        vminfo = argslot + elem_slots;
   1.185        ensure_vmlayout_field(target, CHECK);
   1.186 +      ensure_vmlayout_field(argument, CHECK);
   1.187  
   1.188        switch (dest) {
   1.189        default       : if (!is_subword_type(dest))  goto throw_not_impl;
   1.190 @@ -2527,15 +2535,31 @@
   1.191      break;
   1.192    }
   1.193  
   1.194 -  if (err != NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) {
   1.195 +  if (err == NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) {
   1.196      // should not happen, since vminfo is used to encode arg/slot indexes < 255
   1.197      err = "vminfo overflow";
   1.198    }
   1.199  
   1.200 -  if (err != NULL && !have_entry(ek_opt)) {
   1.201 +  if (err == NULL && !have_entry(ek_opt)) {
   1.202      err = "adapter stub for this kind of method handle is missing";
   1.203    }
   1.204  
   1.205 +  if (err == NULL && ek_opt == ek_orig) {
   1.206 +    switch (ek_opt) {
   1.207 +    case _adapter_prim_to_prim:
   1.208 +    case _adapter_ref_to_prim:
   1.209 +    case _adapter_prim_to_ref:
   1.210 +    case _adapter_swap_args:
   1.211 +    case _adapter_rot_args:
   1.212 +    case _adapter_collect_args:
   1.213 +    case _adapter_fold_args:
   1.214 +    case _adapter_spread_args:
   1.215 +      // should be handled completely by optimized cases; see above
   1.216 +      err = "init_AdapterMethodHandle should not issue this";
   1.217 +      break;
   1.218 +    }
   1.219 +  }
   1.220 +
   1.221    if (err != NULL) {
   1.222      throw_InternalError_for_bad_conversion(conversion, err, THREAD);
   1.223      return;

mercurial