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_MacroAssembler.hpp"
27 #include "c1/c1_Runtime1.hpp"
28 #include "gc/shared/barrierSet.hpp"
29 #include "gc/shared/barrierSetAssembler.hpp"
30 #include "gc/shared/collectedHeap.hpp"
31 #include "gc/shared/tlab_globals.hpp"
32 #include "interpreter/interpreter.hpp"
33 #include "oops/arrayOop.hpp"
34 #include "oops/markWord.hpp"
35 #include "runtime/basicLock.hpp"
36 #include "runtime/os.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #include "runtime/stubRoutines.hpp"
39
40 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
41 const Register rklass_decode_tmp = LP64_ONLY(rscratch1) NOT_LP64(noreg);
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(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
46 Label done;
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_in_bytes()), obj);
53
54 null_check_offset = offset();
55
56 if (DiagnoseSyncOnValueBasedClasses != 0) {
57 load_klass(hdr, obj, rklass_decode_tmp);
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 // and mark it as unlocked
66 orptr(hdr, markWord::unlocked_value);
67 // save unlocked object header into the displaced header location on the stack
68 movptr(Address(disp_hdr, 0), hdr);
69 // test if object header is still the same (i.e. unlocked), and if so, store the
70 // displaced header address in the object header - if it is not the same, get the
71 // object header instead
72 MacroAssembler::lock(); // must be immediately before cmpxchg!
73 cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
74 // if the object header was the same, we're done
75 jcc(Assembler::equal, done);
76 // if the object header was not the same, it is now in the hdr register
77 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
78 //
79 // 1) (hdr & aligned_mask) == 0
80 // 2) rsp <= hdr
81 // 3) hdr <= rsp + page_size
82 //
83 // these 3 tests can be done by evaluating the following expression:
84 //
85 // (hdr - rsp) & (aligned_mask - page_size)
86 //
125 // we do unlocking via runtime call
126 jcc(Assembler::notEqual, slow_case);
127 // done
128 bind(done);
129 }
130
131
132 // Defines obj, preserves var_size_in_bytes
133 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
134 if (UseTLAB) {
135 tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
136 } else {
137 eden_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
138 }
139 }
140
141
142 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
143 assert_different_registers(obj, klass, len);
144 Register tmp_encode_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
145 // This assumes that all prototype bits fit in an int32_t
146 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markWord::prototype().value());
147 #ifdef _LP64
148 if (UseCompressedClassPointers) { // Take care not to kill klass
149 movptr(t1, klass);
150 encode_klass_not_null(t1, tmp_encode_klass);
151 movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
152 } else
153 #endif
154 {
155 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
156 }
157
158 if (len->is_valid()) {
159 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
160 }
161 #ifdef _LP64
162 else if (UseCompressedClassPointers) {
163 xorptr(t1, t1);
164 store_klass_gap(obj, t1);
165 }
166 #endif
281 // explicit NULL check not needed since load from [klass_offset] causes a trap
282 // check against inline cache
283 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
284 int start_offset = offset();
285 Register tmp_load_klass = LP64_ONLY(rscratch2) NOT_LP64(noreg);
286
287 if (UseCompressedClassPointers) {
288 load_klass(rscratch1, receiver, tmp_load_klass);
289 cmpptr(rscratch1, iCache);
290 } else {
291 cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
292 }
293 // if icache check fails, then jump to runtime routine
294 // Note: RECEIVER must still contain the receiver!
295 jump_cc(Assembler::notEqual,
296 RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
297 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
298 assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
299 }
300
301
302 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
303 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
304 // Make sure there is enough stack space for this method's activation.
305 // Note that we do this before doing an enter(). This matches the
306 // ordering of C2's stack overflow check / rsp decrement and allows
307 // the SharedRuntime stack overflow handling to be consistent
308 // between the two compilers.
309 generate_stack_overflow_check(bang_size_in_bytes);
310
311 push(rbp);
312 if (PreserveFramePointer) {
313 mov(rbp, rsp);
314 }
315 #if !defined(_LP64) && defined(COMPILER2)
316 if (UseSSE < 2 && !CompilerConfig::is_c1_only_no_jvmci()) {
317 // c2 leaves fpu stack dirty. Clean it on entry
318 empty_FPU_stack();
319 }
320 #endif // !_LP64 && COMPILER2
321 decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
322
323 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
324 bs->nmethod_entry_barrier(this);
325 }
326
327
328 void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
329 increment(rsp, frame_size_in_bytes); // Does not emit code for frame_size == 0
330 pop(rbp);
331 }
332
333
334 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
335 if (breakAtEntry || VerifyFPU) {
336 // Verified Entry first instruction should be 5 bytes long for correct
337 // patching by patch_verified_entry().
338 //
339 // Breakpoint and VerifyFPU have one byte first instruction.
340 // Also first instruction will be one byte "push(rbp)" if stack banging
341 // code is not generated (see build_frame() above).
342 // For all these cases generate long instruction first.
343 fat_nop();
344 }
345 if (breakAtEntry) int3();
346 // build frame
347 IA32_ONLY( verify_FPU(0, "method_entry"); )
348 }
349
350 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
351 // rbp, + 0: link
352 // + 1: return address
353 // + 2: argument with offset 0
354 // + 3: argument with offset 1
355 // + 4: ...
356
357 movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
358 }
359
360 #ifndef PRODUCT
361
362 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
363 if (!VerifyOops) return;
364 verify_oop_addr(Address(rsp, stack_offset));
365 }
366
367 void C1_MacroAssembler::verify_not_null_oop(Register r) {
368 if (!VerifyOops) return;
369 Label not_null;
|
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_MacroAssembler.hpp"
27 #include "c1/c1_Runtime1.hpp"
28 #include "gc/shared/barrierSet.hpp"
29 #include "gc/shared/barrierSetAssembler.hpp"
30 #include "gc/shared/collectedHeap.hpp"
31 #include "gc/shared/tlab_globals.hpp"
32 #include "interpreter/interpreter.hpp"
33 #include "oops/arrayOop.hpp"
34 #include "oops/markWord.hpp"
35 #include "runtime/basicLock.hpp"
36 #include "runtime/frame.inline.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, Label& slow_case) {
42 const Register rklass_decode_tmp = LP64_ONLY(rscratch1) NOT_LP64(noreg);
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(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
47 Label done;
48 int null_check_offset = -1;
49
50 verify_oop(obj);
51
52 // save object being locked into the BasicObjectLock
53 movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
54
55 null_check_offset = offset();
56
57 if (DiagnoseSyncOnValueBasedClasses != 0) {
58 load_klass(hdr, obj, rklass_decode_tmp);
59 movl(hdr, Address(hdr, Klass::access_flags_offset()));
60 testl(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
61 jcc(Assembler::notZero, slow_case);
62 }
63
64 // Load object header
65 movptr(hdr, Address(obj, hdr_offset));
66 // and mark it as unlocked
67 orptr(hdr, markWord::unlocked_value);
68 if (EnableValhalla) {
69 // Mask inline_type bit such that we go to the slow path if object is an inline type
70 andptr(hdr, ~((int) markWord::inline_type_bit_in_place));
71 }
72 // save unlocked object header into the displaced header location on the stack
73 movptr(Address(disp_hdr, 0), hdr);
74 // test if object header is still the same (i.e. unlocked), and if so, store the
75 // displaced header address in the object header - if it is not the same, get the
76 // object header instead
77 MacroAssembler::lock(); // must be immediately before cmpxchg!
78 cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
79 // if the object header was the same, we're done
80 jcc(Assembler::equal, done);
81 // if the object header was not the same, it is now in the hdr register
82 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
83 //
84 // 1) (hdr & aligned_mask) == 0
85 // 2) rsp <= hdr
86 // 3) hdr <= rsp + page_size
87 //
88 // these 3 tests can be done by evaluating the following expression:
89 //
90 // (hdr - rsp) & (aligned_mask - page_size)
91 //
130 // we do unlocking via runtime call
131 jcc(Assembler::notEqual, slow_case);
132 // done
133 bind(done);
134 }
135
136
137 // Defines obj, preserves var_size_in_bytes
138 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
139 if (UseTLAB) {
140 tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
141 } else {
142 eden_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
143 }
144 }
145
146
147 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
148 assert_different_registers(obj, klass, len);
149 Register tmp_encode_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
150 if (EnableValhalla) {
151 // Need to copy markWord::prototype header for klass
152 assert_different_registers(obj, klass, len, t1, t2);
153 movptr(t1, Address(klass, Klass::prototype_header_offset()));
154 movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
155 } else {
156 // This assumes that all prototype bits fit in an int32_t
157 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markWord::prototype().value());
158 }
159 #ifdef _LP64
160 if (UseCompressedClassPointers) { // Take care not to kill klass
161 movptr(t1, klass);
162 encode_klass_not_null(t1, tmp_encode_klass);
163 movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
164 } else
165 #endif
166 {
167 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
168 }
169
170 if (len->is_valid()) {
171 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
172 }
173 #ifdef _LP64
174 else if (UseCompressedClassPointers) {
175 xorptr(t1, t1);
176 store_klass_gap(obj, t1);
177 }
178 #endif
293 // explicit NULL check not needed since load from [klass_offset] causes a trap
294 // check against inline cache
295 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
296 int start_offset = offset();
297 Register tmp_load_klass = LP64_ONLY(rscratch2) NOT_LP64(noreg);
298
299 if (UseCompressedClassPointers) {
300 load_klass(rscratch1, receiver, tmp_load_klass);
301 cmpptr(rscratch1, iCache);
302 } else {
303 cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
304 }
305 // if icache check fails, then jump to runtime routine
306 // Note: RECEIVER must still contain the receiver!
307 jump_cc(Assembler::notEqual,
308 RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
309 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
310 assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
311 }
312
313 void C1_MacroAssembler::build_frame_helper(int frame_size_in_bytes, int sp_inc, bool needs_stack_repair) {
314 push(rbp);
315 if (PreserveFramePointer) {
316 mov(rbp, rsp);
317 }
318 #if !defined(_LP64) && defined(COMPILER2)
319 if (UseSSE < 2 && !CompilerConfig::is_c1_only_no_jvmci()) {
320 // c2 leaves fpu stack dirty. Clean it on entry
321 empty_FPU_stack();
322 }
323 #endif // !_LP64 && COMPILER2
324 decrement(rsp, frame_size_in_bytes);
325
326 if (needs_stack_repair) {
327 // Save stack increment (also account for fixed framesize and rbp)
328 assert((sp_inc & (StackAlignmentInBytes-1)) == 0, "stack increment not aligned");
329 int real_frame_size = sp_inc + frame_size_in_bytes + wordSize;
330 movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
331 }
332 }
333
334 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) {
335 if (has_scalarized_args) {
336 // Initialize orig_pc to detect deoptimization during buffering in the entry points
337 movptr(Address(rsp, sp_offset_for_orig_pc - frame_size_in_bytes - wordSize), 0);
338 }
339 if (!needs_stack_repair && verified_inline_entry_label != NULL) {
340 bind(*verified_inline_entry_label);
341 }
342 // Make sure there is enough stack space for this method's activation.
343 // Note that we do this before doing an enter(). This matches the
344 // ordering of C2's stack overflow check / rsp decrement and allows
345 // the SharedRuntime stack overflow handling to be consistent
346 // between the two compilers.
347 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
348 generate_stack_overflow_check(bang_size_in_bytes);
349
350 build_frame_helper(frame_size_in_bytes, 0, needs_stack_repair);
351
352 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
353 bs->nmethod_entry_barrier(this);
354
355 if (needs_stack_repair && verified_inline_entry_label != NULL) {
356 // Jump here from the scalarized entry points that require additional stack space
357 // for packing scalarized arguments and therefore already created the frame.
358 bind(*verified_inline_entry_label);
359 }
360 }
361
362 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
363 if (breakAtEntry || VerifyFPU) {
364 // Verified Entry first instruction should be 5 bytes long for correct
365 // patching by patch_verified_entry().
366 //
367 // Breakpoint and VerifyFPU have one byte first instruction.
368 // Also first instruction will be one byte "push(rbp)" if stack banging
369 // code is not generated (see build_frame() above).
370 // For all these cases generate long instruction first.
371 fat_nop();
372 }
373 if (breakAtEntry) int3();
374 // build frame
375 IA32_ONLY( verify_FPU(0, "method_entry"); )
376 }
377
378 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) {
379 assert(InlineTypePassFieldsAsArgs, "sanity");
380 // Make sure there is enough stack space for this method's activation.
381 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
382 generate_stack_overflow_check(bang_size_in_bytes);
383
384 GrowableArray<SigEntry>* sig = &ces->sig();
385 GrowableArray<SigEntry>* sig_cc = is_inline_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc();
386 VMRegPair* regs = ces->regs();
387 VMRegPair* regs_cc = is_inline_ro_entry ? ces->regs_cc_ro() : ces->regs_cc();
388 int args_on_stack = ces->args_on_stack();
389 int args_on_stack_cc = is_inline_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc();
390
391 assert(sig->length() <= sig_cc->length(), "Zero-sized inline class not allowed!");
392 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length());
393 int args_passed = sig->length();
394 int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt);
395
396 // Check if we need to extend the stack for packing
397 int sp_inc = 0;
398 if (args_on_stack > args_on_stack_cc) {
399 sp_inc = extend_stack_for_inline_args(args_on_stack);
400 }
401
402 // Create a temp frame so we can call into the runtime. It must be properly set up to accommodate GC.
403 build_frame_helper(frame_size_in_bytes, sp_inc, ces->c1_needs_stack_repair());
404
405 // Initialize orig_pc to detect deoptimization during buffering in below runtime call
406 movptr(Address(rsp, sp_offset_for_orig_pc), 0);
407
408 // The runtime call might safepoint, make sure nmethod entry barrier is executed
409 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
410 bs->nmethod_entry_barrier(this);
411
412 // FIXME -- call runtime only if we cannot in-line allocate all the incoming inline type args.
413 movptr(rbx, (intptr_t)(ces->method()));
414 if (is_inline_ro_entry) {
415 call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_inline_args_no_receiver_id)));
416 } else {
417 call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_inline_args_id)));
418 }
419 int rt_call_offset = offset();
420
421 // Remove the temp frame
422 addptr(rsp, frame_size_in_bytes);
423 pop(rbp);
424
425 shuffle_inline_args(true, is_inline_ro_entry, sig_cc,
426 args_passed_cc, args_on_stack_cc, regs_cc, // from
427 args_passed, args_on_stack, regs, // to
428 sp_inc, rax);
429
430 if (ces->c1_needs_stack_repair()) {
431 // Create the real frame. Below jump will then skip over the stack banging and frame
432 // setup code in the verified_inline_entry (which has a different real_frame_size).
433 build_frame_helper(frame_size_in_bytes, sp_inc, true);
434 }
435
436 jmp(verified_inline_entry_label);
437 return rt_call_offset;
438 }
439
440 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
441 // rbp, + 0: link
442 // + 1: return address
443 // + 2: argument with offset 0
444 // + 3: argument with offset 1
445 // + 4: ...
446
447 movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
448 }
449
450 #ifndef PRODUCT
451
452 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
453 if (!VerifyOops) return;
454 verify_oop_addr(Address(rsp, stack_offset));
455 }
456
457 void C1_MacroAssembler::verify_not_null_oop(Register r) {
458 if (!VerifyOops) return;
459 Label not_null;
|