< 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));

165 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
166   __ bind(_entry);
167   address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
168   __ call(RuntimeAddress(a));
169   ce->add_call_info_here(_info);
170   ce->verify_oop_map(_info);
171   debug_only(__ should_not_reach_here());
172 }
173 
174 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
175   if (_offset != -1) {
176     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
177   }
178   __ bind(_entry);
179   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_div0_exception_id)));
180   ce->add_call_info_here(_info);
181   debug_only(__ should_not_reach_here());
182 }
183 
184 









































































185 // Implementation of NewInstanceStub
186 
187 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
188   _result = result;
189   _klass = klass;
190   _klass_reg = klass_reg;
191   _info = new CodeEmitInfo(info);
192   assert(stub_id == Runtime1::new_instance_id                 ||

193          stub_id == Runtime1::fast_new_instance_id            ||
194          stub_id == Runtime1::fast_new_instance_init_check_id,
195          "need new_instance id");
196   _stub_id   = stub_id;
197 }
198 
199 
200 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
201   assert(__ rsp_offset() == 0, "frame size should be fixed");
202   __ bind(_entry);
203   __ movptr(rdx, _klass_reg->as_register());
204   __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
205   ce->add_call_info_here(_info);
206   ce->verify_oop_map(_info);
207   assert(_result->as_register() == rax, "result must in rax,");
208   __ jmp(_continuation);
209 }
210 
211 
212 // Implementation of NewTypeArrayStub

217   _result = result;
218   _info = new CodeEmitInfo(info);
219 }
220 
221 
222 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
223   assert(__ rsp_offset() == 0, "frame size should be fixed");
224   __ bind(_entry);
225   assert(_length->as_register() == rbx, "length must in rbx,");
226   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
227   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_type_array_id)));
228   ce->add_call_info_here(_info);
229   ce->verify_oop_map(_info);
230   assert(_result->as_register() == rax, "result must in rax,");
231   __ jmp(_continuation);
232 }
233 
234 
235 // Implementation of NewObjectArrayStub
236 
237 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {

238   _klass_reg = klass_reg;
239   _result = result;
240   _length = length;
241   _info = new CodeEmitInfo(info);

242 }
243 
244 
245 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
246   assert(__ rsp_offset() == 0, "frame size should be fixed");
247   __ bind(_entry);
248   assert(_length->as_register() == rbx, "length must in rbx,");
249   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
250   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id)));




251   ce->add_call_info_here(_info);
252   ce->verify_oop_map(_info);
253   assert(_result->as_register() == rax, "result must in rax,");
254   __ jmp(_continuation);
255 }
256 
257 
258 // Implementation of MonitorAccessStubs
259 
260 MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info)
261 : MonitorAccessStub(obj_reg, lock_reg)
262 {
263   _info = new CodeEmitInfo(info);





264 }
265 
266 
267 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
268   assert(__ rsp_offset() == 0, "frame size should be fixed");
269   __ bind(_entry);









270   ce->store_parameter(_obj_reg->as_register(),  1);
271   ce->store_parameter(_lock_reg->as_register(), 0);
272   Runtime1::StubID enter_id;
273   if (ce->compilation()->has_fpu_code()) {
274     enter_id = Runtime1::monitorenter_id;
275   } else {
276     enter_id = Runtime1::monitorenter_nofpu_id;
277   }
278   __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
279   ce->add_call_info_here(_info);
280   ce->verify_oop_map(_info);
281   __ jmp(_continuation);
282 }
283 
284 
285 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
286   __ bind(_entry);
287   if (_compute_lock) {
288     // lock_reg was destroyed by fast unlocking attempt => recompute it
289     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));

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

292   _result = result;
293   _info = new CodeEmitInfo(info);
294 }
295 
296 
297 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
298   assert(__ rsp_offset() == 0, "frame size should be fixed");
299   __ bind(_entry);
300   assert(_length->as_register() == rbx, "length must in rbx,");
301   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
302   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_type_array_id)));
303   ce->add_call_info_here(_info);
304   ce->verify_oop_map(_info);
305   assert(_result->as_register() == rax, "result must in rax,");
306   __ jmp(_continuation);
307 }
308 
309 
310 // Implementation of NewObjectArrayStub
311 
312 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result,
313                                        CodeEmitInfo* info, bool is_null_free) {
314   _klass_reg = klass_reg;
315   _result = result;
316   _length = length;
317   _info = new CodeEmitInfo(info);
318   _is_null_free = is_null_free;
319 }
320 
321 
322 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
323   assert(__ rsp_offset() == 0, "frame size should be fixed");
324   __ bind(_entry);
325   assert(_length->as_register() == rbx, "length must in rbx,");
326   assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
327   if (_is_null_free) {
328     __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_flat_array_id)));
329   } else {
330     __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id)));
331   }
332   ce->add_call_info_here(_info);
333   ce->verify_oop_map(_info);
334   assert(_result->as_register() == rax, "result must in rax,");
335   __ jmp(_continuation);
336 }
337 
338 
339 // Implementation of MonitorAccessStubs
340 
341 MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info, CodeStub* throw_imse_stub, LIR_Opr scratch_reg)
342 : MonitorAccessStub(obj_reg, lock_reg)
343 {
344   _info = new CodeEmitInfo(info);
345   _throw_imse_stub = throw_imse_stub;
346   _scratch_reg = scratch_reg;
347   if (_throw_imse_stub != NULL) {
348     assert(_scratch_reg != LIR_OprFact::illegalOpr, "must be");
349   }
350 }
351 
352 
353 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
354   assert(__ rsp_offset() == 0, "frame size should be fixed");
355   __ bind(_entry);
356   if (_throw_imse_stub != NULL) {
357     // When we come here, _obj_reg has already been checked to be non-null.
358     const int is_value_mask = markWord::inline_type_pattern;
359     Register mark = _scratch_reg->as_register();
360     __ movptr(mark, Address(_obj_reg->as_register(), oopDesc::mark_offset_in_bytes()));
361     __ andptr(mark, is_value_mask);
362     __ cmpl(mark, is_value_mask);
363     __ jcc(Assembler::equal, *_throw_imse_stub->entry());
364   }
365   ce->store_parameter(_obj_reg->as_register(),  1);
366   ce->store_parameter(_lock_reg->as_register(), 0);
367   Runtime1::StubID enter_id;
368   if (ce->compilation()->has_fpu_code()) {
369     enter_id = Runtime1::monitorenter_id;
370   } else {
371     enter_id = Runtime1::monitorenter_nofpu_id;
372   }
373   __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
374   ce->add_call_info_here(_info);
375   ce->verify_oop_map(_info);
376   __ jmp(_continuation);
377 }
378 
379 
380 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
381   __ bind(_entry);
382   if (_compute_lock) {
383     // lock_reg was destroyed by fast unlocking attempt => recompute it
384     ce->monitor_address(_monitor_ix, _lock_reg);
< prev index next >