< prev index next >

src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp

Print this page

 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 
 25 #include "precompiled.hpp"
 26 #include "c1/c1_CodeStubs.hpp"
 27 #include "c1/c1_FrameMap.hpp"
 28 #include "c1/c1_LIRAssembler.hpp"
 29 #include "c1/c1_MacroAssembler.hpp"
 30 #include "c1/c1_Runtime1.hpp"
 31 #include "classfile/javaClasses.hpp"
 32 #include "nativeInst_x86.hpp"

 33 #include "runtime/sharedRuntime.hpp"
 34 #include "utilities/align.hpp"
 35 #include "utilities/macros.hpp"
 36 #include "vmreg_x86.inline.hpp"
 37 
 38 
 39 #define __ ce->masm()->
 40 
 41 #ifndef _LP64
 42 float ConversionStub::float_zero = 0.0;
 43 double ConversionStub::double_zero = 0.0;
 44 
 45 void ConversionStub::emit_code(LIR_Assembler* ce) {
 46   __ bind(_entry);
 47   assert(bytecode() == Bytecodes::_f2i || bytecode() == Bytecodes::_d2i, "other conversions do not require stub");
 48 
 49 
 50   if (input()->is_single_xmm()) {
 51     __ comiss(input()->as_xmm_float_reg(),
 52               ExternalAddress((address)&float_zero));

153 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
154   __ bind(_entry);
155   address a = Runtime1::entry_for(C1StubId::predicate_failed_trap_id);
156   __ call(RuntimeAddress(a));
157   ce->add_call_info_here(_info);
158   ce->verify_oop_map(_info);
159   debug_only(__ should_not_reach_here());
160 }
161 
162 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
163   if (_offset != -1) {
164     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
165   }
166   __ bind(_entry);
167   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::throw_div0_exception_id)));
168   ce->add_call_info_here(_info);
169   debug_only(__ should_not_reach_here());
170 }
171 
172 









































































173 // Implementation of NewInstanceStub
174 
175 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, C1StubId stub_id) {
176   _result = result;
177   _klass = klass;
178   _klass_reg = klass_reg;
179   _info = new CodeEmitInfo(info);
180   assert(stub_id == C1StubId::new_instance_id                 ||
181          stub_id == C1StubId::fast_new_instance_id            ||
182          stub_id == C1StubId::fast_new_instance_init_check_id,
183          "need new_instance id");
184   _stub_id   = stub_id;
185 }
186 
187 
188 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
189   assert(__ rsp_offset() == 0, "frame size should be fixed");
190   __ bind(_entry);
191   __ movptr(rdx, _klass_reg->as_register());
192   __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));

205   _result = result;
206   _info = new CodeEmitInfo(info);
207 }
208 
209 
210 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
211   assert(__ rsp_offset() == 0, "frame size should be fixed");
212   __ bind(_entry);
213   assert(_length->as_register() == rbx, "length must in rbx,");
214   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
215   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_type_array_id)));
216   ce->add_call_info_here(_info);
217   ce->verify_oop_map(_info);
218   assert(_result->as_register() == rax, "result must in rax,");
219   __ jmp(_continuation);
220 }
221 
222 
223 // Implementation of NewObjectArrayStub
224 
225 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {

226   _klass_reg = klass_reg;
227   _result = result;
228   _length = length;
229   _info = new CodeEmitInfo(info);

230 }
231 
232 
233 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
234   assert(__ rsp_offset() == 0, "frame size should be fixed");
235   __ bind(_entry);
236   assert(_length->as_register() == rbx, "length must in rbx,");
237   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
238   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_object_array_id)));




239   ce->add_call_info_here(_info);
240   ce->verify_oop_map(_info);
241   assert(_result->as_register() == rax, "result must in rax,");
242   __ jmp(_continuation);
243 }
244 
245 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
246   assert(__ rsp_offset() == 0, "frame size should be fixed");
247   __ bind(_entry);









