comparison src/share/vm/prims/methodHandleWalk.cpp @ 3757:f8c9417e3571

7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters Reviewed-by: twisti, kvn, jrose
author never
date Tue, 14 Jun 2011 14:41:33 -0700
parents cba7b5c2d53f
children cfcf2ba8f3eb
comparison
equal deleted inserted replaced
3755:5cf771a79037 3757:f8c9417e3571
234 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY: 234 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
235 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW: 235 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW:
236 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: 236 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
237 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: 237 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
238 case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM: 238 case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM:
239 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF:
240 break; 239 break;
240
241 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: {
242 tty->print(" src_type = %s", type2name(chain.adapter_conversion_src_type()));
243 break;
244 }
241 245
242 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: 246 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS:
243 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: { 247 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
244 int dest_arg_slot = chain.adapter_conversion_vminfo(); 248 int dest_arg_slot = chain.adapter_conversion_vminfo();
245 tty->print(" dest_arg_slot %d type %s", dest_arg_slot, type2name(chain.adapter_conversion_src_type())); 249 tty->print(" dest_arg_slot %d type %s", dest_arg_slot, type2name(chain.adapter_conversion_src_type()));
501 change_argument(a1.basic_type(), arg_slot, a2); 505 change_argument(a1.basic_type(), arg_slot, a2);
502 break; 506 break;
503 } 507 }
504 508
505 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: { 509 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
506 int dest_arg_slot = chain().adapter_conversion_vminfo(); 510 int limit_raw = chain().adapter_conversion_vminfo();
507 if (!has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) { 511 bool rot_down = (arg_slot < limit_raw);
512 int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
513 int limit_slot = limit_raw - limit_bias;
514 if ((uint)limit_slot > (uint)_outgoing.length()) {
508 lose("bad rotate index", CHECK_(empty)); 515 lose("bad rotate index", CHECK_(empty));
509 } 516 }
510 // Rotate the source argument (plus following N slots) into the 517 // Rotate the source argument (plus following N slots) into the
511 // position occupied by the dest argument (plus following N slots). 518 // position occupied by the dest argument (plus following N slots).
512 int rotate_count = type2size[chain().adapter_conversion_src_type()]; 519 int rotate_count = type2size[chain().adapter_conversion_src_type()];
513 // (no other rotate counts are currently supported) 520 // (no other rotate counts are currently supported)
514 if (arg_slot < dest_arg_slot) { 521 if (rot_down) {
515 for (int i = 0; i < rotate_count; i++) { 522 for (int i = 0; i < rotate_count; i++) {
516 ArgToken temp = _outgoing.at(arg_slot); 523 ArgToken temp = _outgoing.at(arg_slot);
517 _outgoing.remove_at(arg_slot); 524 _outgoing.remove_at(arg_slot);
518 _outgoing.insert_before(dest_arg_slot + rotate_count - 1, temp); 525 _outgoing.insert_before(limit_slot - 1, temp);
519 } 526 }
520 } else { // arg_slot > dest_arg_slot 527 } else { // arg_slot > limit_slot => rotate_up
521 for (int i = 0; i < rotate_count; i++) { 528 for (int i = 0; i < rotate_count; i++) {
522 ArgToken temp = _outgoing.at(arg_slot + rotate_count - 1); 529 ArgToken temp = _outgoing.at(arg_slot + rotate_count - 1);
523 _outgoing.remove_at(arg_slot + rotate_count - 1); 530 _outgoing.remove_at(arg_slot + rotate_count - 1);
524 _outgoing.insert_before(dest_arg_slot, temp); 531 _outgoing.insert_before(limit_slot, temp);
525 } 532 }
526 } 533 }
527 assert(_outgoing_argc == argument_count_slow(), "empty slots under control"); 534 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
528 break; 535 break;
529 } 536 }
1414 case T_LONG: emit_bc(Bytecodes::_lreturn); break; 1421 case T_LONG: emit_bc(Bytecodes::_lreturn); break;
1415 case T_FLOAT: emit_bc(Bytecodes::_freturn); break; 1422 case T_FLOAT: emit_bc(Bytecodes::_freturn); break;
1416 case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break; 1423 case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break;
1417 case T_VOID: emit_bc(Bytecodes::_return); break; 1424 case T_VOID: emit_bc(Bytecodes::_return); break;
1418 case T_OBJECT: 1425 case T_OBJECT:
1419 if (_rklass.not_null() && _rklass() != SystemDictionary::Object_klass()) 1426 if (_rklass.not_null() && _rklass() != SystemDictionary::Object_klass() && !Klass::cast(_rklass())->is_interface()) {
1420 emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass())); 1427 emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass()));
1428 }
1421 emit_bc(Bytecodes::_areturn); 1429 emit_bc(Bytecodes::_areturn);
1422 break; 1430 break;
1423 default: ShouldNotReachHere(); 1431 default: ShouldNotReachHere();
1424 } 1432 }
1425 ret = ArgToken(); // Dummy return value. 1433 ret = ArgToken(); // Dummy return value.