comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 2088:8d0b933dda2d

7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot Reviewed-by: kvn, jrose
author twisti
date Wed, 22 Dec 2010 02:02:53 -0800
parents f95d63e2154a
children d810e9a3fc33
comparison
equal deleted inserted replaced
2087:352765ed11a1 2088:8d0b933dda2d
383 //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG! 383 //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
384 ); 384 );
385 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. 385 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
386 } 386 }
387 387
388 //------------------------------------------------------------------------------
389 // MethodHandles::generate_method_handle_stub
390 //
388 // Generate an "entry" field for a method handle. 391 // Generate an "entry" field for a method handle.
389 // This determines how the method handle will respond to calls. 392 // This determines how the method handle will respond to calls.
390 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { 393 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
391 // Here is the register state during an interpreted call, 394 // Here is the register state during an interpreted call,
392 // as set up by generate_method_handle_interpreter_entry(): 395 // as set up by generate_method_handle_interpreter_entry():
393 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused) 396 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
394 // - rcx: receiver method handle 397 // - rcx: receiver method handle
395 // - rax: method handle type (only used by the check_mtype entry point) 398 // - rax: method handle type (only used by the check_mtype entry point)
396 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) 399 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
397 // - rdx: garbage temp, can blow away 400 // - rdx: garbage temp, can blow away
398 401
399 Register rcx_recv = rcx; 402 const Register rcx_recv = rcx;
400 Register rax_argslot = rax; 403 const Register rax_argslot = rax;
401 Register rbx_temp = rbx; 404 const Register rbx_temp = rbx;
402 Register rdx_temp = rdx; 405 const Register rdx_temp = rdx;
403 406
404 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls) 407 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
405 // and gen_c2i_adapter (from compiled calls): 408 // and gen_c2i_adapter (from compiled calls):
406 Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi); 409 const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
410
411 // Argument registers for _raise_exception.
412 // 32-bit: Pass first two oop/int args in registers ECX and EDX.
413 const Register rarg0_code = LP64_ONLY(j_rarg0) NOT_LP64(rcx);
414 const Register rarg1_actual = LP64_ONLY(j_rarg1) NOT_LP64(rdx);
415 const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
416 assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
407 417
408 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); 418 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
409 419
410 // some handy addresses 420 // some handy addresses
411 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() ); 421 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() );
435 BLOCK_COMMENT(entry_name(ek)); 445 BLOCK_COMMENT(entry_name(ek));
436 446
437 switch ((int) ek) { 447 switch ((int) ek) {
438 case _raise_exception: 448 case _raise_exception:
439 { 449 {
440 // Not a real MH entry, but rather shared code for raising an exception. 450 // Not a real MH entry, but rather shared code for raising an
441 // Extra local arguments are pushed on stack, as required type at TOS+8, 451 // exception. Since we use a C2I adapter to set up the
442 // failing object (or NULL) at TOS+4, failing bytecode type at TOS. 452 // interpreter state, arguments are expected in compiler
443 // Beyond those local arguments are the PC, of course. 453 // argument registers.
444 Register rdx_code = rdx_temp; 454 methodHandle mh(raise_exception_method());
445 Register rcx_fail = rcx_recv; 455 address c2i_entry = methodOopDesc::make_adapters(mh, CHECK);
446 Register rax_want = rax_argslot; 456
447 Register rdi_pc = rdi; 457 const Register rdi_pc = rax;
448 __ pop(rdx_code); // TOS+0 458 __ pop(rdi_pc); // caller PC
449 __ pop(rcx_fail); // TOS+4 459 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started
450 __ pop(rax_want); // TOS+8
451 __ pop(rdi_pc); // caller PC
452
453 __ mov(rsp, rsi); // cut the stack back to where the caller started
454
455 // Repush the arguments as if coming from the interpreter.
456 __ push(rdx_code);
457 __ push(rcx_fail);
458 __ push(rax_want);
459 460
460 Register rbx_method = rbx_temp; 461 Register rbx_method = rbx_temp;
461 Label no_method; 462 Label L_no_method;
462 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method 463 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
463 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); 464 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
464 __ testptr(rbx_method, rbx_method); 465 __ testptr(rbx_method, rbx_method);
465 __ jccb(Assembler::zero, no_method); 466 __ jccb(Assembler::zero, L_no_method);
466 int jobject_oop_offset = 0; 467
468 const int jobject_oop_offset = 0;
467 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject 469 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject
468 __ testptr(rbx_method, rbx_method); 470 __ testptr(rbx_method, rbx_method);
469 __ jccb(Assembler::zero, no_method); 471 __ jccb(Assembler::zero, L_no_method);
470 __ verify_oop(rbx_method); 472 __ verify_oop(rbx_method);
471 __ push(rdi_pc); // and restore caller PC 473
472 __ jmp(rbx_method_fie); 474 // 32-bit: push remaining arguments as if coming from the compiler.
475 NOT_LP64(__ push(rarg2_required));
476
477 __ push(rdi_pc); // restore caller PC
478 __ jump(ExternalAddress(c2i_entry)); // do C2I transition
473 479
474 // If we get here, the Java runtime did not do its job of creating the exception. 480 // If we get here, the Java runtime did not do its job of creating the exception.
475 // Do something that is at least causes a valid throw from the interpreter. 481 // Do something that is at least causes a valid throw from the interpreter.
476 __ bind(no_method); 482 __ bind(L_no_method);
477 __ pop(rax_want); 483 __ push(rarg2_required);
478 __ pop(rcx_fail); 484 __ push(rarg1_actual);
479 __ push(rax_want);
480 __ push(rcx_fail);
481 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 485 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
482 } 486 }
483 break; 487 break;
484 488
485 case _invokestatic_mh: 489 case _invokestatic_mh:
570 __ hlt(); 574 __ hlt();
571 575
572 __ bind(no_such_interface); 576 __ bind(no_such_interface);
573 // Throw an exception. 577 // Throw an exception.
574 // For historical reasons, it will be IncompatibleClassChangeError. 578 // For historical reasons, it will be IncompatibleClassChangeError.
575 __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface 579 __ mov(rbx_temp, rcx_recv); // rarg2_required might be RCX
576 __ push(rcx_recv); // bad receiver 580 assert_different_registers(rarg2_required, rbx_temp);
577 __ push((int)Bytecodes::_invokeinterface); // who is complaining? 581 __ movptr(rarg2_required, Address(rdx_intf, java_mirror_offset)); // required interface
582 __ mov( rarg1_actual, rbx_temp); // bad receiver
583 __ movl( rarg0_code, (int) Bytecodes::_invokeinterface); // who is complaining?
578 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 584 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
579 } 585 }
580 break; 586 break;
581 587
582 case _bound_ref_mh: 588 case _bound_ref_mh:
667 // Call the wrong_method_type stub, passing the failing argument type in rax. 673 // Call the wrong_method_type stub, passing the failing argument type in rax.
668 Register rax_mtype = rax_argslot; 674 Register rax_mtype = rax_argslot;
669 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field 675 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field
670 __ movptr(rdx_temp, vmarg); 676 __ movptr(rdx_temp, vmarg);
671 677
672 __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class 678 assert_different_registers(rarg2_required, rdx_temp);
673 __ push(rbx_klass); 679 __ load_heap_oop(rarg2_required, rcx_amh_argument); // required class
674 __ push(rdx_temp); // bad object 680 __ mov( rarg1_actual, rdx_temp); // bad object
675 __ push((int)Bytecodes::_checkcast); // who is complaining? 681 __ movl( rarg0_code, (int) Bytecodes::_checkcast); // who is complaining?
676 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 682 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
677 683
678 __ bind(done); 684 __ bind(done);
679 // get the new MH: 685 // get the new MH:
680 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 686 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
1187 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 1193 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
1188 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1194 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1189 1195
1190 __ bind(bad_array_klass); 1196 __ bind(bad_array_klass);
1191 UNPUSH_RSI_RDI; 1197 UNPUSH_RSI_RDI;
1192 __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type 1198 assert(!vmarg.uses(rarg2_required), "must be different registers");
1193 __ pushptr(vmarg); // bad array 1199 __ movptr(rarg2_required, Address(rdx_array_klass, java_mirror_offset)); // required type
1194 __ push((int)Bytecodes::_aaload); // who is complaining? 1200 __ movptr(rarg1_actual, vmarg); // bad array
1201 __ movl( rarg0_code, (int) Bytecodes::_aaload); // who is complaining?
1195 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 1202 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
1196 1203
1197 __ bind(bad_array_length); 1204 __ bind(bad_array_length);
1198 UNPUSH_RSI_RDI; 1205 UNPUSH_RSI_RDI;
1199 __ push(rcx_recv); // AMH requiring a certain length 1206 assert(!vmarg.uses(rarg2_required), "must be different registers");
1200 __ pushptr(vmarg); // bad array 1207 __ mov (rarg2_required, rcx_recv); // AMH requiring a certain length
1201 __ push((int)Bytecodes::_arraylength); // who is complaining? 1208 __ movptr(rarg1_actual, vmarg); // bad array
1209 __ movl( rarg0_code, (int) Bytecodes::_arraylength); // who is complaining?
1202 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 1210 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
1203 1211
1204 #undef UNPUSH_RSI_RDI 1212 #undef UNPUSH_RSI_RDI
1205 } 1213 }
1206 break; 1214 break;