hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
changeset 13881 a326d528f3e1
parent 13742 9180987e305d
child 13883 6979b9850feb
equal deleted inserted replaced
13751:7fd047780d47 13881:a326d528f3e1
  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++;