36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/thread.hpp"
38 #include "utilities/macros.hpp"
39 #ifdef COMPILER1
40 #include "c1/c1_LIRAssembler.hpp"
41 #include "c1/c1_MacroAssembler.hpp"
42 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
43 #endif
44
45 #define __ masm->
46
47 address ShenandoahBarrierSetAssembler::_shenandoah_lrb = NULL;
48
49 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
50 Register src, Register dst, Register count) {
51
52 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
53
54 if (is_reference_type(type)) {
55
56 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) {
57 #ifdef _LP64
58 Register thread = r15_thread;
59 #else
60 Register thread = rax;
61 if (thread == src || thread == dst || thread == count) {
62 thread = rbx;
63 }
64 if (thread == src || thread == dst || thread == count) {
65 thread = rcx;
66 }
67 if (thread == src || thread == dst || thread == count) {
68 thread = rdx;
69 }
70 __ push(thread);
71 __ get_thread(thread);
72 #endif
73 assert_different_registers(src, dst, count, thread);
74
75 Label done;
76 // Short-circuit if count == 0.
77 __ testptr(count, count);
78 __ jcc(Assembler::zero, done);
79
80 // Avoid runtime call when not marking.
81 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
82 int flags = ShenandoahHeap::HAS_FORWARDED;
83 if (!dest_uninitialized) {
84 flags |= ShenandoahHeap::MARKING;
85 }
86 __ testb(gc_state, flags);
87 __ jcc(Assembler::zero, done);
88
89 __ pusha(); // push registers
90 #ifdef _LP64
91 assert(src == rdi, "expected");
92 assert(dst == rsi, "expected");
93 assert(count == rdx, "expected");
94 if (UseCompressedOops) {
95 if (dest_uninitialized) {
96 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry), src, dst, count);
97 } else {
98 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), src, dst, count);
99 }
100 } else
101 #endif
102 {
103 if (dest_uninitialized) {
104 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry), src, dst, count);
105 } else {
106 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), src, dst, count);
107 }
108 }
109 __ popa();
110 __ bind(done);
111 NOT_LP64(__ pop(thread);)
112 }
113 }
114
115 }
116
117 void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
118 Register obj,
119 Register pre_val,
120 Register thread,
121 Register tmp,
122 bool tosca_live,
123 bool expand_call) {
|
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/thread.hpp"
38 #include "utilities/macros.hpp"
39 #ifdef COMPILER1
40 #include "c1/c1_LIRAssembler.hpp"
41 #include "c1/c1_MacroAssembler.hpp"
42 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
43 #endif
44
45 #define __ masm->
46
47 address ShenandoahBarrierSetAssembler::_shenandoah_lrb = NULL;
48
49 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
50 Register src, Register dst, Register count) {
51
52 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
53
54 if (is_reference_type(type)) {
55
56 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahStoreValEnqueueBarrier || ShenandoahLoadRefBarrier) {
57 #ifdef _LP64
58 Register thread = r15_thread;
59 #else
60 Register thread = rax;
61 if (thread == src || thread == dst || thread == count) {
62 thread = rbx;
63 }
64 if (thread == src || thread == dst || thread == count) {
65 thread = rcx;
66 }
67 if (thread == src || thread == dst || thread == count) {
68 thread = rdx;
69 }
70 __ push(thread);
71 __ get_thread(thread);
72 #endif
73 assert_different_registers(src, dst, count, thread);
74
75 Label done;
76 // Short-circuit if count == 0.
77 __ testptr(count, count);
78 __ jcc(Assembler::zero, done);
79
80 // Avoid runtime call when not marking.
81 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
82 int flags = ShenandoahHeap::HAS_FORWARDED;
83 if (ShenandoahStoreValEnqueueBarrier || !dest_uninitialized) {
84 flags |= ShenandoahHeap::MARKING;
85 }
86 __ testb(gc_state, flags);
87 __ jcc(Assembler::zero, done);
88
89 __ pusha(); // push registers
90 #ifdef _LP64
91 assert(src == rdi, "expected");
92 assert(dst == rsi, "expected");
93 assert(count == rdx, "expected");
94 if (UseCompressedOops) {
95 if (dest_uninitialized && ShenandoahSATBBarrier) {
96 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry), src, dst, count);
97 } else {
98 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), src, dst, count);
99 }
100 } else
101 #endif
102 {
103 if (dest_uninitialized && ShenandoahSATBBarrier) {
104 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry), src, dst, count);
105 } else {
106 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), src, dst, count);
107 }
108 }
109 __ popa();
110 __ bind(done);
111 NOT_LP64(__ pop(thread);)
112 }
113 }
114
115 }
116
117 void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
118 Register obj,
119 Register pre_val,
120 Register thread,
121 Register tmp,
122 bool tosca_live,
123 bool expand_call) {
|