Print this page


Split Close
Expand all
Collapse all
          --- old/src/share/vm/prims/methodHandles.cpp
          +++ new/src/share/vm/prims/methodHandles.cpp
↓ open down ↓ 1091 lines elided ↑ open up ↑
1092 1092      // such null references never fail to convert safely
1093 1093      return false;
1094 1094    }
1095 1095    return !srck->is_subclass_of(dstk->as_klassOop());
1096 1096  }
1097 1097  
1098 1098  static oop object_java_mirror() {
1099 1099    return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
1100 1100  }
1101 1101  
     1102 +bool MethodHandles::is_float_fixed_reinterpretation_cast(BasicType src, BasicType dst) {
     1103 +  if (src == T_FLOAT)   return dst == T_INT;
     1104 +  if (src == T_INT)     return dst == T_FLOAT;
     1105 +  if (src == T_DOUBLE)  return dst == T_LONG;
     1106 +  if (src == T_LONG)    return dst == T_DOUBLE;
     1107 +  return false;
     1108 +}
     1109 +
1102 1110  bool MethodHandles::same_basic_type_for_arguments(BasicType src,
1103 1111                                                    BasicType dst,
1104 1112                                                    bool raw,
1105 1113                                                    bool for_return) {
1106 1114    if (for_return) {
1107 1115      // return values can always be forgotten:
1108 1116      if (dst == T_VOID)  return true;
1109 1117      if (src == T_VOID)  return raw && (dst == T_INT);
1110 1118      // We allow caller to receive a garbage int, which is harmless.
1111 1119      // This trick is pulled by trusted code (see VerifyType.canPassRaw).
↓ open down ↓ 6 lines elided ↑ open up ↑
1118 1126    // allow reinterpretation casts for integral widening
1119 1127    if (is_subword_type(src)) { // subwords can fit in int or other subwords
1120 1128      if (dst == T_INT)         // any subword fits in an int
1121 1129        return true;
1122 1130      if (src == T_BOOLEAN)     // boolean fits in any subword
1123 1131        return is_subword_type(dst);
1124 1132      if (src == T_BYTE && dst == T_SHORT)
1125 1133        return true;            // remaining case: byte fits in short
1126 1134    }
1127 1135    // allow float/fixed reinterpretation casts
1128      -  if (src == T_FLOAT)   return dst == T_INT;
1129      -  if (src == T_INT)     return dst == T_FLOAT;
1130      -  if (src == T_DOUBLE)  return dst == T_LONG;
1131      -  if (src == T_LONG)    return dst == T_DOUBLE;
     1136 +  if (is_float_fixed_reinterpretation_cast(src, dst))
     1137 +    return true;
1132 1138    return false;
1133 1139  }
1134 1140  
1135 1141  const char* MethodHandles::check_method_receiver(methodOop m,
1136 1142                                                   klassOop passed_recv_type) {
1137 1143    assert(!m->is_static(), "caller resp.");
1138 1144    if (passed_recv_type == NULL)
1139 1145      return "receiver type is primitive";
1140 1146    if (class_cast_needed(passed_recv_type, m->method_holder())) {
1141 1147      Klass* formal = Klass::cast(m->method_holder());
↓ open down ↓ 250 lines elided ↑ open up ↑
1392 1398  }
1393 1399  
1394 1400  
1395 1401  const char* MethodHandles::check_argument_type_change(BasicType src_type,
1396 1402                                                        klassOop src_klass,
1397 1403                                                        BasicType dst_type,
1398 1404                                                        klassOop dst_klass,
1399 1405                                                        int argnum,
1400 1406                                                        bool raw) {
1401 1407    const char* err = NULL;
1402      -  bool for_return = (argnum < 0);
     1408 +  const bool for_return = (argnum < 0);
1403 1409  
1404 1410    // just in case:
1405 1411    if (src_type == T_ARRAY)  src_type = T_OBJECT;
1406 1412    if (dst_type == T_ARRAY)  dst_type = T_OBJECT;
1407 1413  
1408 1414    // Produce some nice messages if VerifyMethodHandles is turned on:
1409 1415    if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) {
1410 1416      if (src_type == T_OBJECT) {
1411      -      if (raw && dst_type == T_INT && is_always_null_type(src_klass))
1412      -        return NULL;    // OK to convert a null pointer to a garbage int
1413      -      err = ((argnum >= 0)
     1417 +      if (raw && is_java_primitive(dst_type))
     1418 +        return NULL;    // ref-to-prim discards ref and returns zero
     1419 +      err = (!for_return
1414 1420               ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s"
1415 1421               : "type mismatch: returning a %s, but caller expects primitive %s");
1416 1422      } else if (dst_type == T_OBJECT) {
1417      -      err = ((argnum >= 0)
     1423 +      err = (!for_return
1418 1424               ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s"
1419 1425               : "type mismatch: returning a primitive %s, but caller expects %s");
1420 1426      } else {
1421      -      err = ((argnum >= 0)
     1427 +      err = (!for_return
1422 1428               ? "type mismatch: passing a %s for method argument #%d, which expects %s"
1423 1429               : "type mismatch: returning a %s, but caller expects %s");
1424 1430      }
1425 1431    } else if (src_type == T_OBJECT && dst_type == T_OBJECT &&
1426 1432               class_cast_needed(src_klass, dst_klass)) {
1427 1433      if (!class_cast_needed(dst_klass, src_klass)) {
1428 1434        if (raw)
1429 1435          return NULL;    // reverse cast is OK; the MH target is trusted to enforce it
1430      -      err = ((argnum >= 0)
     1436 +      err = (!for_return
1431 1437               ? "cast required: passing a %s for method argument #%d, which expects %s"
1432 1438               : "cast required: returning a %s, but caller expects %s");
1433 1439      } else {
1434      -      err = ((argnum >= 0)
     1440 +      err = (!for_return
1435 1441               ? "reference mismatch: passing a %s for method argument #%d, which expects %s"
1436 1442               : "reference mismatch: returning a %s, but caller expects %s");
1437 1443      }
1438 1444    } else {
1439 1445      // passed the obstacle course
1440 1446      return NULL;
1441 1447    }
1442 1448  
1443 1449    // format, format, format
1444 1450    const char* src_name = type2name(src_type);
1445 1451    const char* dst_name = type2name(dst_type);
1446 1452    if (src_name == NULL)  src_name = "unknown type";
1447 1453    if (dst_name == NULL)  dst_name = "unknown type";
1448 1454    if (src_type == T_OBJECT)
1449 1455      src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class";
1450 1456    if (dst_type == T_OBJECT)
1451 1457      dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class";
1452 1458  
1453 1459    size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
1454 1460    char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
1455      -  if (argnum >= 0) {
     1461 +  if (!for_return) {
1456 1462      assert(strstr(err, "%d") != NULL, "");
1457 1463      jio_snprintf(msg, msglen, err, src_name, argnum, dst_name);
1458 1464    } else {
1459 1465      assert(strstr(err, "%d") == NULL, "");
1460 1466      jio_snprintf(msg, msglen, err, src_name,         dst_name);
1461 1467    }
1462 1468    return msg;
1463 1469  }
1464 1470  
1465 1471  // Compute the depth within the stack of the given argument, i.e.,
↓ open down ↓ 707 lines elided ↑ open up ↑
2173 2179    }
2174 2180  
2175 2181    if (err != NULL) {
2176 2182      throw_InternalError_for_bad_conversion(conversion, err, THREAD);
2177 2183      return;
2178 2184    }
2179 2185  
2180 2186  }
2181 2187  
2182 2188  void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
2183      -  int  argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
2184      -  jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
2185      -  jint conv_op    = adapter_conversion_op(conversion);
     2189 +  Handle argument   = java_lang_invoke_AdapterMethodHandle::argument(mh());
     2190 +  int    argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
     2191 +  jint   conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
     2192 +  jint   conv_op    = adapter_conversion_op(conversion);
2186 2193  
2187 2194    // adjust the adapter code to the internal EntryKind enumeration:
2188 2195    EntryKind ek_orig = adapter_entry_kind(conv_op);
2189 2196    EntryKind ek_opt  = ek_orig;  // may be optimized
2190 2197    EntryKind ek_try;             // temp
2191 2198  
2192 2199    // Finalize the vmtarget field (Java initialized it to null).
2193 2200    if (!java_lang_invoke_MethodHandle::is_instance(target())) {
2194 2201      throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
2195 2202      return;
↓ open down ↓ 38 lines elided ↑ open up ↑
2234 2241          ek_opt = _adapter_opt_i2i;
2235 2242          vminfo = adapter_prim_to_prim_subword_vminfo(dest);
2236 2243          break;
2237 2244        case 2 *4+ 1:
2238 2245          if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
2239 2246            ek_opt = _adapter_opt_l2i;
2240 2247            vminfo = adapter_prim_to_prim_subword_vminfo(dest);
2241 2248          } else if (src == T_DOUBLE && dest == T_FLOAT) {
2242 2249            ek_opt = _adapter_opt_d2f;
2243 2250          } else {
2244      -          assert(false, "");
     2251 +          goto throw_not_impl;        // runs user code, hence could block
2245 2252          }
2246 2253          break;
2247 2254        case 1 *4+ 2:
2248 2255          if ((src == T_INT || is_subword_type(src)) && dest == T_LONG) {
2249 2256            ek_opt = _adapter_opt_i2l;
2250 2257          } else if (src == T_FLOAT && dest == T_DOUBLE) {
2251 2258            ek_opt = _adapter_opt_f2d;
2252 2259          } else {
2253      -          assert(false, "");
     2260 +          goto throw_not_impl;        // runs user code, hence could block
2254 2261          }
2255 2262          break;
2256 2263        default:
2257      -        assert(false, "");
     2264 +        goto throw_not_impl;        // runs user code, hence could block
2258 2265          break;
2259 2266        }
2260 2267      }
2261 2268      break;
2262 2269  
2263 2270    case _adapter_ref_to_prim:
2264 2271      {
2265 2272        switch (type2size[dest]) {
2266 2273        case 1:
2267 2274          ek_opt = _adapter_opt_unboxi;
2268 2275          vminfo = adapter_unbox_subword_vminfo(dest);
2269 2276          break;
2270 2277        case 2:
2271 2278          ek_opt = _adapter_opt_unboxl;
2272 2279          break;
2273 2280        default:
2274      -        assert(false, "");
     2281 +        goto throw_not_impl;
2275 2282          break;
2276 2283        }
2277 2284      }
2278 2285      break;
2279 2286  
2280 2287    case _adapter_prim_to_ref:
2281 2288      {
2282 2289        assert(UseRicochetFrames, "else don't come here");
2283 2290        // vminfo will be the location to insert the return value
2284 2291        vminfo = argslot;
2285 2292        ek_opt = _adapter_opt_collect_ref;
2286 2293        ensure_vmlayout_field(target, CHECK);
     2294 +      // for MethodHandleWalk:
     2295 +      if (java_lang_invoke_AdapterMethodHandle::is_instance(argument()))
     2296 +        ensure_vmlayout_field(argument, CHECK);
2287 2297        if (!OptimizeMethodHandles)  break;
2288 2298        switch (type2size[src]) {
2289 2299        case 1:
2290 2300          ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot);
2291 2301          if (ek_try < _adapter_opt_collect_LAST &&
2292 2302              ek_adapter_opt_collect_slot(ek_try) == argslot) {
2293 2303            assert(ek_adapter_opt_collect_count(ek_try) == 1 &&
2294 2304                   ek_adapter_opt_collect_type(ek_try) == T_OBJECT, "");
2295 2305            ek_opt = ek_try;
2296 2306            break;
↓ open down ↓ 7 lines elided ↑ open up ↑
2304 2314              ek_adapter_opt_collect_slot(ek_try) == argslot) {
2305 2315            assert(ek_adapter_opt_collect_count(ek_try) == 2 &&
2306 2316                   ek_adapter_opt_collect_type(ek_try) == T_OBJECT, "");
2307 2317            ek_opt = ek_try;
2308 2318            break;
2309 2319          }
2310 2320          // else downgrade to variable slot:
2311 2321          ek_opt = _adapter_opt_collect_2_ref;
2312 2322          break;
2313 2323        default:
2314      -        assert(false, "");
     2324 +        goto throw_not_impl;
2315 2325          break;
2316 2326        }
2317 2327      }
2318 2328      break;
2319 2329  
2320 2330    case _adapter_swap_args:
2321 2331    case _adapter_rot_args:
2322 2332      {
2323 2333        int swap_slots = type2size[src];
2324 2334        int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(mh());
↓ open down ↓ 3 lines elided ↑ open up ↑
2328 2338        switch (swap_slots) {
2329 2339        case 1:
2330 2340          ek_opt = (!rotate    ? _adapter_opt_swap_1 :
2331 2341                    rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
2332 2342          break;
2333 2343        case 2:
2334 2344          ek_opt = (!rotate    ? _adapter_opt_swap_2 :
2335 2345                    rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
2336 2346          break;
2337 2347        default:
2338      -        assert(false, "");
     2348 +        goto throw_not_impl;
2339 2349          break;
2340 2350        }
2341 2351      }
2342 2352      break;
2343 2353  
2344 2354    case _adapter_spread_args:
2345 2355      {
2346 2356  #ifdef TARGET_ARCH_NYI_6939861
2347 2357        // ports before 6939861 supported only three kinds of spread ops
2348 2358        if (!UseRicochetFrames) {
↓ open down ↓ 46 lines elided ↑ open up ↑
2395 2405            break;
2396 2406          }
2397 2407        }
2398 2408        break;
2399 2409      }
2400 2410      break;
2401 2411  
2402 2412    case _adapter_collect_args:
2403 2413      {
2404 2414        assert(UseRicochetFrames, "else don't come here");
2405      -      int elem_slots = argument_slot_count(
2406      -                           java_lang_invoke_MethodHandle::type(
2407      -                               java_lang_invoke_AdapterMethodHandle::argument(mh()) ) );
     2415 +      int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
2408 2416        // vminfo will be the location to insert the return value
2409 2417        vminfo = argslot;
2410 2418        ensure_vmlayout_field(target, CHECK);
     2419 +      ensure_vmlayout_field(argument, CHECK);
2411 2420  
2412 2421        // general case:
2413 2422        switch (dest) {
2414 2423        default       : if (!is_subword_type(dest))  goto throw_not_impl;
2415 2424                      // else fall through:
2416 2425        case T_INT    : ek_opt = _adapter_opt_collect_int;     break;
2417 2426        case T_LONG   : ek_opt = _adapter_opt_collect_long;    break;
2418 2427        case T_FLOAT  : ek_opt = _adapter_opt_collect_float;   break;
2419 2428        case T_DOUBLE : ek_opt = _adapter_opt_collect_double;  break;
2420 2429        case T_OBJECT : ek_opt = _adapter_opt_collect_ref;     break;
↓ open down ↓ 44 lines elided ↑ open up ↑
2465 2474            break;
2466 2475          }
2467 2476        }
2468 2477  
2469 2478        break;
2470 2479      }
2471 2480  
2472 2481    case _adapter_fold_args:
2473 2482      {
2474 2483        assert(UseRicochetFrames, "else don't come here");
2475      -      int elem_slots = argument_slot_count(
2476      -                           java_lang_invoke_MethodHandle::type(
2477      -                               java_lang_invoke_AdapterMethodHandle::argument(mh()) ) );
     2484 +      int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
2478 2485        // vminfo will be the location to insert the return value
2479 2486        vminfo = argslot + elem_slots;
2480 2487        ensure_vmlayout_field(target, CHECK);
     2488 +      ensure_vmlayout_field(argument, CHECK);
2481 2489  
2482 2490        switch (dest) {
2483 2491        default       : if (!is_subword_type(dest))  goto throw_not_impl;
2484 2492                      // else fall through:
2485 2493        case T_INT    : ek_opt = _adapter_opt_fold_int;     break;
2486 2494        case T_LONG   : ek_opt = _adapter_opt_fold_long;    break;
2487 2495        case T_FLOAT  : ek_opt = _adapter_opt_fold_float;   break;
2488 2496        case T_DOUBLE : ek_opt = _adapter_opt_fold_double;  break;
2489 2497        case T_OBJECT : ek_opt = _adapter_opt_fold_ref;     break;
2490 2498        case T_VOID   : ek_opt = _adapter_opt_fold_void;    break;
↓ open down ↓ 29 lines elided ↑ open up ↑
2520 2528      // should have failed much earlier; must be a missing case here
2521 2529      assert(false, "incomplete switch");
2522 2530      // and fall through:
2523 2531  
2524 2532    throw_not_impl:
2525 2533      if (err == NULL)
2526 2534        err = "unknown adapter type";
2527 2535      break;
2528 2536    }
2529 2537  
2530      -  if (err != NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) {
     2538 +  if (err == NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) {
2531 2539      // should not happen, since vminfo is used to encode arg/slot indexes < 255
2532 2540      err = "vminfo overflow";
2533 2541    }
2534 2542  
2535      -  if (err != NULL && !have_entry(ek_opt)) {
     2543 +  if (err == NULL && !have_entry(ek_opt)) {
2536 2544      err = "adapter stub for this kind of method handle is missing";
2537 2545    }
2538 2546  
     2547 +  if (err == NULL && ek_opt == ek_orig) {
     2548 +    switch (ek_opt) {
     2549 +    case _adapter_prim_to_prim:
     2550 +    case _adapter_ref_to_prim:
     2551 +    case _adapter_prim_to_ref:
     2552 +    case _adapter_swap_args:
     2553 +    case _adapter_rot_args:
     2554 +    case _adapter_collect_args:
     2555 +    case _adapter_fold_args:
     2556 +    case _adapter_spread_args:
     2557 +      // should be handled completely by optimized cases; see above
     2558 +      err = "init_AdapterMethodHandle should not issue this";
     2559 +      break;
     2560 +    }
     2561 +  }
     2562 +
2539 2563    if (err != NULL) {
2540 2564      throw_InternalError_for_bad_conversion(conversion, err, THREAD);
2541 2565      return;
2542 2566    }
2543 2567  
2544 2568    // Rebuild the conversion value; maybe parts of it were changed.
2545 2569    jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
2546 2570  
2547 2571    // Finalize the conversion field.  (Note that it is final to Java code.)
2548 2572    java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion);
↓ open down ↓ 438 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX