< prev index next >

src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp

Print this page

 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_MacroAssembler.hpp"
 27 #include "c1/c1_Runtime1.hpp"
 28 #include "compiler/compilerDefinitions.inline.hpp"
 29 #include "gc/shared/barrierSet.hpp"
 30 #include "gc/shared/barrierSetAssembler.hpp"
 31 #include "gc/shared/collectedHeap.hpp"
 32 #include "gc/shared/tlab_globals.hpp"
 33 #include "interpreter/interpreter.hpp"
 34 #include "oops/arrayOop.hpp"
 35 #include "oops/markWord.hpp"
 36 #include "runtime/basicLock.hpp"

 37 #include "runtime/os.hpp"
 38 #include "runtime/sharedRuntime.hpp"
 39 #include "runtime/stubRoutines.hpp"
 40 
 41 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register tmp, Label& slow_case) {
 42   const int aligned_mask = BytesPerWord -1;
 43   const int hdr_offset = oopDesc::mark_offset_in_bytes();
 44   assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
 45   assert_different_registers(hdr, obj, disp_hdr, tmp);
 46   int null_check_offset = -1;
 47 
 48   verify_oop(obj);
 49 
 50   // save object being locked into the BasicObjectLock
 51   movptr(Address(disp_hdr, BasicObjectLock::obj_offset()), obj);
 52 
 53   null_check_offset = offset();
 54 
 55   if (DiagnoseSyncOnValueBasedClasses != 0) {
 56     load_klass(hdr, obj, rscratch1);
 57     movl(hdr, Address(hdr, Klass::access_flags_offset()));
 58     testl(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
 59     jcc(Assembler::notZero, slow_case);
 60   }
 61 
 62   // Load object header
 63   movptr(hdr, Address(obj, hdr_offset));
 64 
 65   if (LockingMode == LM_LIGHTWEIGHT) {
 66 #ifdef _LP64
 67     const Register thread = r15_thread;
 68 #else
 69     const Register thread = disp_hdr;
 70     get_thread(thread);
 71 #endif
 72     fast_lock_impl(obj, hdr, thread, tmp, slow_case);
 73   } else  if (LockingMode == LM_LEGACY) {
 74     Label done;
 75     // and mark it as unlocked
 76     orptr(hdr, markWord::unlocked_value);




 77     // save unlocked object header into the displaced header location on the stack
 78     movptr(Address(disp_hdr, 0), hdr);
 79     // test if object header is still the same (i.e. unlocked), and if so, store the
 80     // displaced header address in the object header - if it is not the same, get the
 81     // object header instead
 82     MacroAssembler::lock(); // must be immediately before cmpxchg!
 83     cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
 84     // if the object header was the same, we're done
 85     jcc(Assembler::equal, done);
 86     // if the object header was not the same, it is now in the hdr register
 87     // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
 88     //
 89     // 1) (hdr & aligned_mask) == 0
 90     // 2) rsp <= hdr
 91     // 3) hdr <= rsp + page_size
 92     //
 93     // these 3 tests can be done by evaluating the following expression:
 94     //
 95     // (hdr - rsp) & (aligned_mask - page_size)
 96     //

147     jcc(Assembler::notEqual, slow_case);
148     // done
149   }
150   bind(done);
151   dec_held_monitor_count();
152 }
153 
154 
155 // Defines obj, preserves var_size_in_bytes
156 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
157   if (UseTLAB) {
158     tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
159   } else {
160     jmp(slow_case);
161   }
162 }
163 
164 
165 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
166   assert_different_registers(obj, klass, len);
167   movptr(Address(obj, oopDesc::mark_offset_in_bytes()), checked_cast<int32_t>(markWord::prototype().value()));








168 #ifdef _LP64
169   if (UseCompressedClassPointers) { // Take care not to kill klass
170     movptr(t1, klass);
171     encode_klass_not_null(t1, rscratch1);
172     movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
173   } else
174 #endif
175   {
176     movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
177   }
178 
179   if (len->is_valid()) {
180     movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
181   }
182 #ifdef _LP64
183   else if (UseCompressedClassPointers) {
184     xorptr(t1, t1);
185     store_klass_gap(obj, t1);
186   }
187 #endif

300   verify_oop(receiver);
301   // explicit null check not needed since load from [klass_offset] causes a trap
302   // check against inline cache
303   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
304   int start_offset = offset();
305 
306   if (UseCompressedClassPointers) {
307     load_klass(rscratch1, receiver, rscratch2);
308     cmpptr(rscratch1, iCache);
309   } else {
310     cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
311   }
312   // if icache check fails, then jump to runtime routine
313   // Note: RECEIVER must still contain the receiver!
314   jump_cc(Assembler::notEqual,
315           RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
316   const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
317   assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
318 }
319 












