Mercurial > hg > truffle
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. |