248   ce->store_parameter(_obj_reg->as_register(),  1);
249   ce->store_parameter(_lock_reg->as_register(), 0);
250   C1StubId enter_id;
251   if (ce->compilation()->has_fpu_code()) {
252     enter_id = C1StubId::monitorenter_id;
253   } else {
254     enter_id = C1StubId::monitorenter_nofpu_id;
255   }
256   __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
257   ce->add_call_info_here(_info);
258   ce->verify_oop_map(_info);
259   __ jmp(_continuation);
260 }
261 
262 
263 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
264   __ bind(_entry);
265   if (_compute_lock) {
266     // lock_reg was destroyed by fast unlocking attempt => recompute it
267     ce->monitor_address(_monitor_ix, _lock_reg);

 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 
 25 #include "precompiled.hpp"
 26 #include "c1/c1_CodeStubs.hpp"
 27 #include "c1/c1_FrameMap.hpp"
 28 #include "c1/c1_LIRAssembler.hpp"
 29 #include "c1/c1_MacroAssembler.hpp"
 30 #include "c1/c1_Runtime1.hpp"
 31 #include "classfile/javaClasses.hpp"
 32 #include "nativeInst_x86.hpp"
 33 #include "oops/objArrayKlass.hpp"
 34 #include "runtime/sharedRuntime.hpp"
 35 #include "utilities/align.hpp"
 36 #include "utilities/macros.hpp"
 37 #include "vmreg_x86.inline.hpp"
 38 
 39 
 40 #define __ ce->masm()->
 41 
 42 #ifndef _LP64
 43 float ConversionStub::float_zero = 0.0;
 44 double ConversionStub::double_zero = 0.0;
 45 
 46 void ConversionStub::emit_code(LIR_Assembler* ce) {
 47   __ bind(_entry);
 48   assert(bytecode() == Bytecodes::_f2i || bytecode() == Bytecodes::_d2i, "other conversions do not require stub");
 49 
 50 
 51   if (input()->is_single_xmm()) {
 52     __ comiss(input()->as_xmm_float_reg(),
 53               ExternalAddress((address)&float_zero));

154 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
155   __ bind(_entry);
156   address a = Runtime1::entry_for(C1StubId::predicate_failed_trap_id);
157   __ call(RuntimeAddress(a));
158   ce->add_call_info_here(_info);
159   ce->verify_oop_map(_info);
160   debug_only(__ should_not_reach_here());
161 }
162 
163 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
164   if (_offset != -1) {
165     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
166   }
167   __ bind(_entry);
168   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::throw_div0_exception_id)));
169   ce->add_call_info_here(_info);
170   debug_only(__ should_not_reach_here());
171 }
172 
173 
174 // Implementation of LoadFlattenedArrayStub
175 
176 LoadFlattenedArrayStub::LoadFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
177   _array = array;
178   _index = index;
179   _result = result;
180   // Tell the register allocator that the runtime call will scratch rax.
181   _scratch_reg = FrameMap::rax_oop_opr;
182   _info = new CodeEmitInfo(info);
183 }
184 
185 void LoadFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
186   assert(__ rsp_offset() == 0, "frame size should be fixed");
187   __ bind(_entry);
188   ce->store_parameter(_array->as_register(), 1);
189   ce->store_parameter(_index->as_register(), 0);
190   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::load_flat_array_id)));
191   ce->add_call_info_here(_info);
192   ce->verify_oop_map(_info);
193   if (_result->as_register() != rax) {
194     __ movptr(_result->as_register(), rax);
195   }
196   __ jmp(_continuation);
197 }
198 
199 
200 // Implementation of StoreFlattenedArrayStub
201 
202 StoreFlattenedArrayStub::StoreFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr value, CodeEmitInfo* info) {
203   _array = array;
204   _index = index;
205   _value = value;
206   // Tell the register allocator that the runtime call will scratch rax.
207   _scratch_reg = FrameMap::rax_oop_opr;
208   _info = new CodeEmitInfo(info);
209 }
210 
211 
212 void StoreFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
213   assert(__ rsp_offset() == 0, "frame size should be fixed");
214   __ bind(_entry);
215   ce->store_parameter(_array->as_register(), 2);
216   ce->store_parameter(_index->as_register(), 1);
217   ce->store_parameter(_value->as_register(), 0);
218   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::store_flat_array_id)));
219   ce->add_call_info_here(_info);
220   ce->verify_oop_map(_info);
221   __ jmp(_continuation);
222 }
223 
224 
225 // Implementation of SubstitutabilityCheckStub
226 
227 SubstitutabilityCheckStub::SubstitutabilityCheckStub(LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
228   _left = left;
229   _right = right;
230   // Tell the register allocator that the runtime call will scratch rax.
231   _scratch_reg = FrameMap::rax_oop_opr;
232   _info = new CodeEmitInfo(info);
233 }
234 
235 void SubstitutabilityCheckStub::emit_code(LIR_Assembler* ce) {
236   assert(__ rsp_offset() == 0, "frame size should be fixed");
237   __ bind(_entry);
238   ce->store_parameter(_left->as_register(), 1);
239   ce->store_parameter(_right->as_register(), 0);
240   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::substitutability_check_id)));
241   ce->add_call_info_here(_info);
242   ce->verify_oop_map(_info);
243   __ jmp(_continuation);
244 }
245 
246 
247 // Implementation of NewInstanceStub
248 
249 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, C1StubId stub_id) {
250   _result = result;
251   _klass = klass;
252   _klass_reg = klass_reg;
253   _info = new CodeEmitInfo(info);
254   assert(stub_id == C1StubId::new_instance_id                 ||
255          stub_id == C1StubId::fast_new_instance_id            ||
256          stub_id == C1StubId::fast_new_instance_init_check_id,
257          "need new_instance id");
258   _stub_id   = stub_id;
259 }
260 
261 
262 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
263   assert(__ rsp_offset() == 0, "frame size should be fixed");
264   __ bind(_entry);
265   __ movptr(rdx, _klass_reg->as_register());
266   __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));

