66 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
67 Label done;
68 int null_check_offset = -1;
69
70 verify_oop(obj);
71
72 // save object being locked into the BasicObjectLock
73 str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
74
75 null_check_offset = offset();
76
77 if (DiagnoseSyncOnValueBasedClasses != 0) {
78 load_klass(hdr, obj);
79 ldrw(hdr, Address(hdr, Klass::access_flags_offset()));
80 tstw(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
81 br(Assembler::NE, slow_case);
82 }
83
84 // Load object header
85 ldr(hdr, Address(obj, hdr_offset));
86 // and mark it as unlocked
87 orr(hdr, hdr, markWord::unlocked_value);
88 // save unlocked object header into the displaced header location on the stack
89 str(hdr, Address(disp_hdr, 0));
90 // test if object header is still the same (i.e. unlocked), and if so, store the
91 // displaced header address in the object header - if it is not the same, get the
92 // object header instead
93 lea(rscratch2, Address(obj, hdr_offset));
94 cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
95 // if the object header was the same, we're done
96 // if the object header was not the same, it is now in the hdr register
97 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
98 //
99 // 1) (hdr & aligned_mask) == 0
100 // 2) sp <= hdr
101 // 3) hdr <= sp + page_size
102 //
103 // these 3 tests can be done by evaluating the following expression:
104 //
105 // (hdr - sp) & (aligned_mask - page_size)
106 //
107 // assuming both the stack pointer and page_size have their least
108 // significant 2 bits cleared and page_size is a power of 2
109 mov(rscratch1, sp);
110 sub(hdr, hdr, rscratch1);
111 ands(hdr, hdr, aligned_mask - (int)os::vm_page_size());
112 // for recursive locking, the result is zero => save it in the displaced header
113 // location (NULL in the displaced hdr location indicates recursive locking)
114 str(hdr, Address(disp_hdr, 0));
115 // otherwise we don't care about the result and handle locking via runtime call
116 cbnz(hdr, slow_case);
117 // done
118 bind(done);
119 increment(Address(rthread, JavaThread::held_monitor_count_offset()));
120 return null_check_offset;
121 }
122
123
124 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
125 const int aligned_mask = BytesPerWord -1;
126 const int hdr_offset = oopDesc::mark_offset_in_bytes();
127 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
128 Label done;
129
130 // load displaced header
131 ldr(hdr, Address(disp_hdr, 0));
132 // if the loaded hdr is NULL we had recursive locking
133 // if we had recursive locking, we are done
134 cbz(hdr, done);
135 // load object
136 ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
137 verify_oop(obj);
138 // test if object header is pointing to the displaced header, and if so, restore
139 // the displaced header in the object - if the object header is not pointing to
140 // the displaced header, get the object header instead
141 // if the object header was not pointing to the displaced header,
142 // we do unlocking via runtime call
143 if (hdr_offset) {
144 lea(rscratch1, Address(obj, hdr_offset));
145 cmpxchgptr(disp_hdr, hdr, rscratch1, rscratch2, done, &slow_case);
146 } else {
147 cmpxchgptr(disp_hdr, hdr, obj, rscratch2, done, &slow_case);
148 }
149 // done
150 bind(done);
151 decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
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(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
159 } else {
160 b(slow_case);
161 }
162 }
163
164 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
165 assert_different_registers(obj, klass, len);
166 // This assumes that all prototype bits fit in an int32_t
167 mov(t1, (int32_t)(intptr_t)markWord::prototype().value());
168 str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
169
170 if (UseCompressedClassPointers) { // Take care not to kill klass
171 encode_klass_not_null(t1, klass);
172 strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
173 } else {
174 str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
175 }
176
177 if (len->is_valid()) {
178 strw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
179 } else if (UseCompressedClassPointers) {
180 store_klass_gap(obj, zr);
181 }
182 }
183
184 // preserves obj, destroys len_in_bytes
185 //
186 // Scratch registers: t1 = r10, t2 = r11
187 //
188 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1, Register t2) {
189 assert(hdr_size_in_bytes >= 0, "header size must be positive or 0");
190 assert(t1 == r10 && t2 == r11, "must be");
191
192 Label done;
193
194 // len_in_bytes is positive and ptr sized
195 subs(len_in_bytes, len_in_bytes, hdr_size_in_bytes);
196 br(Assembler::EQ, done);
197
198 // zero_words() takes ptr in r10 and count in words in r11
199 mov(rscratch1, len_in_bytes);
200 lea(t1, Address(obj, hdr_size_in_bytes));
201 lsr(t2, rscratch1, LogBytesPerWord);
202 address tpc = zero_words(t1, t2);
203
204 bind(done);
205 if (tpc == nullptr) {
206 Compilation::current()->bailout("no space for trampoline stub");
207 }
208 }
209
210
211 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
212 assert_different_registers(obj, t1, t2); // XXX really?
213 assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
214
215 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
216
217 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB);
237 } else if (con_size_in_bytes > hdr_size_in_bytes) {
238 con_size_in_bytes -= hdr_size_in_bytes;
239 lea(t1, Address(obj, hdr_size_in_bytes));
240 address tpc = zero_words(t1, con_size_in_bytes / BytesPerWord);
241 if (tpc == nullptr) {
242 Compilation::current()->bailout("no space for trampoline stub");
243 return;
244 }
245 }
246 }
247
248 membar(StoreStore);
249
250 if (CURRENT_ENV->dtrace_alloc_probes()) {
251 assert(obj == r0, "must be");
252 far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
253 }
254
255 verify_oop(obj);
256 }
257 void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, int f, Register klass, Label& slow_case) {
258 assert_different_registers(obj, len, t1, t2, klass);
259
260 // determine alignment mask
261 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work");
262
263 // check for negative or excessive length
264 mov(rscratch1, (int32_t)max_array_allocation_length);
265 cmp(len, rscratch1);
266 br(Assembler::HS, slow_case);
267
268 const Register arr_size = t2; // okay to be the same
269 // align object end
270 mov(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask);
271 add(arr_size, arr_size, len, ext::uxtw, f);
272 andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
273
274 try_allocate(obj, arr_size, 0, t1, t2, slow_case);
275
276 initialize_header(obj, klass, len, t1, t2);
277
278 // clear rest of allocated space
279 initialize_body(obj, arr_size, header_size * BytesPerWord, t1, t2);
280 if (Compilation::current()->bailed_out()) {
281 return;
282 }
283
284 membar(StoreStore);
285
286 if (CURRENT_ENV->dtrace_alloc_probes()) {
287 assert(obj == r0, "must be");
288 far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
289 }
290
291 verify_oop(obj);
292 }
293
294
295 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
296 verify_oop(receiver);
297 // explicit NULL check not needed since load from [klass_offset] causes a trap
298 // check against inline cache
299 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
300
301 cmp_klass(receiver, iCache, rscratch1);
302 }
303
304
305 void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) {
306 assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
307 // Make sure there is enough stack space for this method's activation.
308 // Note that we do this before creating a frame.
309 generate_stack_overflow_check(bang_size_in_bytes);
310 MacroAssembler::build_frame(framesize);
311
312 // Insert nmethod entry barrier into frame.
313 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
314 bs->nmethod_entry_barrier(this, NULL /* slow_path */, NULL /* continuation */, NULL /* guard */);
315 }
316
317 void C1_MacroAssembler::remove_frame(int framesize) {
318 MacroAssembler::remove_frame(framesize);
319 }
320
321
322 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
323 // If we have to make this method not-entrant we'll overwrite its
324 // first instruction with a jump. For this action to be legal we
325 // must ensure that this first instruction is a B, BL, NOP, BKPT,
326 // SVC, HVC, or SMC. Make it a NOP.
327 nop();
328 }
329
330 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
331 // rfp, + 0: link
|
66 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
67 Label done;
68 int null_check_offset = -1;
69
70 verify_oop(obj);
71
72 // save object being locked into the BasicObjectLock
73 str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
74
75 null_check_offset = offset();
76
77 if (DiagnoseSyncOnValueBasedClasses != 0) {
78 load_klass(hdr, obj);
79 ldrw(hdr, Address(hdr, Klass::access_flags_offset()));
80 tstw(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
81 br(Assembler::NE, slow_case);
82 }
83
84 // Load object header
85 ldr(hdr, Address(obj, hdr_offset));
86 if (UseFastLocking) {
87 fast_lock(obj, hdr, rscratch1, rscratch2, slow_case, false);
88 } else {
89 // and mark it as unlocked
90 orr(hdr, hdr, markWord::unlocked_value);
91 // save unlocked object header into the displaced header location on the stack
92 str(hdr, Address(disp_hdr, 0));
93 // test if object header is still the same (i.e. unlocked), and if so, store the
94 // displaced header address in the object header - if it is not the same, get the
95 // object header instead
96 lea(rscratch2, Address(obj, hdr_offset));
97 cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
98 // if the object header was the same, we're done
99 // if the object header was not the same, it is now in the hdr register
100 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
101 //
102 // 1) (hdr & aligned_mask) == 0
103 // 2) sp <= hdr
104 // 3) hdr <= sp + page_size
105 //
106 // these 3 tests can be done by evaluating the following expression:
107 //
108 // (hdr - sp) & (aligned_mask - page_size)
109 //
110 // assuming both the stack pointer and page_size have their least
111 // significant 2 bits cleared and page_size is a power of 2
112 mov(rscratch1, sp);
113 sub(hdr, hdr, rscratch1);
114 ands(hdr, hdr, aligned_mask - (int)os::vm_page_size());
115 // for recursive locking, the result is zero => save it in the displaced header
116 // location (NULL in the displaced hdr location indicates recursive locking)
117 str(hdr, Address(disp_hdr, 0));
118 // otherwise we don't care about the result and handle locking via runtime call
119 cbnz(hdr, slow_case);
120 }
121 // done
122 bind(done);
123 increment(Address(rthread, JavaThread::held_monitor_count_offset()));
124 return null_check_offset;
125 }
126
127
128 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
129 const int aligned_mask = BytesPerWord -1;
130 const int hdr_offset = oopDesc::mark_offset_in_bytes();
131 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
132 Label done;
133
134 if (!UseFastLocking) {
135 // load displaced header
136 ldr(hdr, Address(disp_hdr, 0));
137 // if the loaded hdr is NULL we had recursive locking
138 // if we had recursive locking, we are done
139 cbz(hdr, done);
140 }
141
142 // load object
143 ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
144 verify_oop(obj);
145
146 if (UseFastLocking) {
147 ldr(hdr, Address(obj, oopDesc::mark_offset_in_bytes()));
148 fast_unlock(obj, hdr, rscratch1, rscratch2, slow_case);
149 } else {
150 // test if object header is pointing to the displaced header, and if so, restore
151 // the displaced header in the object - if the object header is not pointing to
152 // the displaced header, get the object header instead
153 // if the object header was not pointing to the displaced header,
154 // we do unlocking via runtime call
155 if (hdr_offset) {
156 lea(rscratch1, Address(obj, hdr_offset));
157 cmpxchgptr(disp_hdr, hdr, rscratch1, rscratch2, done, &slow_case);
158 } else {
159 cmpxchgptr(disp_hdr, hdr, obj, rscratch2, done, &slow_case);
160 }
161 // done
162 bind(done);
163 }
164 decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
165 }
166
167
168 // Defines obj, preserves var_size_in_bytes
169 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
170 if (UseTLAB) {
171 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
172 } else {
173 b(slow_case);
174 }
175 }
176
177 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
178 assert_different_registers(obj, klass, len);
179 if (UseCompactObjectHeaders) {
180 ldr(t1, Address(klass, Klass::prototype_header_offset()));
181 str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
182 } else {
183 // This assumes that all prototype bits fit in an int32_t
184 mov(t1, (int32_t)(intptr_t)markWord::prototype().value());
185 str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
186
187 if (UseCompressedClassPointers) { // Take care not to kill klass
188 encode_klass_not_null(t1, klass);
189 strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
190 } else {
191 str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
192 }
193 }
194
195 if (len->is_valid()) {
196 strw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
197 } else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
198 store_klass_gap(obj, zr);
199 }
200 }
201
202 // preserves obj, destroys len_in_bytes
203 //
204 // Scratch registers: t1 = r10, t2 = r11
205 //
206 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1, Register t2) {
207 assert(hdr_size_in_bytes >= 0, "header size must be positive or 0");
208 assert(t1 == r10 && t2 == r11, "must be");
209
210 Label done;
211
212 // len_in_bytes is positive and ptr sized
213 subs(len_in_bytes, len_in_bytes, hdr_size_in_bytes);
214 br(Assembler::EQ, done);
215
216 // Zero first 4 bytes, if start offset is not word aligned.
217 if (!is_aligned(hdr_size_in_bytes, BytesPerWord)) {
218 strw(zr, Address(obj, hdr_size_in_bytes));
219 hdr_size_in_bytes += BytesPerInt;
220 }
221
222 // zero_words() takes ptr in r10 and count in words in r11
223 mov(rscratch1, len_in_bytes);
224 lea(t1, Address(obj, hdr_size_in_bytes));
225 lsr(t2, rscratch1, LogBytesPerWord);
226 address tpc = zero_words(t1, t2);
227
228 bind(done);
229 if (tpc == nullptr) {
230 Compilation::current()->bailout("no space for trampoline stub");
231 }
232 }
233
234
235 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
236 assert_different_registers(obj, t1, t2); // XXX really?
237 assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
238
239 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
240
241 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB);
261 } else if (con_size_in_bytes > hdr_size_in_bytes) {
262 con_size_in_bytes -= hdr_size_in_bytes;
263 lea(t1, Address(obj, hdr_size_in_bytes));
264 address tpc = zero_words(t1, con_size_in_bytes / BytesPerWord);
265 if (tpc == nullptr) {
266 Compilation::current()->bailout("no space for trampoline stub");
267 return;
268 }
269 }
270 }
271
272 membar(StoreStore);
273
274 if (CURRENT_ENV->dtrace_alloc_probes()) {
275 assert(obj == r0, "must be");
276 far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
277 }
278
279 verify_oop(obj);
280 }
281 void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int base_offset_in_bytes, int f, Register klass, Label& slow_case) {
282 assert_different_registers(obj, len, t1, t2, klass);
283
284 // determine alignment mask
285 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work");
286
287 // check for negative or excessive length
288 mov(rscratch1, (int32_t)max_array_allocation_length);
289 cmp(len, rscratch1);
290 br(Assembler::HS, slow_case);
291
292 const Register arr_size = t2; // okay to be the same
293 // align object end
294 mov(arr_size, (int32_t)base_offset_in_bytes + MinObjAlignmentInBytesMask);
295 add(arr_size, arr_size, len, ext::uxtw, f);
296 andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
297
298 try_allocate(obj, arr_size, 0, t1, t2, slow_case);
299
300 initialize_header(obj, klass, len, t1, t2);
301
302 // clear rest of allocated space
303 initialize_body(obj, arr_size, base_offset_in_bytes, t1, t2);
304 if (Compilation::current()->bailed_out()) {
305 return;
306 }
307
308 membar(StoreStore);
309
310 if (CURRENT_ENV->dtrace_alloc_probes()) {
311 assert(obj == r0, "must be");
312 far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
313 }
314
315 verify_oop(obj);
316 }
317
318
319 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
320 verify_oop(receiver);
321 // explicit NULL check not needed since load from [klass_offset] causes a trap
322 // check against inline cache
323 if (UseCompactObjectHeaders) {
324 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::mark_offset_in_bytes()), "must add explicit null check");
325 } else {
326 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
327 }
328
329 cmp_klass(receiver, iCache, rscratch1);
330 }
331
332
333 void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes, int max_monitors) {
334 assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
335 // Make sure there is enough stack space for this method's activation.
336 // Note that we do this before creating a frame.
337 generate_stack_overflow_check(bang_size_in_bytes);
338 MacroAssembler::build_frame(framesize);
339
340 if (UseFastLocking && max_monitors > 0) {
341 Label ok;
342 ldr(r9, Address(rthread, JavaThread::lock_stack_current_offset()));
343 ldr(r10, Address(rthread, JavaThread::lock_stack_limit_offset()));
344 add(r9, r9, max_monitors * oopSize);
345 cmp(r9, r10);
346 br(Assembler::LT, ok);
347 assert(StubRoutines::aarch64::check_lock_stack() != NULL, "need runtime call stub");
348 far_call(StubRoutines::aarch64::check_lock_stack());
349 bind(ok);
350 }
351
352 // Insert nmethod entry barrier into frame.
353 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
354 bs->nmethod_entry_barrier(this, NULL /* slow_path */, NULL /* continuation */, NULL /* guard */);
355 }
356
357 void C1_MacroAssembler::remove_frame(int framesize) {
358 MacroAssembler::remove_frame(framesize);
359 }
360
361
362 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
363 // If we have to make this method not-entrant we'll overwrite its
364 // first instruction with a jump. For this action to be legal we
365 // must ensure that this first instruction is a B, BL, NOP, BKPT,
366 // SVC, HVC, or SMC. Make it a NOP.
367 nop();
368 }
369
370 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
371 // rfp, + 0: link
|