1 /*
2 * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2016, 2023 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/barrierSet.hpp"
31 #include "gc/shared/barrierSetAssembler.hpp"
32 #include "gc/shared/collectedHeap.hpp"
33 #include "gc/shared/tlab_globals.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "oops/arrayOop.hpp"
36 #include "oops/markWord.hpp"
37 #include "runtime/basicLock.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/sharedRuntime.hpp"
40 #include "runtime/stubRoutines.hpp"
41 #include "utilities/macros.hpp"
42
43 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
44 Label ic_miss, ic_hit;
45 verify_oop(receiver, FILE_AND_LINE);
46 int klass_offset = oopDesc::klass_offset_in_bytes();
47
48 if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) {
49 if (VM_Version::has_CompareBranch()) {
50 z_cgij(receiver, 0, Assembler::bcondEqual, ic_miss);
51 } else {
52 z_ltgr(receiver, receiver);
53 z_bre(ic_miss);
54 }
55 }
56
57 compare_klass_ptr(iCache, klass_offset, receiver, false);
58 z_bre(ic_hit);
59
60 // If icache check fails, then jump to runtime routine.
61 // Note: RECEIVER must still contain the receiver!
62 load_const_optimized(Z_R1_scratch, AddressLiteral(SharedRuntime::get_ic_miss_stub()));
63 z_br(Z_R1_scratch);
64 align(CodeEntryAlignment);
65 bind(ic_hit);
66 }
67
68 void C1_MacroAssembler::explicit_null_check(Register base) {
69 ShouldNotCallThis(); // unused
70 }
71
72 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
73 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
74 generate_stack_overflow_check(bang_size_in_bytes);
75 save_return_pc();
76 push_frame(frame_size_in_bytes);
77
78 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
79 bs->nmethod_entry_barrier(this);
80 }
81
82 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
83 if (breakAtEntry) z_illtrap(0xC1);
84 }
85
86 void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
87 const int hdr_offset = oopDesc::mark_offset_in_bytes();
88
89 const Register tmp = Z_R1_scratch;
90
91 assert_different_registers(Rmark, Roop, Rbox, tmp);
92
93 verify_oop(Roop, FILE_AND_LINE);
94
95 // Load object header.
96 z_lg(Rmark, Address(Roop, hdr_offset));
97
98 // Save object being locked into the BasicObjectLock...
99 z_stg(Roop, Address(Rbox, BasicObjectLock::obj_offset()));
100
101 if (DiagnoseSyncOnValueBasedClasses != 0) {
102 load_klass(tmp, Roop);
103 testbit(Address(tmp, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
104 branch_optimized(Assembler::bcondAllOne, slow_case);
105 }
106
107 assert(LockingMode != LM_MONITOR, "LM_MONITOR is already handled, by emit_lock()");
108
109 if (LockingMode == LM_LIGHTWEIGHT) {
110 lightweight_lock(Roop, Rmark, tmp, slow_case);
111 } else if (LockingMode == LM_LEGACY) {
112 NearLabel done;
113 // and mark it as unlocked.
114 z_oill(Rmark, markWord::unlocked_value);
115 // Save unlocked object header into the displaced header location on the stack.
116 z_stg(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));
117 // Test if object header is still the same (i.e. unlocked), and if so, store the
118 // displaced header address in the object header. If it is not the same, get the
119 // object header instead.
120 z_csg(Rmark, Rbox, hdr_offset, Roop);
121 // If the object header was the same, we're done.
122 branch_optimized(Assembler::bcondEqual, done);
123 // If the object header was not the same, it is now in the Rmark register.
124 // => Test if it is a stack pointer into the same stack (recursive locking), i.e.:
125 //
126 // 1) (Rmark & markWord::lock_mask_in_place) == 0
127 // 2) rsp <= Rmark
128 // 3) Rmark <= rsp + page_size
129 //
130 // These 3 tests can be done by evaluating the following expression:
131 //
132 // (Rmark - Z_SP) & (~(page_size-1) | markWord::lock_mask_in_place)
133 //
134 // assuming both the stack pointer and page_size have their least
135 // significant 2 bits cleared and page_size is a power of 2
136 z_sgr(Rmark, Z_SP);
137
138 load_const_optimized(Z_R0_scratch, (~(os::vm_page_size() - 1) | markWord::lock_mask_in_place));
139 z_ngr(Rmark, Z_R0_scratch); // AND sets CC (result eq/ne 0).
140 // For recursive locking, the result is zero. => Save it in the displaced header
141 // location (null in the displaced Rmark location indicates recursive locking).
142 z_stg(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));
143 // Otherwise we don't care about the result and handle locking via runtime call.
144 branch_optimized(Assembler::bcondNotZero, slow_case);
145 // done
146 bind(done);
147 }
148 }
149
150 void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
151 const int hdr_offset = oopDesc::mark_offset_in_bytes();
152
153 assert_different_registers(Rmark, Roop, Rbox);
154
155 NearLabel done;
156
157 if (LockingMode != LM_LIGHTWEIGHT) {
158 // Load displaced header.
159 z_ltg(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));
160 // If the loaded Rmark is null we had recursive locking, and we are done.
161 z_bre(done);
162 }
163
164 // Load object.
165 z_lg(Roop, Address(Rbox, BasicObjectLock::obj_offset()));
166 verify_oop(Roop, FILE_AND_LINE);
167
168 if (LockingMode == LM_LIGHTWEIGHT) {
169 const Register tmp = Z_R1_scratch;
170 z_lg(Rmark, Address(Roop, hdr_offset));
171 z_lgr(tmp, Rmark);
172 z_nill(tmp, markWord::monitor_value);
173 branch_optimized(Assembler::bcondNotZero, slow_case);
174 lightweight_unlock(Roop, Rmark, tmp, slow_case);
175 } else if (LockingMode == LM_LEGACY) {
176 // Test if object header is pointing to the displaced header, and if so, restore
177 // the displaced header in the object. If the object header is not pointing to
178 // the displaced header, get the object header instead.
179 z_csg(Rbox, Rmark, hdr_offset, Roop);
180 // If the object header was not pointing to the displaced header,
181 // we do unlocking via runtime call.
182 branch_optimized(Assembler::bcondNotEqual, slow_case);
183 }
184 // done
185 bind(done);
186 }
187
188 void C1_MacroAssembler::try_allocate(
189 Register obj, // result: Pointer to object after successful allocation.
190 Register var_size_in_bytes, // Object size in bytes if unknown at compile time; invalid otherwise.
191 int con_size_in_bytes, // Object size in bytes if known at compile time.
192 Register t1, // Temp register: Must be global register for incr_allocated_bytes.
193 Label& slow_case // Continuation point if fast allocation fails.
194 ) {
195 if (UseTLAB) {
196 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
197 } else {
198 // Allocation in shared Eden not implemented, because sapjvm allocation trace does not allow it.
199 z_brul(slow_case);
200 }
201 }
202
203 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register Rzero, Register t1) {
204 assert_different_registers(obj, klass, len, t1, Rzero);
205 // This assumes that all prototype bits fit in an int32_t.
206 load_const_optimized(t1, (intx)markWord::prototype().value());
207 z_stg(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
208
209 if (len->is_valid()) {
210 // Length will be in the klass gap, if one exists.
211 z_st(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
212 } else if (UseCompressedClassPointers) {
213 store_klass_gap(Rzero, obj); // Zero klass gap for compressed oops.
214 }
215 store_klass(klass, obj, t1);
216 }
217
218 void C1_MacroAssembler::initialize_body(Register objectFields, Register len_in_bytes, Register Rzero) {
219 Label done;
220 assert_different_registers(objectFields, len_in_bytes, Rzero);
221
222 // Initialize object fields.
223 // See documentation for MVCLE instruction!!!
224 assert(objectFields->encoding()%2==0, "objectFields must be an even register");
225 assert(len_in_bytes->encoding() == (objectFields->encoding()+1), "objectFields and len_in_bytes must be a register pair");
226 assert(Rzero->encoding()%2==1, "Rzero must be an odd register");
227
228 // Use Rzero as src length, then mvcle will copy nothing
229 // and fill the object with the padding value 0.
230 move_long_ext(objectFields, as_Register(Rzero->encoding()-1), 0);
231 bind(done);
232 }
233
234 void C1_MacroAssembler::allocate_object(
235 Register obj, // Result: pointer to object after successful allocation.
236 Register t1, // temp register
237 Register t2, // temp register: Must be a global register for try_allocate.
238 int hdr_size, // object header size in words
239 int obj_size, // object size in words
240 Register klass, // object klass
241 Label& slow_case // Continuation point if fast allocation fails.
242 ) {
243 assert_different_registers(obj, t1, t2, klass);
244
245 // Allocate space and initialize header.
246 try_allocate(obj, noreg, obj_size * wordSize, t1, slow_case);
247
248 initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2);
249 }
250
251 void C1_MacroAssembler::initialize_object(
252 Register obj, // result: Pointer to object after successful allocation.
253 Register klass, // object klass
254 Register var_size_in_bytes, // Object size in bytes if unknown at compile time; invalid otherwise.
255 int con_size_in_bytes, // Object size in bytes if known at compile time.
256 Register t1, // temp register
257 Register t2 // temp register
258 ) {
259 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
260 "con_size_in_bytes is not multiple of alignment");
261 assert(var_size_in_bytes == noreg, "not implemented");
262 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
263
264 const Register Rzero = t2;
265
266 z_xgr(Rzero, Rzero);
267 initialize_header(obj, klass, noreg, Rzero, t1);
268
269 // Clear rest of allocated space.
270 const int threshold = 4 * BytesPerWord;
271 if (con_size_in_bytes <= threshold) {
272 // Use explicit null stores.
273 // code size = 6*n bytes (n = number of fields to clear)
274 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord)
275 z_stg(Rzero, Address(obj, i));
276 } else {
277 // Code size generated by initialize_body() is 16.
278 Register object_fields = Z_R0_scratch;
279 Register len_in_bytes = Z_R1_scratch;
280 z_la(object_fields, hdr_size_in_bytes, obj);
281 load_const_optimized(len_in_bytes, con_size_in_bytes - hdr_size_in_bytes);
282 initialize_body(object_fields, len_in_bytes, Rzero);
283 }
284
285 // Dtrace support is unimplemented.
286 // if (CURRENT_ENV->dtrace_alloc_probes()) {
287 // assert(obj == rax, "must be");
288 // call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id)));
289 // }
290
291 verify_oop(obj, FILE_AND_LINE);
292 }
293
294 void C1_MacroAssembler::allocate_array(
295 Register obj, // result: Pointer to array after successful allocation.
296 Register len, // array length
297 Register t1, // temp register
298 Register t2, // temp register
299 int hdr_size, // object header size in words
300 int elt_size, // element size in bytes
301 Register klass, // object klass
302 Label& slow_case // Continuation point if fast allocation fails.
303 ) {
304 assert_different_registers(obj, len, t1, t2, klass);
305
306 // Determine alignment mask.
307 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work");
308
309 // Check for negative or excessive length.
310 compareU64_and_branch(len, (int32_t)max_array_allocation_length, bcondHigh, slow_case);
311
312 // Compute array size.
313 // Note: If 0 <= len <= max_length, len*elt_size + header + alignment is
314 // smaller or equal to the largest integer. Also, since top is always
315 // aligned, we can do the alignment here instead of at the end address
316 // computation.
317 const Register arr_size = t2;
318 switch (elt_size) {
319 case 1: lgr_if_needed(arr_size, len); break;
320 case 2: z_sllg(arr_size, len, 1); break;
321 case 4: z_sllg(arr_size, len, 2); break;
322 case 8: z_sllg(arr_size, len, 3); break;
323 default: ShouldNotReachHere();
324 }
325 add2reg(arr_size, hdr_size * wordSize + MinObjAlignmentInBytesMask); // Add space for header & alignment.
326 z_nill(arr_size, (~MinObjAlignmentInBytesMask) & 0xffff); // Align array size.
327
328 try_allocate(obj, arr_size, 0, t1, slow_case);
329
330 initialize_header(obj, klass, len, noreg, t1);
331
332 // Clear rest of allocated space.
333 Label done;
334 Register object_fields = t1;
335 Register Rzero = Z_R1_scratch;
336 z_aghi(arr_size, -(hdr_size * BytesPerWord));
337 z_bre(done); // Jump if size of fields is zero.
338 z_la(object_fields, hdr_size * BytesPerWord, obj);
339 z_xgr(Rzero, Rzero);
340 initialize_body(object_fields, arr_size, Rzero);
341 bind(done);
342
343 // Dtrace support is unimplemented.
344 // if (CURRENT_ENV->dtrace_alloc_probes()) {
345 // assert(obj == rax, "must be");
346 // call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id)));
347 // }
348
349 verify_oop(obj, FILE_AND_LINE);
350 }
351
352
353 #ifndef PRODUCT
354
355 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
356 if (!VerifyOops) return;
357 verify_oop_addr(Address(Z_SP, stack_offset), FILE_AND_LINE);
358 }
359
360 void C1_MacroAssembler::verify_not_null_oop(Register r) {
361 if (!VerifyOops) return;
362 NearLabel not_null;
363 compareU64_and_branch(r, (intptr_t)0, bcondNotEqual, not_null);
364 stop("non-null oop required");
365 bind(not_null);
366 verify_oop(r, FILE_AND_LINE);
367 }
368
369 void C1_MacroAssembler::invalidate_registers(Register preserve1,
370 Register preserve2,
371 Register preserve3) {
372 Register dead_value = noreg;
373 for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
374 Register r = as_Register(i);
375 if (r != preserve1 && r != preserve2 && r != preserve3 && r != Z_SP && r != Z_thread) {
376 if (dead_value == noreg) {
377 load_const_optimized(r, 0xc1dead);
378 dead_value = r;
379 } else {
380 z_lgr(r, dead_value);
381 }
382 }
383 }
384 }
385
386 #endif // !PRODUCT