47 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
48 Register src, Register dst, Register count, RegSet saved_regs) {
49 if (is_oop) {
50 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
51 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahIUBarrier || ShenandoahLoadRefBarrier) {
52
53 Label done;
54
55 // Avoid calling runtime if count == 0
56 __ beqz(count, done);
57
58 // Is GC active?
59 Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
60 assert_different_registers(src, dst, count, t0);
61
62 __ lbu(t0, gc_state);
63 if (ShenandoahSATBBarrier && dest_uninitialized) {
64 __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED);
65 __ beqz(t0, done);
66 } else {
67 __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING);
68 __ beqz(t0, done);
69 }
70
71 __ push_reg(saved_regs, sp);
72 if (UseCompressedOops) {
73 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
74 src, dst, count);
75 } else {
76 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count);
77 }
78 __ pop_reg(saved_regs, sp);
79 __ bind(done);
80 }
81 }
82 }
83
84 void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
85 Register obj,
86 Register pre_val,
87 Register thread,
625 void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
626 __ prologue("shenandoah_pre_barrier", false);
627
628 // arg0 : previous value of memory
629
630 BarrierSet* bs = BarrierSet::barrier_set();
631
632 const Register pre_val = x10;
633 const Register thread = xthread;
634 const Register tmp = t0;
635
636 Address queue_index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
637 Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
638
639 Label done;
640 Label runtime;
641
642 // Is marking still active?
643 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
644 __ lb(tmp, gc_state);
645 __ andi(tmp, tmp, ShenandoahHeap::MARKING);
646 __ beqz(tmp, done);
647
648 // Can we store original value in the thread's buffer?
649 __ ld(tmp, queue_index);
650 __ beqz(tmp, runtime);
651
652 __ sub(tmp, tmp, wordSize);
653 __ sd(tmp, queue_index);
654 __ ld(t1, buffer);
655 __ add(tmp, tmp, t1);
656 __ load_parameter(0, t1);
657 __ sd(t1, Address(tmp, 0));
658 __ j(done);
659
660 __ bind(runtime);
661 __ push_call_clobbered_registers();
662 __ load_parameter(0, pre_val);
663 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
664 __ pop_call_clobbered_registers();
665 __ bind(done);
|
47 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
48 Register src, Register dst, Register count, RegSet saved_regs) {
49 if (is_oop) {
50 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
51 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahIUBarrier || ShenandoahLoadRefBarrier) {
52
53 Label done;
54
55 // Avoid calling runtime if count == 0
56 __ beqz(count, done);
57
58 // Is GC active?
59 Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
60 assert_different_registers(src, dst, count, t0);
61
62 __ lbu(t0, gc_state);
63 if (ShenandoahSATBBarrier && dest_uninitialized) {
64 __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED);
65 __ beqz(t0, done);
66 } else {
67 __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::YOUNG_MARKING | ShenandoahHeap::OLD_MARKING);
68 __ beqz(t0, done);
69 }
70
71 __ push_reg(saved_regs, sp);
72 if (UseCompressedOops) {
73 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
74 src, dst, count);
75 } else {
76 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count);
77 }
78 __ pop_reg(saved_regs, sp);
79 __ bind(done);
80 }
81 }
82 }
83
84 void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
85 Register obj,
86 Register pre_val,
87 Register thread,
625 void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
626 __ prologue("shenandoah_pre_barrier", false);
627
628 // arg0 : previous value of memory
629
630 BarrierSet* bs = BarrierSet::barrier_set();
631
632 const Register pre_val = x10;
633 const Register thread = xthread;
634 const Register tmp = t0;
635
636 Address queue_index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
637 Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
638
639 Label done;
640 Label runtime;
641
642 // Is marking still active?
643 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
644 __ lb(tmp, gc_state);
645 __ andi(tmp, tmp, ShenandoahHeap::YOUNG_MARKING | ShenandoahHeap::OLD_MARKING);
646 __ beqz(tmp, done);
647
648 // Can we store original value in the thread's buffer?
649 __ ld(tmp, queue_index);
650 __ beqz(tmp, runtime);
651
652 __ sub(tmp, tmp, wordSize);
653 __ sd(tmp, queue_index);
654 __ ld(t1, buffer);
655 __ add(tmp, tmp, t1);
656 __ load_parameter(0, t1);
657 __ sd(t1, Address(tmp, 0));
658 __ j(done);
659
660 __ bind(runtime);
661 __ push_call_clobbered_registers();
662 __ load_parameter(0, pre_val);
663 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
664 __ pop_call_clobbered_registers();
665 __ bind(done);
|