320 
321 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
322   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");











323   // Make sure there is enough stack space for this method's activation.
324   // Note that we do this before doing an enter(). This matches the
325   // ordering of C2's stack overflow check / rsp decrement and allows
326   // the SharedRuntime stack overflow handling to be consistent
327   // between the two compilers.

328   generate_stack_overflow_check(bang_size_in_bytes);
329 
330   push(rbp);
331   if (PreserveFramePointer) {
332     mov(rbp, rsp);
333   }
334 #if !defined(_LP64) && defined(COMPILER2)
335   if (UseSSE < 2 && !CompilerConfig::is_c1_only_no_jvmci()) {
336     // c2 leaves fpu stack dirty. Clean it on entry
337     empty_FPU_stack();
338   }
339 #endif // !_LP64 && COMPILER2
340   decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
341 
342   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
343   // C1 code is not hot enough to micro optimize the nmethod entry barrier with an out-of-line stub
344   bs->nmethod_entry_barrier(this, nullptr /* slow_path */, nullptr /* continuation */);
345 }
346 
347 
348 void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
349   increment(rsp, frame_size_in_bytes);  // Does not emit code for frame_size == 0
350   pop(rbp);
351 }
352 
353 
354 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
355   if (breakAtEntry || VerifyFPU) {
356     // Verified Entry first instruction should be 5 bytes long for correct
357     // patching by patch_verified_entry().
358     //
359     // Breakpoint and VerifyFPU have one byte first instruction.
360     // Also first instruction will be one byte "push(rbp)" if stack banging
361     // code is not generated (see build_frame() above).
362     // For all these cases generate long instruction first.
363     fat_nop();
364   }
365   if (breakAtEntry) int3();
366   // build frame
367   IA32_ONLY( verify_FPU(0, "method_entry"); )
368 }
369 


























































370 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
371   // rbp, + 0: link
372   //     + 1: return address
373   //     + 2: argument with offset 0
374   //     + 3: argument with offset 1
375   //     + 4: ...
376 
377   movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
378 }
379 
380 #ifndef PRODUCT
381 
382 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
383   if (!VerifyOops) return;
384   verify_oop_addr(Address(rsp, stack_offset));
385 }
386 
387 void C1_MacroAssembler::verify_not_null_oop(Register r) {
388   if (!VerifyOops) return;
389   Label not_null;

 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_MacroAssembler.hpp"
 27 #include "c1/c1_Runtime1.hpp"
 28 #include "compiler/compilerDefinitions.inline.hpp"
 29 #include "gc/shared/barrierSet.hpp"
 30 #include "gc/shared/barrierSetAssembler.hpp"
 31 #include "gc/shared/collectedHeap.hpp"
 32 #include "gc/shared/tlab_globals.hpp"
 33 #include "interpreter/interpreter.hpp"
 34 #include "oops/arrayOop.hpp"
 35 #include "oops/markWord.hpp"
 36 #include "runtime/basicLock.hpp"
 37 #include "runtime/frame.inline.hpp"
 38 #include "runtime/os.hpp"
 39 #include "runtime/sharedRuntime.hpp"
 40 #include "runtime/stubRoutines.hpp"
 41 
 42 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register tmp, Label& slow_case) {
 43   const int aligned_mask = BytesPerWord -1;
 44   const int hdr_offset = oopDesc::mark_offset_in_bytes();
 45   assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
 46   assert_different_registers(hdr, obj, disp_hdr, tmp);
 47   int null_check_offset = -1;
 48 
 49   verify_oop(obj);
 50 
 51   // save object being locked into the BasicObjectLock
 52   movptr(Address(disp_hdr, BasicObjectLock::obj_offset()), obj);
 53 
 54   null_check_offset = offset();
 55 
 56   if (DiagnoseSyncOnValueBasedClasses != 0) {
 57     load_klass(hdr, obj, rscratch1);
 58     movl(hdr, Address(hdr, Klass::access_flags_offset()));
 59     testl(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
 60     jcc(Assembler::notZero, slow_case);
 61   }
 62 
 63   // Load object header
 64   movptr(hdr, Address(obj, hdr_offset));
 65 
 66   if (LockingMode == LM_LIGHTWEIGHT) {
 67 #ifdef _LP64
 68     const Register thread = r15_thread;
 69 #else
 70     const Register thread = disp_hdr;
 71     get_thread(thread);
 72 #endif
 73     fast_lock_impl(obj, hdr, thread, tmp, slow_case);
 74   } else  if (LockingMode == LM_LEGACY) {
 75     Label done;
 76     // and mark it as unlocked
 77     orptr(hdr, markWord::unlocked_value);
 78     if (EnableValhalla) {
 79       // Mask inline_type bit such that we go to the slow path if object is an inline type
 80       andptr(hdr, ~((int) markWord::inline_type_bit_in_place));
 81     }
 82     // save unlocked object header into the displaced header location on the stack
 83     movptr(Address(disp_hdr, 0), hdr);
 84     // test if object header is still the same (i.e. unlocked), and if so, store the
 85     // displaced header address in the object header - if it is not the same, get the
 86     // object header instead
 87     MacroAssembler::lock(); // must be immediately before cmpxchg!
 88     cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
 89     // if the object header was the same, we're done
 90     jcc(Assembler::equal, done);
 91     // if the object header was not the same, it is now in the hdr register
 92     // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
 93     //
 94     // 1) (hdr & aligned_mask) == 0
 95     // 2) rsp <= hdr
 96     // 3) hdr <= rsp + page_size
 97     //
 98     // these 3 tests can be done by evaluating the following expression:
 99     //
100     // (hdr - rsp) & (aligned_mask - page_size)
101     //

152     jcc(Assembler::notEqual, slow_case);
153     // done
154   }
155   bind(done);
156   dec_held_monitor_count();
157 }
158 
159 
160 // Defines obj, preserves var_size_in_bytes
161 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
162   if (UseTLAB) {
163     tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
164   } else {
165     jmp(slow_case);
166   }
167 }
168 
169 
170 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
171   assert_different_registers(obj, klass, len);
172   if (EnableValhalla) {
173     // Need to copy markWord::prototype header for klass
174     assert_different_registers(obj, klass, len, t1, t2);
175     movptr(t1, Address(klass, Klass::prototype_header_offset()));
176     movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
177   } else {
178     // This assumes that all prototype bits fit in an int32_t
179     movptr(Address(obj, oopDesc::mark_offset_in_bytes()), checked_cast<int32_t>(markWord::prototype().value()));
180   }
181 #ifdef _LP64
182   if (UseCompressedClassPointers) { // Take care not to kill klass
183     movptr(t1, klass);
184     encode_klass_not_null(t1, rscratch1);
185     movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
186   } else
187 #endif
188   {
189     movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
190   }
191 
192   if (len->is_valid()) {
193     movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
194   }
195 #ifdef _LP64
196   else if (UseCompressedClassPointers) {
197     xorptr(t1, t1);
198     store_klass_gap(obj, t1);
199   }
200 #endif