279   _result = result;
280   _info = new CodeEmitInfo(info);
281 }
282 
283 
284 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
285   assert(__ rsp_offset() == 0, "frame size should be fixed");
286   __ bind(_entry);
287   assert(_length->as_register() == rbx, "length must in rbx,");
288   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
289   __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_type_array_id)));
290   ce->add_call_info_here(_info);
291   ce->verify_oop_map(_info);
292   assert(_result->as_register() == rax, "result must in rax,");
293   __ jmp(_continuation);
294 }
295 
296 
297 // Implementation of NewObjectArrayStub
298 
299 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result,
300                                        CodeEmitInfo* info, bool is_null_free) {
301   _klass_reg = klass_reg;
302   _result = result;
303   _length = length;
304   _info = new CodeEmitInfo(info);
305   _is_null_free = is_null_free;
306 }
307 
308 
309 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
310   assert(__ rsp_offset() == 0, "frame size should be fixed");
311   __ bind(_entry);
312   assert(_length->as_register() == rbx, "length must in rbx,");
313   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
314   if (_is_null_free) {
315     __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_null_free_array_id)));
316   } else {
317     __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_object_array_id)));
318   }
319   ce->add_call_info_here(_info);
320   ce->verify_oop_map(_info);
321   assert(_result->as_register() == rax, "result must in rax,");
322   __ jmp(_continuation);
323 }
324 
325 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
326   assert(__ rsp_offset() == 0, "frame size should be fixed");
327   __ bind(_entry);
328   if (_throw_ie_stub != nullptr) {
329     // When we come here, _obj_reg has already been checked to be non-null.
330     const int is_value_mask = markWord::inline_type_pattern;
331     Register mark = _scratch_reg->as_register();
332     __ movptr(mark, Address(_obj_reg->as_register(), oopDesc::mark_offset_in_bytes()));
333     __ andptr(mark, is_value_mask);
334     __ cmpl(mark, is_value_mask);
335     __ jcc(Assembler::equal, *_throw_ie_stub->entry());
336   }
337   ce->store_parameter(_obj_reg->as_register(),  1);
338   ce->store_parameter(_lock_reg->as_register(), 0);
339   C1StubId enter_id;
340   if (ce->compilation()->has_fpu_code()) {
341     enter_id = C1StubId::monitorenter_id;
342   } else {
343     enter_id = C1StubId::monitorenter_nofpu_id;
344   }
345   __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
346   ce->add_call_info_here(_info);
347   ce->verify_oop_map(_info);
348   __ jmp(_continuation);
349 }
350 
351 
352 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
353   __ bind(_entry);
354   if (_compute_lock) {
355     // lock_reg was destroyed by fast unlocking attempt => recompute it
356     ce->monitor_address(_monitor_ix, _lock_reg);
< prev index next >