26 #include "c1/c1_LIRAssembler.hpp"
27 #include "macroAssembler_x86.hpp"
28 #include "shenandoahBarrierSetAssembler_x86.hpp"
29 #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"
30 #include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp"
31 #include "gc_implementation/shenandoah/shenandoahForwarding.hpp"
32 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
33 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
34 #include "gc_implementation/shenandoah/shenandoahRuntime.hpp"
35 #include "runtime/stubCodeGenerator.hpp"
36
37 ShenandoahBarrierSetAssembler* ShenandoahBarrierSetAssembler::bsasm() {
38 return ShenandoahBarrierSet::barrier_set()->bsasm();
39 }
40
41 #define __ masm->
42
43 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, bool dest_uninitialized,
44 Register src, Register dst, Register count) {
45
46 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) {
47 #ifdef _LP64
48 Register thread = r15_thread;
49 #else
50 Register thread = rax;
51 if (thread == src || thread == dst || thread == count) {
52 thread = rbx;
53 }
54 if (thread == src || thread == dst || thread == count) {
55 thread = rcx;
56 }
57 if (thread == src || thread == dst || thread == count) {
58 thread = rdx;
59 }
60 __ push(thread);
61 __ get_thread(thread);
62 #endif
63 assert_different_registers(src, dst, count, thread);
64
65 Label done;
66 // Short-circuit if count == 0.
67 __ testptr(count, count);
68 __ jcc(Assembler::zero, done);
69
70 // Avoid runtime call when not marking.
71 Address gc_state(thread, in_bytes(JavaThread::gc_state_offset()));
72 int flags = ShenandoahHeap::HAS_FORWARDED;
73 if (!dest_uninitialized) {
74 flags |= ShenandoahHeap::MARKING;
75 }
76 __ testb(gc_state, flags);
77 __ jcc(Assembler::zero, done);
78
79 __ pusha(); // push registers
80 #ifdef _LP64
81 assert(src == rdi, "expected");
82 assert(dst == rsi, "expected");
83 // commented-out for generate_conjoint_long_oop_copy(), call_VM_leaf() will move
84 // register into right place.
85 // assert(count == rdx, "expected");
86 if (UseCompressedOops) {
87 if (dest_uninitialized) {
88 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry), src, dst, count);
89 } else {
90 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), src, dst, count);
91 }
92 } else
93 #endif
94 {
95 if (dest_uninitialized) {
96 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry), src, dst, count);
97 } else {
98 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), src, dst, count);
99 }
100 }
101 __ popa();
102 __ bind(done);
103 NOT_LP64(__ pop(thread);)
104 }
105 }
106
107 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst) {
108 assert(ShenandoahLoadRefBarrier, "Should be enabled");
109
110 Label done;
111
112 #ifdef _LP64
113 Register thread = r15_thread;
114 #else
115 Register thread = rcx;
116 if (thread == dst) {
117 thread = rbx;
118 }
119 __ push(thread);
120 __ get_thread(thread);
|
26 #include "c1/c1_LIRAssembler.hpp"
27 #include "macroAssembler_x86.hpp"
28 #include "shenandoahBarrierSetAssembler_x86.hpp"
29 #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"
30 #include "gc_implementation/shenandoah/shenandoahBarrierSetC1.hpp"
31 #include "gc_implementation/shenandoah/shenandoahForwarding.hpp"
32 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
33 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
34 #include "gc_implementation/shenandoah/shenandoahRuntime.hpp"
35 #include "runtime/stubCodeGenerator.hpp"
36
37 ShenandoahBarrierSetAssembler* ShenandoahBarrierSetAssembler::bsasm() {
38 return ShenandoahBarrierSet::barrier_set()->bsasm();
39 }
40
41 #define __ masm->
42
43 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, bool dest_uninitialized,
44 Register src, Register dst, Register count) {
45
46 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahStoreValEnqueueBarrier || ShenandoahLoadRefBarrier) {
47 #ifdef _LP64
48 Register thread = r15_thread;
49 #else
50 Register thread = rax;
51 if (thread == src || thread == dst || thread == count) {
52 thread = rbx;
53 }
54 if (thread == src || thread == dst || thread == count) {
55 thread = rcx;
56 }
57 if (thread == src || thread == dst || thread == count) {
58 thread = rdx;
59 }
60 __ push(thread);
61 __ get_thread(thread);
62 #endif
63 assert_different_registers(src, dst, count, thread);
64
65 Label done;
66 // Short-circuit if count == 0.
67 __ testptr(count, count);
68 __ jcc(Assembler::zero, done);
69
70 // Avoid runtime call when not active.
71 Address gc_state(thread, in_bytes(JavaThread::gc_state_offset()));
72 int flags;
73 if (ShenandoahSATBBarrier && dest_uninitialized) {
74 flags = ShenandoahHeap::HAS_FORWARDED;
75 } else {
76 flags = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING;
77 }
78 __ testb(gc_state, flags);
79 __ jcc(Assembler::zero, done);
80
81 __ pusha(); // push registers
82
83 #ifdef _LP64
84 assert(src == rdi, "expected");
85 assert(dst == rsi, "expected");
86 // commented-out for generate_conjoint_long_oop_copy(), call_VM_leaf() will move
87 // register into right place.
88 // assert(count == rdx, "expected");
89 if (UseCompressedOops) {
90 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
91 src, dst, count);
92 } else
93 #endif
94 {
95 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry),
96 src, dst, count);
97 }
98
99 __ popa();
100 __ bind(done);
101 NOT_LP64(__ pop(thread);)
102 }
103 }
104
105 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst) {
106 assert(ShenandoahLoadRefBarrier, "Should be enabled");
107
108 Label done;
109
110 #ifdef _LP64
111 Register thread = r15_thread;
112 #else
113 Register thread = rcx;
114 if (thread == dst) {
115 thread = rbx;
116 }
117 __ push(thread);
118 __ get_thread(thread);
|