Mercurial > hg > truffle
comparison src/cpu/x86/vm/sharedRuntime_x86_64.cpp @ 6266:1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author | twisti |
---|---|
date | Tue, 24 Jul 2012 10:51:00 -0700 |
parents | 031df0387c09 |
children | 957c266d8bc5 da91efe96a93 |
comparison
equal
deleted
inserted
replaced
6241:aba91a731143 | 6266:1d7922586cf6 |
---|---|
588 // Schedule the branch target address early. | 588 // Schedule the branch target address early. |
589 __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); | 589 __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); |
590 __ jmp(rcx); | 590 __ jmp(rcx); |
591 } | 591 } |
592 | 592 |
593 static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg, | |
594 address code_start, address code_end, | |
595 Label& L_ok) { | |
596 Label L_fail; | |
597 __ lea(temp_reg, ExternalAddress(code_start)); | |
598 __ cmpptr(pc_reg, temp_reg); | |
599 __ jcc(Assembler::belowEqual, L_fail); | |
600 __ lea(temp_reg, ExternalAddress(code_end)); | |
601 __ cmpptr(pc_reg, temp_reg); | |
602 __ jcc(Assembler::below, L_ok); | |
603 __ bind(L_fail); | |
604 } | |
605 | |
593 static void gen_i2c_adapter(MacroAssembler *masm, | 606 static void gen_i2c_adapter(MacroAssembler *masm, |
594 int total_args_passed, | 607 int total_args_passed, |
595 int comp_args_on_stack, | 608 int comp_args_on_stack, |
596 const BasicType *sig_bt, | 609 const BasicType *sig_bt, |
597 const VMRegPair *regs) { | 610 const VMRegPair *regs) { |
603 // we must align the stack to 16 bytes on an i2c entry else we | 616 // we must align the stack to 16 bytes on an i2c entry else we |
604 // lose alignment we expect in all compiled code and register | 617 // lose alignment we expect in all compiled code and register |
605 // save code can segv when fxsave instructions find improperly | 618 // save code can segv when fxsave instructions find improperly |
606 // aligned stack pointer. | 619 // aligned stack pointer. |
607 | 620 |
621 // Adapters can be frameless because they do not require the caller | |
622 // to perform additional cleanup work, such as correcting the stack pointer. | |
623 // An i2c adapter is frameless because the *caller* frame, which is interpreted, | |
624 // routinely repairs its own stack pointer (from interpreter_frame_last_sp), | |
625 // even if a callee has modified the stack pointer. | |
626 // A c2i adapter is frameless because the *callee* frame, which is interpreted, | |
627 // routinely repairs its caller's stack pointer (from sender_sp, which is set | |
628 // up via the senderSP register). | |
629 // In other words, if *either* the caller or callee is interpreted, we can | |
630 // get the stack pointer repaired after a call. | |
631 // This is why c2i and i2c adapters cannot be indefinitely composed. | |
632 // In particular, if a c2i adapter were to somehow call an i2c adapter, | |
633 // both caller and callee would be compiled methods, and neither would | |
634 // clean up the stack pointer changes performed by the two adapters. | |
635 // If this happens, control eventually transfers back to the compiled | |
636 // caller, but with an uncorrected stack, causing delayed havoc. | |
637 | |
608 // Pick up the return address | 638 // Pick up the return address |
609 __ movptr(rax, Address(rsp, 0)); | 639 __ movptr(rax, Address(rsp, 0)); |
640 | |
641 if (VerifyAdapterCalls && | |
642 (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) { | |
643 // So, let's test for cascading c2i/i2c adapters right now. | |
644 // assert(Interpreter::contains($return_addr) || | |
645 // StubRoutines::contains($return_addr), | |
646 // "i2c adapter must return to an interpreter frame"); | |
647 __ block_comment("verify_i2c { "); | |
648 Label L_ok; | |
649 if (Interpreter::code() != NULL) | |
650 range_check(masm, rax, r11, | |
651 Interpreter::code()->code_start(), Interpreter::code()->code_end(), | |
652 L_ok); | |
653 if (StubRoutines::code1() != NULL) | |
654 range_check(masm, rax, r11, | |
655 StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(), | |
656 L_ok); | |
657 if (StubRoutines::code2() != NULL) | |
658 range_check(masm, rax, r11, | |
659 StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(), | |
660 L_ok); | |
661 const char* msg = "i2c adapter must return to an interpreter frame"; | |
662 __ block_comment(msg); | |
663 __ stop(msg); | |
664 __ bind(L_ok); | |
665 __ block_comment("} verify_i2ce "); | |
666 } | |
610 | 667 |
611 // Must preserve original SP for loading incoming arguments because | 668 // Must preserve original SP for loading incoming arguments because |
612 // we need to align the outgoing SP for compiled code. | 669 // we need to align the outgoing SP for compiled code. |
613 __ movptr(r11, rsp); | 670 __ movptr(r11, rsp); |
614 | 671 |
1364 move32_64(masm, tmp, length_arg); | 1421 move32_64(masm, tmp, length_arg); |
1365 __ bind(done); | 1422 __ bind(done); |
1366 } | 1423 } |
1367 | 1424 |
1368 | 1425 |
1426 // Different signatures may require very different orders for the move | |
1427 // to avoid clobbering other arguments. There's no simple way to | |
1428 // order them safely. Compute a safe order for issuing stores and | |
1429 // break any cycles in those stores. This code is fairly general but | |
1430 // it's not necessary on the other platforms so we keep it in the | |
1431 // platform dependent code instead of moving it into a shared file. | |
1432 // (See bugs 7013347 & 7145024.) | |
1433 // Note that this code is specific to LP64. | |
1369 class ComputeMoveOrder: public StackObj { | 1434 class ComputeMoveOrder: public StackObj { |
1370 class MoveOperation: public ResourceObj { | 1435 class MoveOperation: public ResourceObj { |
1371 friend class ComputeMoveOrder; | 1436 friend class ComputeMoveOrder; |
1372 private: | 1437 private: |
1373 VMRegPair _src; | 1438 VMRegPair _src; |
1530 } | 1595 } |
1531 return stores; | 1596 return stores; |
1532 } | 1597 } |
1533 }; | 1598 }; |
1534 | 1599 |
1600 static void verify_oop_args(MacroAssembler* masm, | |
1601 int total_args_passed, | |
1602 const BasicType* sig_bt, | |
1603 const VMRegPair* regs) { | |
1604 Register temp_reg = rbx; // not part of any compiled calling seq | |
1605 if (VerifyOops) { | |
1606 for (int i = 0; i < total_args_passed; i++) { | |
1607 if (sig_bt[i] == T_OBJECT || | |
1608 sig_bt[i] == T_ARRAY) { | |
1609 VMReg r = regs[i].first(); | |
1610 assert(r->is_valid(), "bad oop arg"); | |
1611 if (r->is_stack()) { | |
1612 __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | |
1613 __ verify_oop(temp_reg); | |
1614 } else { | |
1615 __ verify_oop(r->as_Register()); | |
1616 } | |
1617 } | |
1618 } | |
1619 } | |
1620 } | |
1621 | |
1622 static void gen_special_dispatch(MacroAssembler* masm, | |
1623 int total_args_passed, | |
1624 int comp_args_on_stack, | |
1625 vmIntrinsics::ID special_dispatch, | |
1626 const BasicType* sig_bt, | |
1627 const VMRegPair* regs) { | |
1628 verify_oop_args(masm, total_args_passed, sig_bt, regs); | |
1629 | |
1630 // Now write the args into the outgoing interpreter space | |
1631 bool has_receiver = false; | |
1632 Register receiver_reg = noreg; | |
1633 int member_arg_pos = -1; | |
1634 Register member_reg = noreg; | |
1635 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); | |
1636 if (ref_kind != 0) { | |
1637 member_arg_pos = total_args_passed - 1; // trailing MemberName argument | |
1638 member_reg = rbx; // known to be free at this point | |
1639 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); | |
1640 } else if (special_dispatch == vmIntrinsics::_invokeBasic) { | |
1641 has_receiver = true; | |
1642 } else { | |
1643 guarantee(false, err_msg("special_dispatch=%d", special_dispatch)); | |
1644 } | |
1645 | |
1646 if (member_reg != noreg) { | |
1647 // Load the member_arg into register, if necessary. | |
1648 assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); | |
1649 assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); | |
1650 VMReg r = regs[member_arg_pos].first(); | |
1651 assert(r->is_valid(), "bad member arg"); | |
1652 if (r->is_stack()) { | |
1653 __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | |
1654 } else { | |
1655 // no data motion is needed | |
1656 member_reg = r->as_Register(); | |
1657 } | |
1658 } | |
1659 | |
1660 if (has_receiver) { | |
1661 // Make sure the receiver is loaded into a register. | |
1662 assert(total_args_passed > 0, "oob"); | |
1663 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); | |
1664 VMReg r = regs[0].first(); | |
1665 assert(r->is_valid(), "bad receiver arg"); | |
1666 if (r->is_stack()) { | |
1667 // Porting note: This assumes that compiled calling conventions always | |
1668 // pass the receiver oop in a register. If this is not true on some | |
1669 // platform, pick a temp and load the receiver from stack. | |
1670 assert(false, "receiver always in a register"); | |
1671 receiver_reg = j_rarg0; // known to be free at this point | |
1672 __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | |
1673 } else { | |
1674 // no data motion is needed | |
1675 receiver_reg = r->as_Register(); | |
1676 } | |
1677 } | |
1678 | |
1679 // Figure out which address we are really jumping to: | |
1680 MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, | |
1681 receiver_reg, member_reg, /*for_compiler_entry:*/ true); | |
1682 } | |
1535 | 1683 |
1536 // --------------------------------------------------------------------------- | 1684 // --------------------------------------------------------------------------- |
1537 // Generate a native wrapper for a given method. The method takes arguments | 1685 // Generate a native wrapper for a given method. The method takes arguments |
1538 // in the Java compiled code convention, marshals them to the native | 1686 // in the Java compiled code convention, marshals them to the native |
1539 // convention (handlizes oops, etc), transitions to native, makes the call, | 1687 // convention (handlizes oops, etc), transitions to native, makes the call, |
1540 // returns to java state (possibly blocking), unhandlizes any result and | 1688 // returns to java state (possibly blocking), unhandlizes any result and |
1541 // returns. | 1689 // returns. |
1542 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, | 1690 // |
1691 // Critical native functions are a shorthand for the use of | |
1692 // GetPrimtiveArrayCritical and disallow the use of any other JNI | |
1693 // functions. The wrapper is expected to unpack the arguments before | |
1694 // passing them to the callee and perform checks before and after the | |
1695 // native call to ensure that they GC_locker | |
1696 // lock_critical/unlock_critical semantics are followed. Some other | |
1697 // parts of JNI setup are skipped like the tear down of the JNI handle | |
1698 // block and the check for pending exceptions it's impossible for them | |
1699 // to be thrown. | |
1700 // | |
1701 // They are roughly structured like this: | |
1702 // if (GC_locker::needs_gc()) | |
1703 // SharedRuntime::block_for_jni_critical(); | |
1704 // tranistion to thread_in_native | |
1705 // unpack arrray arguments and call native entry point | |
1706 // check for safepoint in progress | |
1707 // check if any thread suspend flags are set | |
1708 // call into JVM and possible unlock the JNI critical | |
1709 // if a GC was suppressed while in the critical native. | |
1710 // transition back to thread_in_Java | |
1711 // return to caller | |
1712 // | |
1713 nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, | |
1543 methodHandle method, | 1714 methodHandle method, |
1544 int compile_id, | 1715 int compile_id, |
1545 int total_in_args, | 1716 int total_in_args, |
1546 int comp_args_on_stack, | 1717 int comp_args_on_stack, |
1547 BasicType *in_sig_bt, | 1718 BasicType* in_sig_bt, |
1548 VMRegPair *in_regs, | 1719 VMRegPair* in_regs, |
1549 BasicType ret_type) { | 1720 BasicType ret_type) { |
1721 if (method->is_method_handle_intrinsic()) { | |
1722 vmIntrinsics::ID iid = method->intrinsic_id(); | |
1723 intptr_t start = (intptr_t)__ pc(); | |
1724 int vep_offset = ((intptr_t)__ pc()) - start; | |
1725 gen_special_dispatch(masm, | |
1726 total_in_args, | |
1727 comp_args_on_stack, | |
1728 method->intrinsic_id(), | |
1729 in_sig_bt, | |
1730 in_regs); | |
1731 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period | |
1732 __ flush(); | |
1733 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually | |
1734 return nmethod::new_native_nmethod(method, | |
1735 compile_id, | |
1736 masm->code(), | |
1737 vep_offset, | |
1738 frame_complete, | |
1739 stack_slots / VMRegImpl::slots_per_word, | |
1740 in_ByteSize(-1), | |
1741 in_ByteSize(-1), | |
1742 (OopMapSet*)NULL); | |
1743 } | |
1550 bool is_critical_native = true; | 1744 bool is_critical_native = true; |
1551 address native_func = method->critical_native_function(); | 1745 address native_func = method->critical_native_function(); |
1552 if (native_func == NULL) { | 1746 if (native_func == NULL) { |
1553 native_func = method->native_function(); | 1747 native_func = method->native_function(); |
1554 is_critical_native = false; | 1748 is_critical_native = false; |
1656 case T_BOOLEAN: | 1850 case T_BOOLEAN: |
1657 case T_BYTE: | 1851 case T_BYTE: |
1658 case T_SHORT: | 1852 case T_SHORT: |
1659 case T_CHAR: | 1853 case T_CHAR: |
1660 case T_INT: single_slots++; break; | 1854 case T_INT: single_slots++; break; |
1661 case T_ARRAY: | 1855 case T_ARRAY: // specific to LP64 (7145024) |
1662 case T_LONG: double_slots++; break; | 1856 case T_LONG: double_slots++; break; |
1663 default: ShouldNotReachHere(); | 1857 default: ShouldNotReachHere(); |
1664 } | 1858 } |
1665 } else if (in_regs[i].first()->is_XMMRegister()) { | 1859 } else if (in_regs[i].first()->is_XMMRegister()) { |
1666 switch (in_sig_bt[i]) { | 1860 switch (in_sig_bt[i]) { |