Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/sharedRuntime_x86_64.cpp @ 6790:2cb2f30450c7
7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
Reviewed-by: kvn, jrose, bdelsart
author | twisti |
---|---|
date | Mon, 17 Sep 2012 12:57:58 -0700 |
parents | 8a02ca5e5576 |
children | 137868b7aa6f |
comparison
equal
deleted
inserted
replaced
6749:a6fe94b9759f | 6790:2cb2f30450c7 |
---|---|
1591 return stores; | 1591 return stores; |
1592 } | 1592 } |
1593 }; | 1593 }; |
1594 | 1594 |
1595 static void verify_oop_args(MacroAssembler* masm, | 1595 static void verify_oop_args(MacroAssembler* masm, |
1596 int total_args_passed, | 1596 methodHandle method, |
1597 const BasicType* sig_bt, | 1597 const BasicType* sig_bt, |
1598 const VMRegPair* regs) { | 1598 const VMRegPair* regs) { |
1599 Register temp_reg = rbx; // not part of any compiled calling seq | 1599 Register temp_reg = rbx; // not part of any compiled calling seq |
1600 if (VerifyOops) { | 1600 if (VerifyOops) { |
1601 for (int i = 0; i < total_args_passed; i++) { | 1601 for (int i = 0; i < method->size_of_parameters(); i++) { |
1602 if (sig_bt[i] == T_OBJECT || | 1602 if (sig_bt[i] == T_OBJECT || |
1603 sig_bt[i] == T_ARRAY) { | 1603 sig_bt[i] == T_ARRAY) { |
1604 VMReg r = regs[i].first(); | 1604 VMReg r = regs[i].first(); |
1605 assert(r->is_valid(), "bad oop arg"); | 1605 assert(r->is_valid(), "bad oop arg"); |
1606 if (r->is_stack()) { | 1606 if (r->is_stack()) { |
1613 } | 1613 } |
1614 } | 1614 } |
1615 } | 1615 } |
1616 | 1616 |
1617 static void gen_special_dispatch(MacroAssembler* masm, | 1617 static void gen_special_dispatch(MacroAssembler* masm, |
1618 int total_args_passed, | 1618 methodHandle method, |
1619 int comp_args_on_stack, | |
1620 vmIntrinsics::ID special_dispatch, | |
1621 const BasicType* sig_bt, | 1619 const BasicType* sig_bt, |
1622 const VMRegPair* regs) { | 1620 const VMRegPair* regs) { |
1623 verify_oop_args(masm, total_args_passed, sig_bt, regs); | 1621 verify_oop_args(masm, method, sig_bt, regs); |
1622 vmIntrinsics::ID iid = method->intrinsic_id(); | |
1624 | 1623 |
1625 // Now write the args into the outgoing interpreter space | 1624 // Now write the args into the outgoing interpreter space |
1626 bool has_receiver = false; | 1625 bool has_receiver = false; |
1627 Register receiver_reg = noreg; | 1626 Register receiver_reg = noreg; |
1628 int member_arg_pos = -1; | 1627 int member_arg_pos = -1; |
1629 Register member_reg = noreg; | 1628 Register member_reg = noreg; |
1630 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); | 1629 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); |
1631 if (ref_kind != 0) { | 1630 if (ref_kind != 0) { |
1632 member_arg_pos = total_args_passed - 1; // trailing MemberName argument | 1631 member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument |
1633 member_reg = rbx; // known to be free at this point | 1632 member_reg = rbx; // known to be free at this point |
1634 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); | 1633 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); |
1635 } else if (special_dispatch == vmIntrinsics::_invokeBasic) { | 1634 } else if (iid == vmIntrinsics::_invokeBasic) { |
1636 has_receiver = true; | 1635 has_receiver = true; |
1637 } else { | 1636 } else { |
1638 guarantee(false, err_msg("special_dispatch=%d", special_dispatch)); | 1637 fatal(err_msg_res("unexpected intrinsic id %d", iid)); |
1639 } | 1638 } |
1640 | 1639 |
1641 if (member_reg != noreg) { | 1640 if (member_reg != noreg) { |
1642 // Load the member_arg into register, if necessary. | 1641 // Load the member_arg into register, if necessary. |
1643 assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); | 1642 SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs); |
1644 assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); | |
1645 VMReg r = regs[member_arg_pos].first(); | 1643 VMReg r = regs[member_arg_pos].first(); |
1646 assert(r->is_valid(), "bad member arg"); | |
1647 if (r->is_stack()) { | 1644 if (r->is_stack()) { |
1648 __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | 1645 __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); |
1649 } else { | 1646 } else { |
1650 // no data motion is needed | 1647 // no data motion is needed |
1651 member_reg = r->as_Register(); | 1648 member_reg = r->as_Register(); |
1652 } | 1649 } |
1653 } | 1650 } |
1654 | 1651 |
1655 if (has_receiver) { | 1652 if (has_receiver) { |
1656 // Make sure the receiver is loaded into a register. | 1653 // Make sure the receiver is loaded into a register. |
1657 assert(total_args_passed > 0, "oob"); | 1654 assert(method->size_of_parameters() > 0, "oob"); |
1658 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); | 1655 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); |
1659 VMReg r = regs[0].first(); | 1656 VMReg r = regs[0].first(); |
1660 assert(r->is_valid(), "bad receiver arg"); | 1657 assert(r->is_valid(), "bad receiver arg"); |
1661 if (r->is_stack()) { | 1658 if (r->is_stack()) { |
1662 // Porting note: This assumes that compiled calling conventions always | 1659 // Porting note: This assumes that compiled calling conventions always |
1663 // pass the receiver oop in a register. If this is not true on some | 1660 // pass the receiver oop in a register. If this is not true on some |
1664 // platform, pick a temp and load the receiver from stack. | 1661 // platform, pick a temp and load the receiver from stack. |
1665 assert(false, "receiver always in a register"); | 1662 fatal("receiver always in a register"); |
1666 receiver_reg = j_rarg0; // known to be free at this point | 1663 receiver_reg = j_rarg0; // known to be free at this point |
1667 __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | 1664 __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); |
1668 } else { | 1665 } else { |
1669 // no data motion is needed | 1666 // no data motion is needed |
1670 receiver_reg = r->as_Register(); | 1667 receiver_reg = r->as_Register(); |
1671 } | 1668 } |
1672 } | 1669 } |
1673 | 1670 |
1674 // Figure out which address we are really jumping to: | 1671 // Figure out which address we are really jumping to: |
1675 MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, | 1672 MethodHandles::generate_method_handle_dispatch(masm, iid, |
1676 receiver_reg, member_reg, /*for_compiler_entry:*/ true); | 1673 receiver_reg, member_reg, /*for_compiler_entry:*/ true); |
1677 } | 1674 } |
1678 | 1675 |
1679 // --------------------------------------------------------------------------- | 1676 // --------------------------------------------------------------------------- |
1680 // Generate a native wrapper for a given method. The method takes arguments | 1677 // Generate a native wrapper for a given method. The method takes arguments |
1706 // return to caller | 1703 // return to caller |
1707 // | 1704 // |
1708 nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, | 1705 nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, |
1709 methodHandle method, | 1706 methodHandle method, |
1710 int compile_id, | 1707 int compile_id, |
1711 int total_in_args, | |
1712 int comp_args_on_stack, | |
1713 BasicType* in_sig_bt, | 1708 BasicType* in_sig_bt, |
1714 VMRegPair* in_regs, | 1709 VMRegPair* in_regs, |
1715 BasicType ret_type) { | 1710 BasicType ret_type) { |
1716 if (method->is_method_handle_intrinsic()) { | 1711 if (method->is_method_handle_intrinsic()) { |
1717 vmIntrinsics::ID iid = method->intrinsic_id(); | 1712 vmIntrinsics::ID iid = method->intrinsic_id(); |
1718 intptr_t start = (intptr_t)__ pc(); | 1713 intptr_t start = (intptr_t)__ pc(); |
1719 int vep_offset = ((intptr_t)__ pc()) - start; | 1714 int vep_offset = ((intptr_t)__ pc()) - start; |
1720 gen_special_dispatch(masm, | 1715 gen_special_dispatch(masm, |
1721 total_in_args, | 1716 method, |
1722 comp_args_on_stack, | |
1723 method->intrinsic_id(), | |
1724 in_sig_bt, | 1717 in_sig_bt, |
1725 in_regs); | 1718 in_regs); |
1726 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period | 1719 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period |
1727 __ flush(); | 1720 __ flush(); |
1728 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually | 1721 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually |
1752 // on entry to the wrapper. We need to convert these args to where | 1745 // on entry to the wrapper. We need to convert these args to where |
1753 // the jni function will expect them. To figure out where they go | 1746 // the jni function will expect them. To figure out where they go |
1754 // we convert the java signature to a C signature by inserting | 1747 // we convert the java signature to a C signature by inserting |
1755 // the hidden arguments as arg[0] and possibly arg[1] (static method) | 1748 // the hidden arguments as arg[0] and possibly arg[1] (static method) |
1756 | 1749 |
1750 const int total_in_args = method->size_of_parameters(); | |
1757 int total_c_args = total_in_args; | 1751 int total_c_args = total_in_args; |
1758 if (!is_critical_native) { | 1752 if (!is_critical_native) { |
1759 total_c_args += 1; | 1753 total_c_args += 1; |
1760 if (method->is_static()) { | 1754 if (method->is_static()) { |
1761 total_c_args++; | 1755 total_c_args++; |