1123 return is_subword_type(dst); |
1131 return is_subword_type(dst); |
1124 if (src == T_BYTE && dst == T_SHORT) |
1132 if (src == T_BYTE && dst == T_SHORT) |
1125 return true; // remaining case: byte fits in short |
1133 return true; // remaining case: byte fits in short |
1126 } |
1134 } |
1127 // allow float/fixed reinterpretation casts |
1135 // allow float/fixed reinterpretation casts |
1128 if (src == T_FLOAT) return dst == T_INT; |
1136 if (is_float_fixed_reinterpretation_cast(src, dst)) |
1129 if (src == T_INT) return dst == T_FLOAT; |
1137 return true; |
1130 if (src == T_DOUBLE) return dst == T_LONG; |
|
1131 if (src == T_LONG) return dst == T_DOUBLE; |
|
1132 return false; |
1138 return false; |
1133 } |
1139 } |
1134 |
1140 |
1135 const char* MethodHandles::check_method_receiver(methodOop m, |
1141 const char* MethodHandles::check_method_receiver(methodOop m, |
1136 klassOop passed_recv_type) { |
1142 klassOop passed_recv_type) { |
1397 BasicType dst_type, |
1403 BasicType dst_type, |
1398 klassOop dst_klass, |
1404 klassOop dst_klass, |
1399 int argnum, |
1405 int argnum, |
1400 bool raw) { |
1406 bool raw) { |
1401 const char* err = NULL; |
1407 const char* err = NULL; |
1402 bool for_return = (argnum < 0); |
1408 const bool for_return = (argnum < 0); |
1403 |
1409 |
1404 // just in case: |
1410 // just in case: |
1405 if (src_type == T_ARRAY) src_type = T_OBJECT; |
1411 if (src_type == T_ARRAY) src_type = T_OBJECT; |
1406 if (dst_type == T_ARRAY) dst_type = T_OBJECT; |
1412 if (dst_type == T_ARRAY) dst_type = T_OBJECT; |
1407 |
1413 |
1408 // Produce some nice messages if VerifyMethodHandles is turned on: |
1414 // Produce some nice messages if VerifyMethodHandles is turned on: |
1409 if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) { |
1415 if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) { |
1410 if (src_type == T_OBJECT) { |
1416 if (src_type == T_OBJECT) { |
1411 if (raw && dst_type == T_INT && is_always_null_type(src_klass)) |
1417 if (raw && is_java_primitive(dst_type)) |
1412 return NULL; // OK to convert a null pointer to a garbage int |
1418 return NULL; // ref-to-prim discards ref and returns zero |
1413 err = ((argnum >= 0) |
1419 err = (!for_return |
1414 ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s" |
1420 ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s" |
1415 : "type mismatch: returning a %s, but caller expects primitive %s"); |
1421 : "type mismatch: returning a %s, but caller expects primitive %s"); |
1416 } else if (dst_type == T_OBJECT) { |
1422 } else if (dst_type == T_OBJECT) { |
1417 err = ((argnum >= 0) |
1423 err = (!for_return |
1418 ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s" |
1424 ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s" |
1419 : "type mismatch: returning a primitive %s, but caller expects %s"); |
1425 : "type mismatch: returning a primitive %s, but caller expects %s"); |
1420 } else { |
1426 } else { |
1421 err = ((argnum >= 0) |
1427 err = (!for_return |
1422 ? "type mismatch: passing a %s for method argument #%d, which expects %s" |
1428 ? "type mismatch: passing a %s for method argument #%d, which expects %s" |
1423 : "type mismatch: returning a %s, but caller expects %s"); |
1429 : "type mismatch: returning a %s, but caller expects %s"); |
1424 } |
1430 } |
1425 } else if (src_type == T_OBJECT && dst_type == T_OBJECT && |
1431 } else if (src_type == T_OBJECT && dst_type == T_OBJECT && |
1426 class_cast_needed(src_klass, dst_klass)) { |
1432 class_cast_needed(src_klass, dst_klass)) { |
1427 if (!class_cast_needed(dst_klass, src_klass)) { |
1433 if (!class_cast_needed(dst_klass, src_klass)) { |
1428 if (raw) |
1434 if (raw) |
1429 return NULL; // reverse cast is OK; the MH target is trusted to enforce it |
1435 return NULL; // reverse cast is OK; the MH target is trusted to enforce it |
1430 err = ((argnum >= 0) |
1436 err = (!for_return |
1431 ? "cast required: passing a %s for method argument #%d, which expects %s" |
1437 ? "cast required: passing a %s for method argument #%d, which expects %s" |
1432 : "cast required: returning a %s, but caller expects %s"); |
1438 : "cast required: returning a %s, but caller expects %s"); |
1433 } else { |
1439 } else { |
1434 err = ((argnum >= 0) |
1440 err = (!for_return |
1435 ? "reference mismatch: passing a %s for method argument #%d, which expects %s" |
1441 ? "reference mismatch: passing a %s for method argument #%d, which expects %s" |
1436 : "reference mismatch: returning a %s, but caller expects %s"); |
1442 : "reference mismatch: returning a %s, but caller expects %s"); |
1437 } |
1443 } |
1438 } else { |
1444 } else { |
1439 // passed the obstacle course |
1445 // passed the obstacle course |
1450 if (dst_type == T_OBJECT) |
1456 if (dst_type == T_OBJECT) |
1451 dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class"; |
1457 dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class"; |
1452 |
1458 |
1453 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); |
1459 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); |
1454 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); |
1460 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); |
1455 if (argnum >= 0) { |
1461 if (!for_return) { |
1456 assert(strstr(err, "%d") != NULL, ""); |
1462 assert(strstr(err, "%d") != NULL, ""); |
1457 jio_snprintf(msg, msglen, err, src_name, argnum, dst_name); |
1463 jio_snprintf(msg, msglen, err, src_name, argnum, dst_name); |
1458 } else { |
1464 } else { |
1459 assert(strstr(err, "%d") == NULL, ""); |
1465 assert(strstr(err, "%d") == NULL, ""); |
1460 jio_snprintf(msg, msglen, err, src_name, dst_name); |
1466 jio_snprintf(msg, msglen, err, src_name, dst_name); |
2178 } |
2184 } |
2179 |
2185 |
2180 } |
2186 } |
2181 |
2187 |
2182 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
2188 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
2183 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
2189 Handle argument = java_lang_invoke_AdapterMethodHandle::argument(mh()); |
2184 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
2190 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
2185 jint conv_op = adapter_conversion_op(conversion); |
2191 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
|
2192 jint conv_op = adapter_conversion_op(conversion); |
2186 |
2193 |
2187 // adjust the adapter code to the internal EntryKind enumeration: |
2194 // adjust the adapter code to the internal EntryKind enumeration: |
2188 EntryKind ek_orig = adapter_entry_kind(conv_op); |
2195 EntryKind ek_orig = adapter_entry_kind(conv_op); |
2189 EntryKind ek_opt = ek_orig; // may be optimized |
2196 EntryKind ek_opt = ek_orig; // may be optimized |
2190 EntryKind ek_try; // temp |
2197 EntryKind ek_try; // temp |
2239 ek_opt = _adapter_opt_l2i; |
2246 ek_opt = _adapter_opt_l2i; |
2240 vminfo = adapter_prim_to_prim_subword_vminfo(dest); |
2247 vminfo = adapter_prim_to_prim_subword_vminfo(dest); |
2241 } else if (src == T_DOUBLE && dest == T_FLOAT) { |
2248 } else if (src == T_DOUBLE && dest == T_FLOAT) { |
2242 ek_opt = _adapter_opt_d2f; |
2249 ek_opt = _adapter_opt_d2f; |
2243 } else { |
2250 } else { |
2244 assert(false, ""); |
2251 goto throw_not_impl; // runs user code, hence could block |
2245 } |
2252 } |
2246 break; |
2253 break; |
2247 case 1 *4+ 2: |
2254 case 1 *4+ 2: |
2248 if ((src == T_INT || is_subword_type(src)) && dest == T_LONG) { |
2255 if ((src == T_INT || is_subword_type(src)) && dest == T_LONG) { |
2249 ek_opt = _adapter_opt_i2l; |
2256 ek_opt = _adapter_opt_i2l; |
2250 } else if (src == T_FLOAT && dest == T_DOUBLE) { |
2257 } else if (src == T_FLOAT && dest == T_DOUBLE) { |
2251 ek_opt = _adapter_opt_f2d; |
2258 ek_opt = _adapter_opt_f2d; |
2252 } else { |
2259 } else { |
2253 assert(false, ""); |
2260 goto throw_not_impl; // runs user code, hence could block |
2254 } |
2261 } |
2255 break; |
2262 break; |
2256 default: |
2263 default: |
2257 assert(false, ""); |
2264 goto throw_not_impl; // runs user code, hence could block |
2258 break; |
2265 break; |
2259 } |
2266 } |
2260 } |
2267 } |
2261 break; |
2268 break; |
2262 |
2269 |
2282 assert(UseRicochetFrames, "else don't come here"); |
2289 assert(UseRicochetFrames, "else don't come here"); |
2283 // vminfo will be the location to insert the return value |
2290 // vminfo will be the location to insert the return value |
2284 vminfo = argslot; |
2291 vminfo = argslot; |
2285 ek_opt = _adapter_opt_collect_ref; |
2292 ek_opt = _adapter_opt_collect_ref; |
2286 ensure_vmlayout_field(target, CHECK); |
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 if (!OptimizeMethodHandles) break; |
2297 if (!OptimizeMethodHandles) break; |
2288 switch (type2size[src]) { |
2298 switch (type2size[src]) { |
2289 case 1: |
2299 case 1: |
2290 ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot); |
2300 ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot); |
2291 if (ek_try < _adapter_opt_collect_LAST && |
2301 if (ek_try < _adapter_opt_collect_LAST && |
2400 break; |
2410 break; |
2401 |
2411 |
2402 case _adapter_collect_args: |
2412 case _adapter_collect_args: |
2403 { |
2413 { |
2404 assert(UseRicochetFrames, "else don't come here"); |
2414 assert(UseRicochetFrames, "else don't come here"); |
2405 int elem_slots = argument_slot_count( |
2415 int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument())); |
2406 java_lang_invoke_MethodHandle::type( |
|
2407 java_lang_invoke_AdapterMethodHandle::argument(mh()) ) ); |
|
2408 // vminfo will be the location to insert the return value |
2416 // vminfo will be the location to insert the return value |
2409 vminfo = argslot; |
2417 vminfo = argslot; |
2410 ensure_vmlayout_field(target, CHECK); |
2418 ensure_vmlayout_field(target, CHECK); |
|
2419 ensure_vmlayout_field(argument, CHECK); |
2411 |
2420 |
2412 // general case: |
2421 // general case: |
2413 switch (dest) { |
2422 switch (dest) { |
2414 default : if (!is_subword_type(dest)) goto throw_not_impl; |
2423 default : if (!is_subword_type(dest)) goto throw_not_impl; |
2415 // else fall through: |
2424 // else fall through: |
2470 } |
2479 } |
2471 |
2480 |
2472 case _adapter_fold_args: |
2481 case _adapter_fold_args: |
2473 { |
2482 { |
2474 assert(UseRicochetFrames, "else don't come here"); |
2483 assert(UseRicochetFrames, "else don't come here"); |
2475 int elem_slots = argument_slot_count( |
2484 int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument())); |
2476 java_lang_invoke_MethodHandle::type( |
|
2477 java_lang_invoke_AdapterMethodHandle::argument(mh()) ) ); |
|
2478 // vminfo will be the location to insert the return value |
2485 // vminfo will be the location to insert the return value |
2479 vminfo = argslot + elem_slots; |
2486 vminfo = argslot + elem_slots; |
2480 ensure_vmlayout_field(target, CHECK); |
2487 ensure_vmlayout_field(target, CHECK); |
|
2488 ensure_vmlayout_field(argument, CHECK); |
2481 |
2489 |
2482 switch (dest) { |
2490 switch (dest) { |
2483 default : if (!is_subword_type(dest)) goto throw_not_impl; |
2491 default : if (!is_subword_type(dest)) goto throw_not_impl; |
2484 // else fall through: |
2492 // else fall through: |
2485 case T_INT : ek_opt = _adapter_opt_fold_int; break; |
2493 case T_INT : ek_opt = _adapter_opt_fold_int; break; |
2525 if (err == NULL) |
2533 if (err == NULL) |
2526 err = "unknown adapter type"; |
2534 err = "unknown adapter type"; |
2527 break; |
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 // should not happen, since vminfo is used to encode arg/slot indexes < 255 |
2539 // should not happen, since vminfo is used to encode arg/slot indexes < 255 |
2532 err = "vminfo overflow"; |
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 err = "adapter stub for this kind of method handle is missing"; |
2544 err = "adapter stub for this kind of method handle is missing"; |
|
2545 } |
|
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 } |
2537 } |
2561 } |
2538 |
2562 |
2539 if (err != NULL) { |
2563 if (err != NULL) { |
2540 throw_InternalError_for_bad_conversion(conversion, err, THREAD); |
2564 throw_InternalError_for_bad_conversion(conversion, err, THREAD); |
2541 return; |
2565 return; |