313   verify_oop(receiver);
314   // explicit null check not needed since load from [klass_offset] causes a trap
315   // check against inline cache
316   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
317   int start_offset = offset();
318 
319   if (UseCompressedClassPointers) {
320     load_klass(rscratch1, receiver, rscratch2);
321     cmpptr(rscratch1, iCache);
322   } else {
323     cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
324   }
325   // if icache check fails, then jump to runtime routine
326   // Note: RECEIVER must still contain the receiver!
327   jump_cc(Assembler::notEqual,
328           RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
329   const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
330   assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
331 }
332 
333 void C1_MacroAssembler::build_frame_helper(int frame_size_in_bytes, int sp_offset_for_orig_pc, int sp_inc, bool reset_orig_pc, bool needs_stack_repair) {
334   push(rbp);
335   if (PreserveFramePointer) {
336     mov(rbp, rsp);
337   }
338 #if !defined(_LP64) && defined(COMPILER2)
339   if (UseSSE < 2 && !CompilerConfig::is_c1_only_no_jvmci()) {
340       // c2 leaves fpu stack dirty. Clean it on entry
341       empty_FPU_stack();
342     }
343 #endif // !_LP64 && COMPILER2
344   decrement(rsp, frame_size_in_bytes);
345 
346   if (needs_stack_repair) {
347     // Save stack increment (also account for fixed framesize and rbp)
348     assert((sp_inc & (StackAlignmentInBytes-1)) == 0, "stack increment not aligned");
349     int real_frame_size = sp_inc + frame_size_in_bytes + wordSize;
350     movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
351   }
352   if (reset_orig_pc) {
353     // Zero orig_pc to detect deoptimization during buffering in the entry points
354     movptr(Address(rsp, sp_offset_for_orig_pc), 0);
355   }
356 }
357 
358 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes, int sp_offset_for_orig_pc, bool needs_stack_repair, bool has_scalarized_args, Label* verified_inline_entry_label) {
359   // Make sure there is enough stack space for this method's activation.
360   // Note that we do this before doing an enter(). This matches the
361   // ordering of C2's stack overflow check / rsp decrement and allows
362   // the SharedRuntime stack overflow handling to be consistent
363   // between the two compilers.
364   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
365   generate_stack_overflow_check(bang_size_in_bytes);
366 
367   build_frame_helper(frame_size_in_bytes, sp_offset_for_orig_pc, 0, has_scalarized_args, needs_stack_repair);










368 
369   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
370   // C1 code is not hot enough to micro optimize the nmethod entry barrier with an out-of-line stub
371   bs->nmethod_entry_barrier(this, nullptr /* slow_path */, nullptr /* continuation */);

372 
373   if (verified_inline_entry_label != nullptr) {
374     // Jump here from the scalarized entry points that already created the frame.
375     bind(*verified_inline_entry_label);
376   }
377 }
378 

