comparison src/share/vm/prims/methodHandleWalk.cpp @ 3371:fabcf26ee72f

6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW Reviewed-by: jrose, kvn, never
author twisti
date Thu, 12 May 2011 14:04:48 -0700
parents e2a92dd0d3d2
children 33ae33516634
comparison
equal deleted inserted replaced
3370:2f17eb233d13 3371:fabcf26ee72f
29 29
30 /* 30 /*
31 * JSR 292 reference implementation: method handle structure analysis 31 * JSR 292 reference implementation: method handle structure analysis
32 */ 32 */
33 33
34 #ifdef PRODUCT
35 #define print_method_handle(mh) {}
36 #else //PRODUCT
37 extern "C" void print_method_handle(oop mh);
38 #endif //PRODUCT
34 39
35 // ----------------------------------------------------------------------------- 40 // -----------------------------------------------------------------------------
36 // MethodHandleChain 41 // MethodHandleChain
37 42
38 void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { 43 void MethodHandleChain::set_method_handle(Handle mh, TRAPS) {
204 if (arg_state == NULL 209 if (arg_state == NULL
205 && conv_op > java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) { 210 && conv_op > java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) {
206 lose("bad argument index", CHECK_(empty)); 211 lose("bad argument index", CHECK_(empty));
207 } 212 }
208 213
214 bool retain_original_args = false; // used by fold/collect logic
215
209 // perform the adapter action 216 // perform the adapter action
210 switch (chain().adapter_conversion_op()) { 217 switch (conv_op) {
211 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY: 218 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
212 // No changes to arguments; pass the bits through. 219 // No changes to arguments; pass the bits through.
213 break; 220 break;
214 221
215 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW: { 222 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW: {
216 // To keep the verifier happy, emit bitwise ("raw") conversions as needed. 223 // To keep the verifier happy, emit bitwise ("raw") conversions as needed.
217 // See MethodHandles::same_basic_type_for_arguments for allowed conversions. 224 // See MethodHandles::same_basic_type_for_arguments for allowed conversions.
218 Handle incoming_mtype(THREAD, chain().method_type_oop()); 225 Handle incoming_mtype(THREAD, chain().method_type_oop());
219 oop outgoing_mh_oop = chain().vmtarget_oop(); 226 Handle outgoing_mtype;
220 if (!java_lang_invoke_MethodHandle::is_instance(outgoing_mh_oop)) 227 {
221 lose("outgoing target not a MethodHandle", CHECK_(empty)); 228 oop outgoing_mh_oop = chain().vmtarget_oop();
222 Handle outgoing_mtype(THREAD, java_lang_invoke_MethodHandle::type(outgoing_mh_oop)); 229 if (!java_lang_invoke_MethodHandle::is_instance(outgoing_mh_oop))
223 outgoing_mh_oop = NULL; // GC safety 230 lose("outgoing target not a MethodHandle", CHECK_(empty));
231 outgoing_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(outgoing_mh_oop));
232 }
224 233
225 int nptypes = java_lang_invoke_MethodType::ptype_count(outgoing_mtype()); 234 int nptypes = java_lang_invoke_MethodType::ptype_count(outgoing_mtype());
226 if (nptypes != java_lang_invoke_MethodType::ptype_count(incoming_mtype())) 235 if (nptypes != java_lang_invoke_MethodType::ptype_count(incoming_mtype()))
227 lose("incoming and outgoing parameter count do not agree", CHECK_(empty)); 236 lose("incoming and outgoing parameter count do not agree", CHECK_(empty));
228 237
238 // Argument types.
229 for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) { 239 for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) {
230 SlotState* arg_state = slot_state(slot); 240 SlotState* arg_state = slot_state(slot);
231 if (arg_state->_type == T_VOID) continue; 241 if (arg_state->_type == T_VOID) continue;
232 ArgToken arg = _outgoing.at(slot)._arg; 242
233 243 klassOop src_klass = NULL;
234 klassOop in_klass = NULL; 244 klassOop dst_klass = NULL;
235 klassOop out_klass = NULL; 245 BasicType src = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(incoming_mtype(), i), &src_klass);
236 BasicType inpbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(incoming_mtype(), i), &in_klass); 246 BasicType dst = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(outgoing_mtype(), i), &dst_klass);
237 BasicType outpbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(outgoing_mtype(), i), &out_klass); 247 retype_raw_argument_type(src, dst, slot, CHECK_(empty));
238 assert(inpbt == arg.basic_type(), "sanity");
239
240 if (inpbt != outpbt) {
241 vmIntrinsics::ID iid = vmIntrinsics::for_raw_conversion(inpbt, outpbt);
242 if (iid == vmIntrinsics::_none) {
243 lose("no raw conversion method", CHECK_(empty));
244 }
245 ArgToken arglist[2];
246 arglist[0] = arg; // outgoing 'this'
247 arglist[1] = ArgToken(); // sentinel
248 arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
249 change_argument(inpbt, slot, outpbt, arg);
250 }
251
252 i++; // We need to skip void slots at the top of the loop. 248 i++; // We need to skip void slots at the top of the loop.
253 } 249 }
254 250
255 BasicType inrbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(incoming_mtype())); 251 // Return type.
256 BasicType outrbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(outgoing_mtype())); 252 {
257 if (inrbt != outrbt) { 253 BasicType src = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(incoming_mtype()));
258 if (inrbt == T_INT && outrbt == T_VOID) { 254 BasicType dst = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(outgoing_mtype()));
259 // See comments in MethodHandles::same_basic_type_for_arguments. 255 retype_raw_return_type(src, dst, CHECK_(empty));
260 } else {
261 assert(false, "IMPLEMENT ME");
262 lose("no raw conversion method", CHECK_(empty));
263 }
264 } 256 }
265 break; 257 break;
266 } 258 }
267 259
268 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: { 260 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: {
271 BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass); 263 BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass);
272 assert(dest == T_OBJECT, ""); 264 assert(dest == T_OBJECT, "");
273 assert(dest == arg_state->_type, ""); 265 assert(dest == arg_state->_type, "");
274 ArgToken arg = arg_state->_arg; 266 ArgToken arg = arg_state->_arg;
275 ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty)); 267 ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty));
276 assert(arg.index() == new_arg.index(), "should be the same index"); 268 assert(arg.token_type() >= tt_symbolic || arg.index() == new_arg.index(), "should be the same index");
277 debug_only(dest_klass = (klassOop)badOop); 269 debug_only(dest_klass = (klassOop)badOop);
278 break; 270 break;
279 } 271 }
280 272
281 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: { 273 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: {
330 lose("no boxing method", CHECK_(empty)); 322 lose("no boxing method", CHECK_(empty));
331 } 323 }
332 ArgToken arglist[2]; 324 ArgToken arglist[2];
333 arglist[0] = arg; // outgoing value 325 arglist[0] = arg; // outgoing value
334 arglist[1] = ArgToken(); // sentinel 326 arglist[1] = ArgToken(); // sentinel
335 arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_(empty)); 327 arg = make_invoke(NULL, boxer, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
336 change_argument(src, arg_slot, T_OBJECT, arg); 328 change_argument(src, arg_slot, T_OBJECT, arg);
337 break; 329 break;
338 } 330 }
339 331
340 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: { 332 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: {
402 _outgoing.remove_at(arg_slot); 394 _outgoing.remove_at(arg_slot);
403 } 395 }
404 break; 396 break;
405 } 397 }
406 398
407 case java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC 399 case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS:
408 lose("unimplemented", CHECK_(empty)); 400 retain_original_args = true; // and fall through:
409 break; 401 case java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS: {
410 } 402 // call argument MH recursively
411 403 //{static int x; if (!x++) print_method_handle(chain().method_handle_oop()); --x;}
412 case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS: { //NYI, may GC 404 Handle recursive_mh(THREAD, chain().adapter_arg_oop());
413 lose("unimplemented", CHECK_(empty)); 405 if (!java_lang_invoke_MethodHandle::is_instance(recursive_mh())) {
406 lose("recursive target not a MethodHandle", CHECK_(empty));
407 }
408 Handle recursive_mtype(THREAD, java_lang_invoke_MethodHandle::type(recursive_mh()));
409 int argc = java_lang_invoke_MethodType::ptype_count(recursive_mtype());
410 int coll_slots = java_lang_invoke_MethodHandle::vmslots(recursive_mh());
411 BasicType rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(recursive_mtype()));
412 ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, 1 + argc + 1); // 1+: mh, +1: sentinel
413 arglist[0] = make_oop_constant(recursive_mh(), CHECK_(empty));
414 if (arg_slot < 0 || coll_slots < 0 || arg_slot + coll_slots > _outgoing.length()) {
415 lose("bad fold/collect arg slot", CHECK_(empty));
416 }
417 for (int i = 0, slot = arg_slot + coll_slots - 1; slot >= arg_slot; slot--) {
418 SlotState* arg_state = slot_state(slot);
419 BasicType arg_type = arg_state->_type;
420 if (arg_type == T_VOID) continue;
421 ArgToken arg = _outgoing.at(slot)._arg;
422 if (i >= argc) { lose("bad fold/collect arg", CHECK_(empty)); }
423 arglist[1+i] = arg;
424 if (!retain_original_args)
425 change_argument(arg_type, slot, T_VOID, ArgToken(tt_void));
426 }
427 arglist[1+argc] = ArgToken(); // sentinel
428 oop invoker = java_lang_invoke_MethodTypeForm::vmlayout(
429 java_lang_invoke_MethodType::form(recursive_mtype()) );
430 if (invoker == NULL || !invoker->is_method()) {
431 lose("bad vmlayout slot", CHECK_(empty));
432 }
433 // FIXME: consider inlining the invokee at the bytecode level
434 ArgToken ret = make_invoke(methodOop(invoker), vmIntrinsics::_none,
435 Bytecodes::_invokevirtual, false, 1+argc, &arglist[0], CHECK_(empty));
436 DEBUG_ONLY(invoker = NULL);
437 if (rtype == T_OBJECT) {
438 klassOop rklass = java_lang_Class::as_klassOop( java_lang_invoke_MethodType::rtype(recursive_mtype()) );
439 if (rklass != SystemDictionary::Object_klass() &&
440 !Klass::cast(rklass)->is_interface()) {
441 // preserve type safety
442 ret = make_conversion(T_OBJECT, rklass, Bytecodes::_checkcast, ret, CHECK_(empty));
443 }
444 }
445 int ret_slot = arg_slot + (retain_original_args ? coll_slots : 0);
446 change_argument(T_VOID, ret_slot, rtype, ret);
414 break; 447 break;
415 } 448 }
416 449
417 case java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS: { 450 case java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS: {
418 klassOop array_klass_oop = NULL; 451 klassOop array_klass_oop = NULL;
502 arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty)); 535 arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty));
503 } else { 536 } else {
504 lose("bad bound value", CHECK_(empty)); 537 lose("bad bound value", CHECK_(empty));
505 } 538 }
506 } 539 }
507 debug_only(arg_oop = badOop); 540 DEBUG_ONLY(arg_oop = badOop);
508 change_argument(T_VOID, arg_slot, arg_type, arg); 541 change_argument(T_VOID, arg_slot, arg_type, arg);
509 } 542 }
510 543
511 // this test must come after the body of the loop 544 // this test must come after the body of the loop
512 if (!chain().is_last()) { 545 if (!chain().is_last()) {
545 if (argp >= 0) { 578 if (argp >= 0) {
546 _outgoing.at_grow(argp, make_state(T_VOID, ArgToken(tt_void))); // presize 579 _outgoing.at_grow(argp, make_state(T_VOID, ArgToken(tt_void))); // presize
547 } 580 }
548 for (int i = 0; i < nptypes; i++) { 581 for (int i = 0; i < nptypes; i++) {
549 klassOop arg_type_klass = NULL; 582 klassOop arg_type_klass = NULL;
550 BasicType arg_type = java_lang_Class::as_BasicType( 583 BasicType arg_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(mtype(), i), &arg_type_klass);
551 java_lang_invoke_MethodType::ptype(mtype(), i), &arg_type_klass);
552 int index = new_local_index(arg_type); 584 int index = new_local_index(arg_type);
553 ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK); 585 ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK);
554 debug_only(arg_type_klass = (klassOop) NULL); 586 DEBUG_ONLY(arg_type_klass = (klassOop) NULL);
555 _outgoing.at_put(argp, make_state(arg_type, arg)); 587 _outgoing.at_put(argp, make_state(arg_type, arg));
556 if (type2size[arg_type] == 2) { 588 if (type2size[arg_type] == 2) {
557 // add the extra slot, so we can model the JVM stack 589 // add the extra slot, so we can model the JVM stack
558 _outgoing.insert_before(argp+1, make_state(T_VOID, ArgToken(tt_void))); 590 _outgoing.insert_before(argp+1, make_state(T_VOID, ArgToken(tt_void)));
559 } 591 }
560 --argp; 592 --argp;
561 } 593 }
562 // call make_parameter at the end of the list for the return type 594 // call make_parameter at the end of the list for the return type
563 klassOop ret_type_klass = NULL; 595 klassOop ret_type_klass = NULL;
564 BasicType ret_type = java_lang_Class::as_BasicType( 596 BasicType ret_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(mtype()), &ret_type_klass);
565 java_lang_invoke_MethodType::rtype(mtype()), &ret_type_klass);
566 ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK); 597 ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK);
567 // ignore ret; client can catch it if needed 598 // ignore ret; client can catch it if needed
568 } 599 }
569 600
570 601
609 } 640 }
610 } 641 }
611 return args_seen; 642 return args_seen;
612 } 643 }
613 #endif 644 #endif
645
646
647 // -----------------------------------------------------------------------------
648 // MethodHandleWalker::retype_raw_conversion
649 //
650 // Do the raw retype conversions for OP_RETYPE_RAW.
651 void MethodHandleWalker::retype_raw_conversion(BasicType src, BasicType dst, bool for_return, int slot, TRAPS) {
652 if (src != dst) {
653 if (MethodHandles::same_basic_type_for_returns(src, dst, /*raw*/ true)) {
654 if (MethodHandles::is_float_fixed_reinterpretation_cast(src, dst)) {
655 if (for_return) Untested("MHW return raw conversion"); // still untested
656 vmIntrinsics::ID iid = vmIntrinsics::for_raw_conversion(src, dst);
657 if (iid == vmIntrinsics::_none) {
658 lose("no raw conversion method", CHECK);
659 }
660 ArgToken arglist[2];
661 if (!for_return) {
662 // argument type conversion
663 ArgToken arg = _outgoing.at(slot)._arg;
664 assert(arg.token_type() >= tt_symbolic || src == arg.basic_type(), "sanity");
665 arglist[0] = arg; // outgoing 'this'
666 arglist[1] = ArgToken(); // sentinel
667 arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
668 change_argument(src, slot, dst, arg);
669 } else {
670 // return type conversion
671 klassOop arg_klass = NULL;
672 arglist[0] = make_parameter(src, arg_klass, -1, CHECK); // return value
673 arglist[1] = ArgToken(); // sentinel
674 (void) make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
675 }
676 } else {
677 // Nothing to do.
678 }
679 } else if (src == T_OBJECT && is_java_primitive(dst)) {
680 // ref-to-prim: discard ref, push zero
681 lose("requested ref-to-prim conversion not expected", CHECK);
682 } else {
683 lose("requested raw conversion not allowed", CHECK);
684 }
685 }
686 }
614 687
615 688
616 // ----------------------------------------------------------------------------- 689 // -----------------------------------------------------------------------------
617 // MethodHandleCompiler 690 // MethodHandleCompiler
618 691
717 case Bytecodes::_dstore_3: 790 case Bytecodes::_dstore_3:
718 case Bytecodes::_astore_0: 791 case Bytecodes::_astore_0:
719 case Bytecodes::_astore_1: 792 case Bytecodes::_astore_1:
720 case Bytecodes::_astore_2: 793 case Bytecodes::_astore_2:
721 case Bytecodes::_astore_3: 794 case Bytecodes::_astore_3:
795 case Bytecodes::_iand:
722 case Bytecodes::_i2l: 796 case Bytecodes::_i2l:
723 case Bytecodes::_i2f: 797 case Bytecodes::_i2f:
724 case Bytecodes::_i2d: 798 case Bytecodes::_i2d:
725 case Bytecodes::_i2b: 799 case Bytecodes::_i2b:
726 case Bytecodes::_i2c: 800 case Bytecodes::_i2c:
943 emit_bc(op, cpool_klass_put(tk)); 1017 emit_bc(op, cpool_klass_put(tk));
944 emit_store(srctype, index); 1018 emit_store(srctype, index);
945 break; 1019 break;
946 1020
947 default: 1021 default:
948 ShouldNotReachHere(); 1022 if (op == Bytecodes::_illegal)
1023 lose("no such primitive conversion", THREAD);
1024 else
1025 lose("bad primitive conversion op", THREAD);
1026 return make_prim_constant(type, &zero_jvalue, THREAD);
949 } 1027 }
950 1028
951 return make_parameter(type, tk, index, THREAD); 1029 return make_parameter(type, tk, index, THREAD);
952 } 1030 }
953 1031
954 1032
955 // ----------------------------------------------------------------------------- 1033 // -----------------------------------------------------------------------------
956 // MethodHandleCompiler 1034 // MethodHandleCompiler
957 // 1035 //
958 1036
959 static jvalue zero_jvalue; 1037 // Values used by the compiler.
1038 jvalue MethodHandleCompiler::zero_jvalue = { 0 };
1039 jvalue MethodHandleCompiler::one_jvalue = { 1 };
960 1040
961 // Emit bytecodes for the given invoke instruction. 1041 // Emit bytecodes for the given invoke instruction.
962 MethodHandleWalker::ArgToken 1042 MethodHandleWalker::ArgToken
963 MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid, 1043 MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
964 Bytecodes::Code op, bool tailcall, 1044 Bytecodes::Code op, bool tailcall,
965 int argc, MethodHandleWalker::ArgToken* argv, 1045 int argc, MethodHandleWalker::ArgToken* argv,
966 TRAPS) { 1046 TRAPS) {
1047 ArgToken zero;
967 if (m == NULL) { 1048 if (m == NULL) {
968 // Get the intrinsic methodOop. 1049 // Get the intrinsic methodOop.
969 m = vmIntrinsics::method_for(iid); 1050 m = vmIntrinsics::method_for(iid);
970 if (m == NULL) { 1051 if (m == NULL) {
971 ArgToken zero;
972 lose(vmIntrinsics::name_at(iid), CHECK_(zero)); 1052 lose(vmIntrinsics::name_at(iid), CHECK_(zero));
973 } 1053 }
974 } 1054 }
975 1055
976 klassOop klass = m->method_holder(); 1056 klassOop klass = m->method_holder();
977 Symbol* name = m->name(); 1057 Symbol* name = m->name();
978 Symbol* signature = m->signature(); 1058 Symbol* signature = m->signature();
979 1059
980 if (tailcall) { 1060 if (tailcall) {
981 // Actually, in order to make these methods more recognizable, 1061 // Actually, in order to make these methods more recognizable,
982 // let's put them in holder class MethodHandle. That way stack 1062 // let's put them in holder class MethodHandle. That way stack
983 // walkers and compiler heuristics can recognize them. 1063 // walkers and compiler heuristics can recognize them.
1039 ArgToken ret; 1119 ArgToken ret;
1040 if (tailcall) { 1120 if (tailcall) {
1041 if (rbt != _rtype) { 1121 if (rbt != _rtype) {
1042 if (rbt == T_VOID) { 1122 if (rbt == T_VOID) {
1043 // push a zero of the right sort 1123 // push a zero of the right sort
1044 ArgToken zero;
1045 if (_rtype == T_OBJECT) { 1124 if (_rtype == T_OBJECT) {
1046 zero = make_oop_constant(NULL, CHECK_(zero)); 1125 zero = make_oop_constant(NULL, CHECK_(zero));
1047 } else { 1126 } else {
1048 zero = make_prim_constant(_rtype, &zero_jvalue, CHECK_(zero)); 1127 zero = make_prim_constant(_rtype, &zero_jvalue, CHECK_(zero));
1049 } 1128 }
1050 emit_load_constant(zero); 1129 emit_load_constant(zero);
1051 } else if (_rtype == T_VOID) { 1130 } else if (_rtype == T_VOID) {
1052 // We'll emit a _return with something on the stack. 1131 // We'll emit a _return with something on the stack.
1053 // It's OK to ignore what's on the stack. 1132 // It's OK to ignore what's on the stack.
1133 } else if (rbt == T_INT && is_subword_type(_rtype)) {
1134 // Convert value to match return type.
1135 switch (_rtype) {
1136 case T_BOOLEAN: {
1137 // boolean is treated as a one-bit unsigned integer.
1138 // Cf. API documentation: java/lang/invoke/MethodHandles.html#explicitCastArguments
1139 ArgToken one = make_prim_constant(T_INT, &one_jvalue, CHECK_(zero));
1140 emit_load_constant(one);
1141 emit_bc(Bytecodes::_iand);
1142 break;
1143 }
1144 case T_BYTE: emit_bc(Bytecodes::_i2b); break;
1145 case T_CHAR: emit_bc(Bytecodes::_i2c); break;
1146 case T_SHORT: emit_bc(Bytecodes::_i2s); break;
1147 default: ShouldNotReachHere();
1148 }
1149 } else if (is_subword_type(rbt) && (is_subword_type(_rtype) || (_rtype == T_INT))) {
1150 // The subword type was returned as an int and will be passed
1151 // on as an int.
1054 } else { 1152 } else {
1055 tty->print_cr("*** rbt=%d != rtype=%d", rbt, _rtype); 1153 lose("unknown conversion", CHECK_(zero));
1056 assert(false, "IMPLEMENT ME");
1057 } 1154 }
1058 } 1155 }
1059 switch (_rtype) { 1156 switch (_rtype) {
1060 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: 1157 case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
1061 case T_INT: emit_bc(Bytecodes::_ireturn); break; 1158 case T_INT: emit_bc(Bytecodes::_ireturn); break;
1214 m->set_size_of_parameters(_num_params); 1311 m->set_size_of_parameters(_num_params);
1215 1312
1216 typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array()); 1313 typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
1217 m->set_exception_table(exception_handlers()); 1314 m->set_exception_table(exception_handlers());
1218 1315
1219 // Set the invocation counter's count to the invoke count of the
1220 // original call site.
1221 InvocationCounter* ic = m->invocation_counter();
1222 ic->set(InvocationCounter::wait_for_compile, _invoke_count);
1223
1224 // Rewrite the method and set up the constant pool cache. 1316 // Rewrite the method and set up the constant pool cache.
1225 objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(empty)); 1317 objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(empty));
1226 objArrayHandle methods(THREAD, m_array); 1318 objArrayHandle methods(THREAD, m_array);
1227 methods->obj_at_put(0, m()); 1319 methods->obj_at_put(0, m());
1228 Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(empty)); // Use fake class. 1320 Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(empty)); // Use fake class.
1229 1321
1322 // Set the invocation counter's count to the invoke count of the
1323 // original call site.
1324 InvocationCounter* ic = m->invocation_counter();
1325 ic->set(InvocationCounter::wait_for_compile, _invoke_count);
1326
1230 // Create a new MDO 1327 // Create a new MDO
1231 { 1328 {
1232 methodDataOop mdo = oopFactory::new_methodData(m, CHECK_(empty)); 1329 methodDataOop mdo = oopFactory::new_methodData(m, CHECK_(empty));
1233 assert(m->method_data() == NULL, "there should not be an MDO yet"); 1330 assert(m->method_data() == NULL, "there should not be an MDO yet");
1234 m->set_method_data(mdo); 1331 m->set_method_data(mdo);
1235 1332
1236 // Iterate over all profile data and set the count of the counter 1333 // Iterate over all profile data and set the count of the counter
1237 // data entries to the original call site counter. 1334 // data entries to the original call site counter.
1238 for (ProfileData* pd = mdo->first_data(); mdo->is_valid(pd); pd = mdo->next_data(pd)) { 1335 for (ProfileData* profile_data = mdo->first_data();
1239 if (pd->is_CounterData()) { 1336 mdo->is_valid(profile_data);
1240 CounterData* cd = pd->as_CounterData(); 1337 profile_data = mdo->next_data(profile_data)) {
1241 cd->set_count(_invoke_count); 1338 if (profile_data->is_CounterData()) {
1339 CounterData* counter_data = profile_data->as_CounterData();
1340 counter_data->set_count(_invoke_count);
1242 } 1341 }
1243 } 1342 }
1244 } 1343 }
1245 1344
1246 #ifndef PRODUCT 1345 #ifndef PRODUCT
1255 } 1354 }
1256 1355
1257 1356
1258 #ifndef PRODUCT 1357 #ifndef PRODUCT
1259 1358
1260 #if 0
1261 // MH printer for debugging. 1359 // MH printer for debugging.
1262 1360
1263 class MethodHandlePrinter : public MethodHandleWalker { 1361 class MethodHandlePrinter : public MethodHandleWalker {
1264 private: 1362 private:
1265 outputStream* _out; 1363 outputStream* _out;
1266 bool _verbose; 1364 bool _verbose;
1267 int _temp_num; 1365 int _temp_num;
1366 int _param_state;
1268 stringStream _strbuf; 1367 stringStream _strbuf;
1269 const char* strbuf() { 1368 const char* strbuf() {
1270 const char* s = _strbuf.as_string(); 1369 const char* s = _strbuf.as_string();
1271 _strbuf.reset(); 1370 _strbuf.reset();
1272 return s; 1371 return s;
1273 } 1372 }
1274 ArgToken token(const char* str) { 1373 ArgToken token(const char* str) {
1275 return (ArgToken) str; 1374 jvalue string_con;
1375 string_con.j = (intptr_t) str;
1376 return ArgToken(tt_symbolic, T_LONG, string_con);
1377 }
1378 const char* string(ArgToken token) {
1379 return (const char*) (intptr_t) token.get_jlong();
1276 } 1380 }
1277 void start_params() { 1381 void start_params() {
1382 _param_state <<= 1;
1278 _out->print("("); 1383 _out->print("(");
1279 } 1384 }
1280 void end_params() { 1385 void end_params() {
1281 if (_verbose) _out->print("\n"); 1386 if (_verbose) _out->print("\n");
1282 _out->print(") => {"); 1387 _out->print(") => {");
1388 _param_state >>= 1;
1283 } 1389 }
1284 void put_type_name(BasicType type, klassOop tk, outputStream* s) { 1390 void put_type_name(BasicType type, klassOop tk, outputStream* s) {
1285 const char* kname = NULL; 1391 const char* kname = NULL;
1286 if (tk != NULL) 1392 if (tk != NULL)
1287 kname = Klass::cast(tk)->external_name(); 1393 kname = Klass::cast(tk)->external_name();
1297 return token(temp); 1403 return token(temp);
1298 } 1404 }
1299 1405
1300 public: 1406 public:
1301 MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS) 1407 MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS)
1302 : MethodHandleWalker(root, THREAD), 1408 : MethodHandleWalker(root, false, THREAD),
1303 _out(out), 1409 _out(out),
1304 _verbose(verbose), 1410 _verbose(verbose),
1411 _param_state(0),
1305 _temp_num(0) 1412 _temp_num(0)
1306 { 1413 {
1307 start_params(); 1414 start_params();
1308 } 1415 }
1309 virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) { 1416 virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) {
1310 if (argnum < 0) { 1417 if (argnum < 0) {
1311 end_params(); 1418 end_params();
1312 return NULL; 1419 return token("return");
1313 } 1420 }
1314 if (argnum == 0) { 1421 if ((_param_state & 1) == 0) {
1422 _param_state |= 1;
1315 _out->print(_verbose ? "\n " : ""); 1423 _out->print(_verbose ? "\n " : "");
1316 } else { 1424 } else {
1317 _out->print(_verbose ? ",\n " : ", "); 1425 _out->print(_verbose ? ",\n " : ", ");
1318 } 1426 }
1319 if (argnum >= _temp_num) 1427 if (argnum >= _temp_num)
1339 } 1447 }
1340 virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) { 1448 virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) {
1341 java_lang_boxing_object::print(type, con, &_strbuf); 1449 java_lang_boxing_object::print(type, con, &_strbuf);
1342 return maybe_make_temp("constant", type, "k"); 1450 return maybe_make_temp("constant", type, "k");
1343 } 1451 }
1344 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, ArgToken src, TRAPS) { 1452 void print_bytecode_name(Bytecodes::Code op) {
1345 _strbuf.print("%s(%s", Bytecodes::name(op), (const char*)src); 1453 if (Bytecodes::is_defined(op))
1454 _strbuf.print("%s", Bytecodes::name(op));
1455 else
1456 _strbuf.print("bytecode_%d", (int) op);
1457 }
1458 virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS) {
1459 print_bytecode_name(op);
1460 _strbuf.print("(%s", string(src));
1346 if (tk != NULL) { 1461 if (tk != NULL) {
1347 _strbuf.print(", "); 1462 _strbuf.print(", ");
1348 put_type_name(type, tk, &_strbuf); 1463 put_type_name(type, tk, &_strbuf);
1349 } 1464 }
1350 _strbuf.print(")"); 1465 _strbuf.print(")");
1351 return maybe_make_temp("convert", type, "v"); 1466 return maybe_make_temp("convert", type, "v");
1352 } 1467 }
1353 virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, ArgToken base, ArgToken offset, TRAPS) { 1468 virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS) {
1354 _strbuf.print("%s(%s, %s", Bytecodes::name(op), (const char*)base, (const char*)offset); 1469 _strbuf.print("%s(%s, %s", Bytecodes::name(op), string(base), string(offset));
1355 if (tk != NULL) { 1470 if (tk != NULL) {
1356 _strbuf.print(", "); 1471 _strbuf.print(", ");
1357 put_type_name(type, tk, &_strbuf); 1472 put_type_name(type, tk, &_strbuf);
1358 } 1473 }
1359 _strbuf.print(")"); 1474 _strbuf.print(")");
1360 return maybe_make_temp("fetch", type, "x"); 1475 return maybe_make_temp("fetch", type, "x");
1361 } 1476 }
1362 virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, 1477 virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid,
1363 Bytecodes::Code op, bool tailcall, 1478 Bytecodes::Code op, bool tailcall,
1364 int argc, ArgToken* argv, TRAPS) { 1479 int argc, ArgToken* argv, TRAPS) {
1365 Symbol* name, sig; 1480 Symbol* name;
1481 Symbol* sig;
1366 if (m != NULL) { 1482 if (m != NULL) {
1367 name = m->name(); 1483 name = m->name();
1368 sig = m->signature(); 1484 sig = m->signature();
1369 } else { 1485 } else {
1370 name = vmSymbols::symbol_at(vmIntrinsics::name_for(iid)); 1486 name = vmSymbols::symbol_at(vmIntrinsics::name_for(iid));
1371 sig = vmSymbols::symbol_at(vmIntrinsics::signature_for(iid)); 1487 sig = vmSymbols::symbol_at(vmIntrinsics::signature_for(iid));
1372 } 1488 }
1373 _strbuf.print("%s %s%s(", Bytecodes::name(op), name->as_C_string(), sig->as_C_string()); 1489 _strbuf.print("%s %s%s(", Bytecodes::name(op), name->as_C_string(), sig->as_C_string());
1374 for (int i = 0; i < argc; i++) { 1490 for (int i = 0; i < argc; i++) {
1375 _strbuf.print("%s%s", (i > 0 ? ", " : ""), (const char*)argv[i]); 1491 _strbuf.print("%s%s", (i > 0 ? ", " : ""), string(argv[i]));
1376 } 1492 }
1377 _strbuf.print(")"); 1493 _strbuf.print(")");
1378 if (!tailcall) { 1494 if (!tailcall) {
1379 BasicType rt = char2type(sig->byte_at(sig->utf8_length()-1)); 1495 BasicType rt = char2type(sig->byte_at(sig->utf8_length()-1));
1380 if (rt == T_ILLEGAL) rt = T_OBJECT; // ';' at the end of '(...)L...;' 1496 if (rt == T_ILLEGAL) rt = T_OBJECT; // ';' at the end of '(...)L...;'
1408 if (!HAS_PENDING_EXCEPTION) 1524 if (!HAS_PENDING_EXCEPTION)
1409 printer.walk(THREAD); 1525 printer.walk(THREAD);
1410 if (HAS_PENDING_EXCEPTION) { 1526 if (HAS_PENDING_EXCEPTION) {
1411 oop ex = PENDING_EXCEPTION; 1527 oop ex = PENDING_EXCEPTION;
1412 CLEAR_PENDING_EXCEPTION; 1528 CLEAR_PENDING_EXCEPTION;
1413 out->print("\n*** "); 1529 out->print(" *** ");
1414 if (ex != Universe::virtual_machine_error_instance()) 1530 if (printer.lose_message() != NULL) out->print("%s ", printer.lose_message());
1415 ex->print_on(out); 1531 out->print("}");
1416 else
1417 out->print("lose: %s", printer.lose_message());
1418 out->print("\n}\n");
1419 } 1532 }
1420 out->print("\n"); 1533 out->print("\n");
1421 } 1534 }
1422 }; 1535 };
1423 #endif // 0
1424 1536
1425 extern "C" 1537 extern "C"
1426 void print_method_handle(oop mh) { 1538 void print_method_handle(oop mh) {
1427 if (!mh->is_oop()) { 1539 if (!mh->is_oop()) {
1428 tty->print_cr("*** not a method handle: "INTPTR_FORMAT, (intptr_t)mh); 1540 tty->print_cr("*** not a method handle: "PTR_FORMAT, (intptr_t)mh);
1429 } else if (java_lang_invoke_MethodHandle::is_instance(mh)) { 1541 } else if (java_lang_invoke_MethodHandle::is_instance(mh)) {
1430 //MethodHandlePrinter::print(mh); 1542 MethodHandlePrinter::print(mh);
1431 } else { 1543 } else {
1432 tty->print("*** not a method handle: "); 1544 tty->print("*** not a method handle: ");
1433 mh->print(); 1545 mh->print();
1434 } 1546 }
1435 } 1547 }