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 active.
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
91 #ifdef _LP64
92 assert(src == rdi, "expected");
93 assert(dst == rsi, "expected");
94 assert(count == rdx, "expected");
95 if (UseCompressedOops) {
96 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
97 src, dst, count);
98 } else
99 #endif
100 {
101 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry),
102 src, dst, count);
103 }
|
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 active.
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
91 #ifdef _LP64
92 assert(src == rdi, "expected");
93 assert(dst == rsi, "expected");
94 assert(count == rdx, "expected");
95 if (UseCompressedOops) {
96 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
97 src, dst, count);
98 } else
99 #endif
100 {
101 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry),
102 src, dst, count);
103 }
|