379 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
380   if (breakAtEntry || VerifyFPU) {
381     // Verified Entry first instruction should be 5 bytes long for correct
382     // patching by patch_verified_entry().
383     //
384     // Breakpoint and VerifyFPU have one byte first instruction.
385     // Also first instruction will be one byte "push(rbp)" if stack banging
386     // code is not generated (see build_frame() above).
387     // For all these cases generate long instruction first.
388     fat_nop();
389   }
390   if (breakAtEntry) int3();
391   // build frame
392   IA32_ONLY( verify_FPU(0, "method_entry"); )
393 }
394 
395 int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature* ces, int frame_size_in_bytes, int bang_size_in_bytes, int sp_offset_for_orig_pc, Label& verified_inline_entry_label, bool is_inline_ro_entry) {
396   assert(InlineTypePassFieldsAsArgs, "sanity");
397   // Make sure there is enough stack space for this method's activation.
398   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
399   generate_stack_overflow_check(bang_size_in_bytes);
400 
401   GrowableArray<SigEntry>* sig    = ces->sig();
402   GrowableArray<SigEntry>* sig_cc = is_inline_ro_entry ? ces->sig_cc_ro() : ces->sig_cc();
403   VMRegPair* regs      = ces->regs();
404   VMRegPair* regs_cc   = is_inline_ro_entry ? ces->regs_cc_ro() : ces->regs_cc();
405   int args_on_stack    = ces->args_on_stack();
406   int args_on_stack_cc = is_inline_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc();
407 
408   assert(sig->length() <= sig_cc->length(), "Zero-sized inline class not allowed!");
409   BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length());
410   int args_passed = sig->length();
411   int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt);
412 
413   // Create a temp frame so we can call into the runtime. It must be properly set up to accommodate GC.
414   build_frame_helper(frame_size_in_bytes, sp_offset_for_orig_pc, 0, true, ces->c1_needs_stack_repair());
415 
416   // The runtime call might safepoint, make sure nmethod entry barrier is executed
417   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
418   // C1 code is not hot enough to micro optimize the nmethod entry barrier with an out-of-line stub
419   bs->nmethod_entry_barrier(this, nullptr /* slow_path */, nullptr /* continuation */);
420 
421   // FIXME -- call runtime only if we cannot in-line allocate all the incoming inline type args.
422   movptr(rbx, (intptr_t)(ces->method()));
423   if (is_inline_ro_entry) {
424     call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_inline_args_no_receiver_id)));
425   } else {
426     call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_inline_args_id)));
427   }
428   int rt_call_offset = offset();
429 
430   // Remove the temp frame
431   addptr(rsp, frame_size_in_bytes);
432   pop(rbp);
433 
434   // Check if we need to extend the stack for packing
435   int sp_inc = 0;
436   if (args_on_stack > args_on_stack_cc) {
437     sp_inc = extend_stack_for_inline_args(args_on_stack);
438   }
439 
440   shuffle_inline_args(true, is_inline_ro_entry, sig_cc,
441                       args_passed_cc, args_on_stack_cc, regs_cc, // from
442                       args_passed, args_on_stack, regs,          // to
443                       sp_inc, rax);
444 
445   // Create the real frame. Below jump will then skip over the stack banging and frame
446   // setup code in the verified_inline_entry (which has a different real_frame_size).
447   build_frame_helper(frame_size_in_bytes, sp_offset_for_orig_pc, sp_inc, false, ces->c1_needs_stack_repair());
448 
449   jmp(verified_inline_entry_label);
450   return rt_call_offset;
451 }
452 
453 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
454   // rbp, + 0: link
455   //     + 1: return address
456   //     + 2: argument with offset 0
457   //     + 3: argument with offset 1
458   //     + 4: ...
459 
460   movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
461 }
462 
463 #ifndef PRODUCT
464 
465 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
466   if (!VerifyOops) return;
467   verify_oop_addr(Address(rsp, stack_offset));
468 }
469 
470 void C1_MacroAssembler::verify_not_null_oop(Register r) {
471   if (!VerifyOops) return;
472   Label not_null;
< prev index next >