1 /*
  2  * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "precompiled.hpp"
 27 #include "asm/macroAssembler.inline.hpp"
 28 #include "c1/c1_MacroAssembler.hpp"
 29 #include "c1/c1_Runtime1.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 #include "utilities/align.hpp"
 40 #include "utilities/macros.hpp"
 41 #include "utilities/powerOfTwo.hpp"
 42 
 43 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
 44   const Register temp_reg = R12_scratch2;
 45   Label Lmiss;
 46 
 47   verify_oop(receiver, FILE_AND_LINE);
 48   load_klass_check_null(temp_reg, receiver, &Lmiss);
 49 
 50   if (TrapBasedICMissChecks && TrapBasedNullChecks) {
 51     trap_ic_miss_check(temp_reg, iCache);
 52   } else {
 53     Label Lok;
 54     cmpd(CCR0, temp_reg, iCache);
 55     beq(CCR0, Lok);
 56     bind(Lmiss);
 57     //load_const_optimized(temp_reg, SharedRuntime::get_ic_miss_stub(), R0);
 58     calculate_address_from_global_toc(temp_reg, SharedRuntime::get_ic_miss_stub(), true, true, false);
 59     mtctr(temp_reg);
 60     bctr();
 61     align(32, 12);
 62     bind(Lok);
 63   }
 64 }
 65 
 66 
 67 void C1_MacroAssembler::explicit_null_check(Register base) {
 68   Unimplemented();
 69 }
 70 
 71 
 72 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes, int max_monitors) {
 73   // Avoid stack bang as first instruction. It may get overwritten by patch_verified_entry.
 74   const Register return_pc = R20;
 75   mflr(return_pc);
 76 
 77   // Make sure there is enough stack space for this method's activation.
 78   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
 79   generate_stack_overflow_check(bang_size_in_bytes);
 80 
 81   std(return_pc, _abi0(lr), R1_SP);     // SP->lr = return_pc
 82   push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes
 83 
 84   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
 85   bs->nmethod_entry_barrier(this, R20);
 86 }
 87 
 88 
 89 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
 90   if (breakAtEntry) illtrap();
 91   // build frame
 92 }
 93 
 94 
 95 void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) {
 96   assert_different_registers(Rmark, Roop, Rbox, Rscratch);
 97 
 98   Label done, cas_failed, slow_int;
 99 
100   // The following move must be the first instruction of emitted since debug
101   // information may be generated for it.
102   // Load object header.
103   ld(Rmark, oopDesc::mark_offset_in_bytes(), Roop);
104 
105   verify_oop(Roop, FILE_AND_LINE);
106 
107   // Save object being locked into the BasicObjectLock...
108   std(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);
109 
110   if (DiagnoseSyncOnValueBasedClasses != 0) {
111     load_klass(Rscratch, Roop);
112     lwz(Rscratch, in_bytes(Klass::access_flags_offset()), Rscratch);
113     testbitdi(CCR0, R0, Rscratch, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
114     bne(CCR0, slow_int);
115   }
116 
117   // ... and mark it unlocked.
118   ori(Rmark, Rmark, markWord::unlocked_value);
119 
120   // Save unlocked object header into the displaced header location on the stack.
121   std(Rmark, BasicLock::displaced_header_offset_in_bytes(), Rbox);
122 
123   // Compare object markWord with Rmark and if equal exchange Rscratch with object markWord.
124   assert(oopDesc::mark_offset_in_bytes() == 0, "cas must take a zero displacement");
125   cmpxchgd(/*flag=*/CCR0,
126            /*current_value=*/Rscratch,
127            /*compare_value=*/Rmark,
128            /*exchange_value=*/Rbox,
129            /*where=*/Roop/*+0==mark_offset_in_bytes*/,
130            MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
131            MacroAssembler::cmpxchgx_hint_acquire_lock(),
132            noreg,
133            &cas_failed,
134            /*check without membar and ldarx first*/true);
135   // If compare/exchange succeeded we found an unlocked object and we now have locked it
136   // hence we are done.
137   b(done);
138 
139   bind(slow_int);
140   b(slow_case); // far
141 
142   bind(cas_failed);
143   // We did not find an unlocked object so see if this is a recursive case.
144   sub(Rscratch, Rscratch, R1_SP);
145   load_const_optimized(R0, (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
146   and_(R0/*==0?*/, Rscratch, R0);
147   std(R0/*==0, perhaps*/, BasicLock::displaced_header_offset_in_bytes(), Rbox);
148   bne(CCR0, slow_int);
149 
150   bind(done);
151 
152   inc_held_monitor_count(Rmark /*tmp*/);
153 }
154 
155 
156 void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
157   assert_different_registers(Rmark, Roop, Rbox);
158 
159   Label slow_int, done;
160 
161   Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
162   assert(mark_addr.disp() == 0, "cas must take a zero displacement");
163 
164   // Test first if it is a fast recursive unlock.
165   ld(Rmark, BasicLock::displaced_header_offset_in_bytes(), Rbox);
166   cmpdi(CCR0, Rmark, 0);
167   beq(CCR0, done);
168 
169   // Load object.
170   ld(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);
171   verify_oop(Roop, FILE_AND_LINE);
172 
173   // Check if it is still a light weight lock, this is is true if we see
174   // the stack address of the basicLock in the markWord of the object.
175   cmpxchgd(/*flag=*/CCR0,
176            /*current_value=*/R0,
177            /*compare_value=*/Rbox,
178            /*exchange_value=*/Rmark,
179            /*where=*/Roop,
180            MacroAssembler::MemBarRel,
181            MacroAssembler::cmpxchgx_hint_release_lock(),
182            noreg,
183            &slow_int);
184   b(done);
185   bind(slow_int);
186   b(slow_case); // far
187 
188   // Done
189   bind(done);
190 
191   dec_held_monitor_count(Rmark /*tmp*/);
192 }
193 
194 
195 void C1_MacroAssembler::try_allocate(
196   Register obj,                        // result: pointer to object after successful allocation
197   Register var_size_in_bytes,          // object size in bytes if unknown at compile time; invalid otherwise
198   int      con_size_in_bytes,          // object size in bytes if   known at compile time
199   Register t1,                         // temp register, must be global register for incr_allocated_bytes
200   Register t2,                         // temp register
201   Label&   slow_case                   // continuation point if fast allocation fails
202 ) {
203   if (UseTLAB) {
204     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
205   } else {
206     b(slow_case);
207   }
208 }
209 
210 
211 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
212   assert_different_registers(obj, klass, len, t1, t2);
213   load_const_optimized(t1, (intx)markWord::prototype().value());
214   std(t1, oopDesc::mark_offset_in_bytes(), obj);
215   store_klass(obj, klass);
216   if (len->is_valid()) {
217     stw(len, arrayOopDesc::length_offset_in_bytes(), obj);
218   } else if (UseCompressedClassPointers) {
219     // Otherwise length is in the class gap.
220     store_klass_gap(obj);
221   }
222 }
223 
224 
225 void C1_MacroAssembler::initialize_body(Register base, Register index) {
226   assert_different_registers(base, index);
227   srdi(index, index, LogBytesPerWord);
228   clear_memory_doubleword(base, index);
229 }
230 
231 void C1_MacroAssembler::initialize_body(Register obj, Register tmp1, Register tmp2,
232                                         int obj_size_in_bytes, int hdr_size_in_bytes) {
233   const int index = (obj_size_in_bytes - hdr_size_in_bytes) / HeapWordSize;
234 
235   // 2x unrolled loop is shorter with more than 9 HeapWords.
236   if (index <= 9) {
237     clear_memory_unrolled(obj, index, R0, hdr_size_in_bytes);
238   } else {
239     const Register base_ptr = tmp1,
240                    cnt_dwords = tmp2;
241 
242     addi(base_ptr, obj, hdr_size_in_bytes); // Compute address of first element.
243     clear_memory_doubleword(base_ptr, cnt_dwords, R0, index);
244   }
245 }
246 
247 void C1_MacroAssembler::allocate_object(
248   Register obj,                        // result: pointer to object after successful allocation
249   Register t1,                         // temp register
250   Register t2,                         // temp register
251   Register t3,                         // temp register
252   int      hdr_size,                   // object header size in words
253   int      obj_size,                   // object size in words
254   Register klass,                      // object klass
255   Label&   slow_case                   // continuation point if fast allocation fails
256 ) {
257   assert_different_registers(obj, t1, t2, t3, klass);
258 
259   // allocate space & initialize header
260   if (!is_simm16(obj_size * wordSize)) {
261     // Would need to use extra register to load
262     // object size => go the slow case for now.
263     b(slow_case);
264     return;
265   }
266   try_allocate(obj, noreg, obj_size * wordSize, t2, t3, slow_case);
267 
268   initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2);
269 }
270 
271 void C1_MacroAssembler::initialize_object(
272   Register obj,                        // result: pointer to object after successful allocation
273   Register klass,                      // object klass
274   Register var_size_in_bytes,          // object size in bytes if unknown at compile time; invalid otherwise
275   int      con_size_in_bytes,          // object size in bytes if   known at compile time
276   Register t1,                         // temp register
277   Register t2                          // temp register
278   ) {
279   const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
280 
281   initialize_header(obj, klass, noreg, t1, t2);
282 
283 #ifdef ASSERT
284   {
285     lwz(t1, in_bytes(Klass::layout_helper_offset()), klass);
286     if (var_size_in_bytes != noreg) {
287       cmpw(CCR0, t1, var_size_in_bytes);
288     } else {
289       cmpwi(CCR0, t1, con_size_in_bytes);
290     }
291     asm_assert_eq("bad size in initialize_object");
292   }
293 #endif
294 
295   // Initialize body.
296   if (var_size_in_bytes != noreg) {
297     // Use a loop.
298     addi(t1, obj, hdr_size_in_bytes);                // Compute address of first element.
299     addi(t2, var_size_in_bytes, -hdr_size_in_bytes); // Compute size of body.
300     initialize_body(t1, t2);
301   } else if (con_size_in_bytes > hdr_size_in_bytes) {
302     // Use a loop.
303     initialize_body(obj, t1, t2, con_size_in_bytes, hdr_size_in_bytes);
304   }
305 
306   if (CURRENT_ENV->dtrace_alloc_probes()) {
307     Unimplemented();
308 //    assert(obj == O0, "must be");
309 //    call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
310 //         relocInfo::runtime_call_type);
311   }
312 
313   verify_oop(obj, FILE_AND_LINE);
314 }
315 
316 
317 void C1_MacroAssembler::allocate_array(
318   Register obj,                        // result: pointer to array after successful allocation
319   Register len,                        // array length
320   Register t1,                         // temp register
321   Register t2,                         // temp register
322   Register t3,                         // temp register
323   int      hdr_size,                   // object header size in words
324   int      elt_size,                   // element size in bytes
325   Register klass,                      // object klass
326   Label&   slow_case                   // continuation point if fast allocation fails
327 ) {
328   assert_different_registers(obj, len, t1, t2, t3, klass);
329 
330   // Determine alignment mask.
331   assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work");
332   int log2_elt_size = exact_log2(elt_size);
333 
334   // Check for negative or excessive length.
335   size_t max_length = max_array_allocation_length >> log2_elt_size;
336   if (UseTLAB) {
337     size_t max_tlab = align_up(ThreadLocalAllocBuffer::max_size() >> log2_elt_size, 64*K);
338     if (max_tlab < max_length) { max_length = max_tlab; }
339   }
340   load_const_optimized(t1, max_length);
341   cmpld(CCR0, len, t1);
342   bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::greater), slow_case);
343 
344   // compute array size
345   // note: If 0 <= len <= max_length, len*elt_size + header + alignment is
346   //       smaller or equal to the largest integer; also, since top is always
347   //       aligned, we can do the alignment here instead of at the end address
348   //       computation.
349   const Register arr_size = t1;
350   Register arr_len_in_bytes = len;
351   if (elt_size != 1) {
352     sldi(t1, len, log2_elt_size);
353     arr_len_in_bytes = t1;
354   }
355   addi(arr_size, arr_len_in_bytes, hdr_size * wordSize + MinObjAlignmentInBytesMask); // Add space for header & alignment.
356   clrrdi(arr_size, arr_size, LogMinObjAlignmentInBytes);                              // Align array size.
357 
358   // Allocate space & initialize header.
359   try_allocate(obj, arr_size, 0, t2, t3, slow_case);
360   initialize_header(obj, klass, len, t2, t3);
361 
362   // Initialize body.
363   const Register base  = t2;
364   const Register index = t3;
365   addi(base, obj, hdr_size * wordSize);               // compute address of first element
366   addi(index, arr_size, -(hdr_size * wordSize));      // compute index = number of bytes to clear
367   initialize_body(base, index);
368 
369   if (CURRENT_ENV->dtrace_alloc_probes()) {
370     Unimplemented();
371     //assert(obj == O0, "must be");
372     //call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
373     //     relocInfo::runtime_call_type);
374   }
375 
376   verify_oop(obj, FILE_AND_LINE);
377 }
378 
379 
380 #ifndef PRODUCT
381 
382 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
383   verify_oop_addr((RegisterOrConstant)stack_offset, R1_SP, "broken oop in stack slot");
384 }
385 
386 void C1_MacroAssembler::verify_not_null_oop(Register r) {
387   Label not_null;
388   cmpdi(CCR0, r, 0);
389   bne(CCR0, not_null);
390   stop("non-null oop required");
391   bind(not_null);
392   verify_oop(r, FILE_AND_LINE);
393 }
394 
395 #endif // PRODUCT
396 
397 void C1_MacroAssembler::null_check(Register r, Label* Lnull) {
398   if (TrapBasedNullChecks) { // SIGTRAP based
399     trap_null_check(r);
400   } else { // explicit
401     //const address exception_entry = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
402     assert(Lnull != NULL, "must have Label for explicit check");
403     cmpdi(CCR0, r, 0);
404     bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::equal), *Lnull);
405   }
406 }
407 
408 address C1_MacroAssembler::call_c_with_frame_resize(address dest, int frame_resize) {
409   if (frame_resize) { resize_frame(-frame_resize, R0); }
410 #if defined(ABI_ELFv2)
411   address return_pc = call_c(dest, relocInfo::runtime_call_type);
412 #else
413   address return_pc = call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, dest), relocInfo::runtime_call_type);
414 #endif
415   if (frame_resize) { resize_frame(frame_resize, R0); }
416   return return_pc;
417 }