231 if (borrow_reg) { |
231 if (borrow_reg) { |
232 __ pop(RegSet::of(tmp), sp); |
232 __ pop(RegSet::of(tmp), sp); |
233 } |
233 } |
234 } |
234 } |
235 |
235 |
236 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Register tmp) { |
236 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr) { |
237 assert(ShenandoahLoadRefBarrier, "Should be enabled"); |
237 assert(ShenandoahLoadRefBarrier, "Should be enabled"); |
238 assert(dst != rscratch2, "need rscratch2"); |
238 assert(dst != rscratch2, "need rscratch2"); |
|
239 assert_different_registers(load_addr.base(), load_addr.index(), rscratch1, rscratch2); |
239 |
240 |
240 Label done; |
241 Label done; |
241 __ enter(); |
242 __ enter(); |
242 Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); |
243 Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); |
243 __ ldrb(rscratch2, gc_state); |
244 __ ldrb(rscratch2, gc_state); |
244 |
245 |
245 // Check for heap stability |
246 // Check for heap stability |
246 __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done); |
247 __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done); |
247 |
248 |
248 RegSet to_save = RegSet::of(r0); |
249 // use r1 for load address |
|
250 Register result_dst = dst; |
|
251 if (dst == r1) { |
|
252 __ mov(rscratch1, dst); |
|
253 dst = rscratch1; |
|
254 } |
|
255 |
|
256 RegSet to_save_r1 = RegSet::of(r1); |
|
257 // If outgoing register is r1, we can clobber it |
|
258 if (result_dst != r1) { |
|
259 __ push(to_save_r1, sp); |
|
260 } |
|
261 __ lea(r1, load_addr); |
|
262 |
|
263 RegSet to_save_r0 = RegSet::of(r0); |
249 if (dst != r0) { |
264 if (dst != r0) { |
250 __ push(to_save, sp); |
265 __ push(to_save_r0, sp); |
251 __ mov(r0, dst); |
266 __ mov(r0, dst); |
252 } |
267 } |
253 |
268 |
254 __ far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb()))); |
269 __ far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb()))); |
255 |
270 |
|
271 if (result_dst != r0) { |
|
272 __ mov(result_dst, r0); |
|
273 } |
|
274 |
256 if (dst != r0) { |
275 if (dst != r0) { |
257 __ mov(dst, r0); |
276 __ pop(to_save_r0, sp); |
258 __ pop(to_save, sp); |
277 } |
|
278 |
|
279 if (result_dst != r1) { |
|
280 __ pop(to_save_r1, sp); |
259 } |
281 } |
260 |
282 |
261 __ bind(done); |
283 __ bind(done); |
262 __ leave(); |
284 __ leave(); |
263 } |
285 } |
313 __ ldrd(v0, __ post(sp, 2 * wordSize)); |
335 __ ldrd(v0, __ post(sp, 2 * wordSize)); |
314 __ pop(live_regs, sp); |
336 __ pop(live_regs, sp); |
315 } |
337 } |
316 } |
338 } |
317 |
339 |
318 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Register tmp) { |
340 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr) { |
319 if (ShenandoahLoadRefBarrier) { |
341 if (ShenandoahLoadRefBarrier) { |
320 Label is_null; |
342 Label is_null; |
321 __ cbz(dst, is_null); |
343 __ cbz(dst, is_null); |
322 load_reference_barrier_not_null(masm, dst, tmp); |
344 load_reference_barrier_not_null(masm, dst, load_addr); |
323 __ bind(is_null); |
345 __ bind(is_null); |
324 } |
346 } |
325 } |
347 } |
326 |
348 |
327 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
349 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
347 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
369 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
348 if (on_oop) { |
370 if (on_oop) { |
349 if (not_in_heap && !is_traversal_mode) { |
371 if (not_in_heap && !is_traversal_mode) { |
350 load_reference_barrier_native(masm, dst, src); |
372 load_reference_barrier_native(masm, dst, src); |
351 } else { |
373 } else { |
352 load_reference_barrier(masm, dst, tmp1); |
374 load_reference_barrier(masm, dst, src); |
353 } |
375 } |
354 |
376 |
355 if (dst != result_dst) { |
377 if (dst != result_dst) { |
356 __ mov(result_dst, dst); |
378 __ mov(result_dst, dst); |
357 dst = result_dst; |
379 dst = result_dst; |
617 |
639 |
618 __ push_call_clobbered_registers(); |
640 __ push_call_clobbered_registers(); |
619 __ load_parameter(0, r0); |
641 __ load_parameter(0, r0); |
620 __ load_parameter(1, r1); |
642 __ load_parameter(1, r1); |
621 if (UseCompressedOops) { |
643 if (UseCompressedOops) { |
622 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup_narrow)); |
644 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)); |
623 } else { |
645 } else { |
624 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup)); |
646 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); |
625 } |
647 } |
626 __ blr(lr); |
648 __ blr(lr); |
627 __ mov(rscratch1, r0); |
649 __ mov(rscratch1, r0); |
628 __ pop_call_clobbered_registers(); |
650 __ pop_call_clobbered_registers(); |
629 __ mov(r0, rscratch1); |
651 __ mov(r0, rscratch1); |
679 __ bind(slow_path); |
702 __ bind(slow_path); |
680 __ enter(); // required for proper stackwalking of RuntimeStub frame |
703 __ enter(); // required for proper stackwalking of RuntimeStub frame |
681 |
704 |
682 __ push_call_clobbered_registers(); |
705 __ push_call_clobbered_registers(); |
683 |
706 |
684 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); |
707 if (UseCompressedOops) { |
|
708 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)); |
|
709 } else { |
|
710 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); |
|
711 } |
685 __ blr(lr); |
712 __ blr(lr); |
686 __ mov(rscratch1, r0); |
713 __ mov(rscratch1, r0); |
687 __ pop_call_clobbered_registers(); |
714 __ pop_call_clobbered_registers(); |
688 __ mov(r0, rscratch1); |
715 __ mov(r0, rscratch1); |
689 |
716 |