< prev index next >

src/hotspot/cpu/x86/foreign_globals_x86.cpp

Print this page

  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 #include "precompiled.hpp"
 25 #include "runtime/jniHandles.hpp"
 26 #include "runtime/jniHandles.inline.hpp"
 27 #include "oops/typeArrayOop.inline.hpp"
 28 #include "prims/foreign_globals.hpp"
 29 #include "prims/foreign_globals.inline.hpp"


 30 
 31 bool ABIDescriptor::is_volatile_reg(Register reg) const {
 32     return _integer_argument_registers.contains(reg)
 33         || _integer_additional_volatile_registers.contains(reg);
 34 }
 35 
 36 bool ABIDescriptor::is_volatile_reg(XMMRegister reg) const {
 37     return _vector_argument_registers.contains(reg)
 38         || _vector_additional_volatile_registers.contains(reg);
 39 }
 40 
 41 #define INTEGER_TYPE 0
 42 #define VECTOR_TYPE 1
 43 #define X87_TYPE 2
 44 
 45 const ABIDescriptor ForeignGlobals::parse_abi_descriptor_impl(jobject jabi) const {
 46   oop abi_oop = JNIHandles::resolve_non_null(jabi);
 47   ABIDescriptor abi;
 48 
 49   objArrayOop inputStorage = cast<objArrayOop>(abi_oop->obj_field(ABI.inputStorage_offset));
 50   loadArray(inputStorage, INTEGER_TYPE, abi._integer_argument_registers, as_Register);
 51   loadArray(inputStorage, VECTOR_TYPE, abi._vector_argument_registers, as_XMMRegister);
 52 
 53   objArrayOop outputStorage = cast<objArrayOop>(abi_oop->obj_field(ABI.outputStorage_offset));
 54   loadArray(outputStorage, INTEGER_TYPE, abi._integer_return_registers, as_Register);
 55   loadArray(outputStorage, VECTOR_TYPE, abi._vector_return_registers, as_XMMRegister);
 56   objArrayOop subarray = cast<objArrayOop>(outputStorage->obj_at(X87_TYPE));
 57   abi._X87_return_registers_noof = subarray->length();
 58 
 59   objArrayOop volatileStorage = cast<objArrayOop>(abi_oop->obj_field(ABI.volatileStorage_offset));
 60   loadArray(volatileStorage, INTEGER_TYPE, abi._integer_additional_volatile_registers, as_Register);
 61   loadArray(volatileStorage, VECTOR_TYPE, abi._vector_additional_volatile_registers, as_XMMRegister);
 62 
 63   abi._stack_alignment_bytes = abi_oop->int_field(ABI.stackAlignment_offset);
 64   abi._shadow_space_bytes = abi_oop->int_field(ABI.shadowSpace_offset);
 65 



 66   return abi;
 67 }
 68 
 69 const BufferLayout ForeignGlobals::parse_buffer_layout_impl(jobject jlayout) const {
 70   oop layout_oop = JNIHandles::resolve_non_null(jlayout);
 71   BufferLayout layout;
 72 
 73   layout.stack_args_bytes = layout_oop->long_field(BL.stack_args_bytes_offset);
 74   layout.stack_args = layout_oop->long_field(BL.stack_args_offset);
 75   layout.arguments_next_pc = layout_oop->long_field(BL.arguments_next_pc_offset);
 76 
 77   typeArrayOop input_offsets = cast<typeArrayOop>(layout_oop->obj_field(BL.input_type_offsets_offset));
 78   layout.arguments_integer = (size_t) input_offsets->long_at(INTEGER_TYPE);
 79   layout.arguments_vector = (size_t) input_offsets->long_at(VECTOR_TYPE);
 80 
 81   typeArrayOop output_offsets = cast<typeArrayOop>(layout_oop->obj_field(BL.output_type_offsets_offset));
 82   layout.returns_integer = (size_t) output_offsets->long_at(INTEGER_TYPE);
 83   layout.returns_vector = (size_t) output_offsets->long_at(VECTOR_TYPE);
 84   layout.returns_x87 = (size_t) output_offsets->long_at(X87_TYPE);
 85 
 86   layout.buffer_size = layout_oop->long_field(BL.size_offset);
 87 
 88   return layout;
 89 }
 90 
 91 const CallRegs ForeignGlobals::parse_call_regs_impl(jobject jconv) const {
 92   oop conv_oop = JNIHandles::resolve_non_null(jconv);
 93   objArrayOop arg_regs_oop = cast<objArrayOop>(conv_oop->obj_field(CallConvOffsets.arg_regs_offset));
 94   objArrayOop ret_regs_oop = cast<objArrayOop>(conv_oop->obj_field(CallConvOffsets.ret_regs_offset));
 95 
 96   CallRegs result;
 97   result._args_length = arg_regs_oop->length();
 98   result._arg_regs = NEW_RESOURCE_ARRAY(VMReg, result._args_length);
 99 
100   result._rets_length = ret_regs_oop->length();
101   result._ret_regs = NEW_RESOURCE_ARRAY(VMReg, result._rets_length);
102 
103   for (int i = 0; i < result._args_length; i++) {
104     oop storage = arg_regs_oop->obj_at(i);
105     jint index = storage->int_field(VMS.index_offset);
106     jint type = storage->int_field(VMS.type_offset);
107     result._arg_regs[i] = VMRegImpl::vmStorageToVMReg(type, index);


108   }

109 
110   for (int i = 0; i < result._rets_length; i++) {
111     oop storage = ret_regs_oop->obj_at(i);
112     jint index = storage->int_field(VMS.index_offset);
113     jint type = storage->int_field(VMS.type_offset);
114     result._ret_regs[i] = VMRegImpl::vmStorageToVMReg(type, index);


115   }

116 
117   return result;









































118 }

  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 #include "precompiled.hpp"

 25 #include "runtime/jniHandles.inline.hpp"
 26 #include "oops/typeArrayOop.inline.hpp"
 27 #include "oops/oopCast.inline.hpp"
 28 #include "prims/foreign_globals.inline.hpp"
 29 #include "runtime/sharedRuntime.hpp"
 30 #include "utilities/formatBuffer.hpp"
 31 
 32 bool ABIDescriptor::is_volatile_reg(Register reg) const {
 33     return _integer_argument_registers.contains(reg)
 34         || _integer_additional_volatile_registers.contains(reg);
 35 }
 36 
 37 bool ABIDescriptor::is_volatile_reg(XMMRegister reg) const {
 38     return _vector_argument_registers.contains(reg)
 39         || _vector_additional_volatile_registers.contains(reg);
 40 }
 41 
 42 #define INTEGER_TYPE 0
 43 #define VECTOR_TYPE 1
 44 #define X87_TYPE 2
 45 
 46 const ABIDescriptor ForeignGlobals::parse_abi_descriptor_impl(jobject jabi) const {
 47   oop abi_oop = JNIHandles::resolve_non_null(jabi);
 48   ABIDescriptor abi;
 49 
 50   objArrayOop inputStorage = oop_cast<objArrayOop>(abi_oop->obj_field(ABI.inputStorage_offset));
 51   loadArray(inputStorage, INTEGER_TYPE, abi._integer_argument_registers, as_Register);
 52   loadArray(inputStorage, VECTOR_TYPE, abi._vector_argument_registers, as_XMMRegister);
 53 
 54   objArrayOop outputStorage = oop_cast<objArrayOop>(abi_oop->obj_field(ABI.outputStorage_offset));
 55   loadArray(outputStorage, INTEGER_TYPE, abi._integer_return_registers, as_Register);
 56   loadArray(outputStorage, VECTOR_TYPE, abi._vector_return_registers, as_XMMRegister);
 57   objArrayOop subarray = oop_cast<objArrayOop>(outputStorage->obj_at(X87_TYPE));
 58   abi._X87_return_registers_noof = subarray->length();
 59 
 60   objArrayOop volatileStorage = oop_cast<objArrayOop>(abi_oop->obj_field(ABI.volatileStorage_offset));
 61   loadArray(volatileStorage, INTEGER_TYPE, abi._integer_additional_volatile_registers, as_Register);
 62   loadArray(volatileStorage, VECTOR_TYPE, abi._vector_additional_volatile_registers, as_XMMRegister);
 63 
 64   abi._stack_alignment_bytes = abi_oop->int_field(ABI.stackAlignment_offset);
 65   abi._shadow_space_bytes = abi_oop->int_field(ABI.shadowSpace_offset);
 66 
 67   abi._target_addr_reg = parse_vmstorage(abi_oop->obj_field(ABI.targetAddrStorage_offset))->as_Register();
 68   abi._ret_buf_addr_reg = parse_vmstorage(abi_oop->obj_field(ABI.retBufAddrStorage_offset))->as_Register();
 69 
 70   return abi;
 71 }
 72 
 73 enum class RegType {
 74   INTEGER = 0,
 75   VECTOR = 1,
 76   X87 = 2,
 77   STACK = 3
 78 };
 79 
 80 VMReg ForeignGlobals::vmstorage_to_vmreg(int type, int index) {
 81   switch(static_cast<RegType>(type)) {
 82     case RegType::INTEGER: return ::as_Register(index)->as_VMReg();
 83     case RegType::VECTOR: return ::as_XMMRegister(index)->as_VMReg();
 84     case RegType::STACK: return VMRegImpl::stack2reg(index LP64_ONLY(* 2)); // numbering on x64 goes per 64-bits
 85     case RegType::X87: break;
 86   }
 87   return VMRegImpl::Bad();





 88 }
 89 
 90 int RegSpiller::pd_reg_size(VMReg reg) {
 91   if (reg->is_Register()) {
 92     return 8;
 93   } else if (reg->is_XMMRegister()) {
 94     return 16;
 95   }
 96   return 0; // stack and BAD
 97 }



 98 
 99 void RegSpiller::pd_store_reg(MacroAssembler* masm, int offset, VMReg reg) {
100   if (reg->is_Register()) {
101     masm->movptr(Address(rsp, offset), reg->as_Register());
102   } else if (reg->is_XMMRegister()) {
103     masm->movdqu(Address(rsp, offset), reg->as_XMMRegister());
104   } else {
105     // stack and BAD
106   }
107 }
108 
109 void RegSpiller::pd_load_reg(MacroAssembler* masm, int offset, VMReg reg) {
110   if (reg->is_Register()) {
111     masm->movptr(reg->as_Register(), Address(rsp, offset));
112   } else if (reg->is_XMMRegister()) {
113     masm->movdqu(reg->as_XMMRegister(), Address(rsp, offset));
114   } else {
115     // stack and BAD
116   }
117 }
118 
119 void ArgumentShuffle::pd_generate(MacroAssembler* masm, VMReg tmp, int in_stk_bias, int out_stk_bias) const {
120   Register tmp_reg = tmp->as_Register();
121   for (int i = 0; i < _moves.length(); i++) {
122     Move move = _moves.at(i);
123     BasicType arg_bt     = move.bt;
124     VMRegPair from_vmreg = move.from;
125     VMRegPair to_vmreg   = move.to;
126 
127     masm->block_comment(err_msg("bt=%s", null_safe_string(type2name(arg_bt))));
128     switch (arg_bt) {
129       case T_BOOLEAN:
130       case T_BYTE:
131       case T_SHORT:
132       case T_CHAR:
133       case T_INT:
134         masm->move32_64(from_vmreg, to_vmreg, tmp_reg, in_stk_bias, out_stk_bias);
135         break;
136 
137       case T_FLOAT:
138         if (to_vmreg.first()->is_Register()) { // Windows vararg call
139           masm->movq(to_vmreg.first()->as_Register(), from_vmreg.first()->as_XMMRegister());
140         } else {
141           masm->float_move(from_vmreg, to_vmreg, tmp_reg, in_stk_bias, out_stk_bias);
142         }
143         break;
144 
145       case T_DOUBLE:
146         if (to_vmreg.first()->is_Register()) { // Windows vararg call
147           masm->movq(to_vmreg.first()->as_Register(), from_vmreg.first()->as_XMMRegister());
148         } else {
149           masm->double_move(from_vmreg, to_vmreg, tmp_reg, in_stk_bias, out_stk_bias);
150         }
151         break;
152 
153       case T_LONG:
154         masm->long_move(from_vmreg, to_vmreg, tmp_reg, in_stk_bias, out_stk_bias);
155         break;
156 
157       default:
158         fatal("found in upcall args: %s", type2name(arg_bt));
159     }
160   }
161 }
< prev index next >