comparison src/cpu/sparc/vm/methodHandles_sparc.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 b856cd7f4e60
children d810e9a3fc33
comparison
equal deleted inserted replaced
2087:352765ed11a1 2088:8d0b933dda2d
393 //------------------------------------------------------------------------------ 393 //------------------------------------------------------------------------------
394 // MethodHandles::generate_method_handle_stub 394 // MethodHandles::generate_method_handle_stub
395 // 395 //
396 // Generate an "entry" field for a method handle. 396 // Generate an "entry" field for a method handle.
397 // This determines how the method handle will respond to calls. 397 // This determines how the method handle will respond to calls.
398 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { 398 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
399 // Here is the register state during an interpreted call, 399 // Here is the register state during an interpreted call,
400 // as set up by generate_method_handle_interpreter_entry(): 400 // as set up by generate_method_handle_interpreter_entry():
401 // - G5: garbage temp (was MethodHandle.invoke methodOop, unused) 401 // - G5: garbage temp (was MethodHandle.invoke methodOop, unused)
402 // - G3: receiver method handle 402 // - G3: receiver method handle
403 // - O5_savedSP: sender SP (must preserve) 403 // - O5_savedSP: sender SP (must preserve)
404 404
405 Register O0_argslot = O0; 405 const Register O0_argslot = O0;
406 Register O1_scratch = O1; 406 const Register O1_scratch = O1;
407 Register O2_scratch = O2; 407 const Register O2_scratch = O2;
408 Register O3_scratch = O3; 408 const Register O3_scratch = O3;
409 Register G5_index = G5; 409 const Register G5_index = G5;
410
411 // Argument registers for _raise_exception.
412 const Register O0_code = O0;
413 const Register O1_actual = O1;
414 const Register O2_required = O2;
410 415
411 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); 416 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
412 417
413 // Some handy addresses: 418 // Some handy addresses:
414 Address G5_method_fie( G5_method, in_bytes(methodOopDesc::from_interpreted_offset())); 419 Address G5_method_fie( G5_method, in_bytes(methodOopDesc::from_interpreted_offset()));
437 442
438 switch ((int) ek) { 443 switch ((int) ek) {
439 case _raise_exception: 444 case _raise_exception:
440 { 445 {
441 // Not a real MH entry, but rather shared code for raising an 446 // Not a real MH entry, but rather shared code for raising an
442 // exception. Extra local arguments are passed in scratch 447 // exception. Since we use a C2I adapter to set up the
443 // registers, as required type in O3, failing object (or NULL) 448 // interpreter state, arguments are expected in compiler
444 // in O2, failing bytecode type in O1. 449 // argument registers.
450 methodHandle mh(raise_exception_method());
451 address c2i_entry = methodOopDesc::make_adapters(mh, CATCH);
445 452
446 __ mov(O5_savedSP, SP); // Cut the stack back to where the caller started. 453 __ mov(O5_savedSP, SP); // Cut the stack back to where the caller started.
447 454
448 // Push arguments as if coming from the interpreter. 455 Label L_no_method;
449 Register O0_scratch = O0_argslot;
450 int stackElementSize = Interpreter::stackElementSize;
451
452 // Make space on the stack for the arguments and set Gargs
453 // correctly.
454 __ sub(SP, 4*stackElementSize, SP); // Keep stack aligned.
455 __ add(SP, (frame::varargs_offset)*wordSize - 1*Interpreter::stackElementSize + STACK_BIAS + BytesPerWord, Gargs);
456
457 // void raiseException(int code, Object actual, Object required)
458 __ st( O1_scratch, Address(Gargs, 2*stackElementSize)); // code
459 __ st_ptr(O2_scratch, Address(Gargs, 1*stackElementSize)); // actual
460 __ st_ptr(O3_scratch, Address(Gargs, 0*stackElementSize)); // required
461
462 Label no_method;
463 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method 456 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
464 __ set(AddressLiteral((address) &_raise_exception_method), G5_method); 457 __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
465 __ ld_ptr(Address(G5_method, 0), G5_method); 458 __ ld_ptr(Address(G5_method, 0), G5_method);
466 __ tst(G5_method); 459 __ tst(G5_method);
467 __ brx(Assembler::zero, false, Assembler::pn, no_method); 460 __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
468 __ delayed()->nop(); 461 __ delayed()->nop();
469 462
470 int jobject_oop_offset = 0; 463 const int jobject_oop_offset = 0;
471 __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method); 464 __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
472 __ tst(G5_method); 465 __ tst(G5_method);
473 __ brx(Assembler::zero, false, Assembler::pn, no_method); 466 __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
474 __ delayed()->nop(); 467 __ delayed()->nop();
475 468
476 __ verify_oop(G5_method); 469 __ verify_oop(G5_method);
477 __ jump_indirect_to(G5_method_fie, O1_scratch); 470 __ jump_to(AddressLiteral(c2i_entry), O3_scratch);
478 __ delayed()->nop(); 471 __ delayed()->nop();
479 472
480 // If we get here, the Java runtime did not do its job of creating the exception. 473 // If we get here, the Java runtime did not do its job of creating the exception.
481 // Do something that is at least causes a valid throw from the interpreter. 474 // Do something that is at least causes a valid throw from the interpreter.
482 __ bind(no_method); 475 __ bind(L_no_method);
483 __ unimplemented("_raise_exception no method"); 476 __ unimplemented("call throw_WrongMethodType_entry");
484 } 477 }
485 break; 478 break;
486 479
487 case _invokestatic_mh: 480 case _invokestatic_mh:
488 case _invokespecial_mh: 481 case _invokespecial_mh:
568 561
569 __ bind(no_such_interface); 562 __ bind(no_such_interface);
570 // Throw an exception. 563 // Throw an exception.
571 // For historical reasons, it will be IncompatibleClassChangeError. 564 // For historical reasons, it will be IncompatibleClassChangeError.
572 __ unimplemented("not tested yet"); 565 __ unimplemented("not tested yet");
573 __ ld_ptr(Address(O1_intf, java_mirror_offset), O3_scratch); // required interface 566 __ ld_ptr(Address(O1_intf, java_mirror_offset), O2_required); // required interface
574 __ mov(O0_klass, O2_scratch); // bad receiver 567 __ mov( O0_klass, O1_actual); // bad receiver
575 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot); 568 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
576 __ delayed()->mov(Bytecodes::_invokeinterface, O1_scratch); // who is complaining? 569 __ delayed()->mov(Bytecodes::_invokeinterface, O0_code); // who is complaining?
577 } 570 }
578 break; 571 break;
579 572
580 case _bound_ref_mh: 573 case _bound_ref_mh:
581 case _bound_int_mh: 574 case _bound_int_mh:
661 // - O1_scratch : argument klass to test 654 // - O1_scratch : argument klass to test
662 // - G3_method_handle: adapter method handle 655 // - G3_method_handle: adapter method handle
663 __ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done); 656 __ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done);
664 657
665 // If we get here, the type check failed! 658 // If we get here, the type check failed!
666 __ ldsw(G3_amh_vmargslot, O0_argslot); // reload argslot field 659 __ load_heap_oop(G3_amh_argument, O2_required); // required class
667 __ load_heap_oop(G3_amh_argument, O3_scratch); // required class 660 __ ld_ptr( vmarg, O1_actual); // bad object
668 __ ld_ptr(vmarg, O2_scratch); // bad object 661 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
669 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot); 662 __ delayed()->mov(Bytecodes::_checkcast, O0_code); // who is complaining?
670 __ delayed()->mov(Bytecodes::_checkcast, O1_scratch); // who is complaining?
671 663
672 __ bind(done); 664 __ bind(done);
673 // Get the new MH: 665 // Get the new MH:
674 __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); 666 __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
675 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 667 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);