19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include "precompiled.hpp"
25 #include "c1/c1_LIR.hpp"
26 #include "c1/c1_LIRGenerator.hpp"
27 #include "c1/c1_CodeStubs.hpp"
28 #include "gc/z/c1/zBarrierSetC1.hpp"
29 #include "gc/z/zBarrierSet.hpp"
30 #include "gc/z/zBarrierSetAssembler.hpp"
31 #include "gc/z/zThreadLocalData.hpp"
32 #include "utilities/macros.hpp"
33
34 ZLoadBarrierStubC1::ZLoadBarrierStubC1(LIRAccess& access, LIR_Opr ref, address runtime_stub) :
35 _decorators(access.decorators()),
36 _ref_addr(access.resolved_addr()),
37 _ref(ref),
38 _tmp(LIR_OprFact::illegalOpr),
39 _patch_info(access.patch_emit_info()),
40 _runtime_stub(runtime_stub) {
41
42 // Allocate tmp register if needed
43 if (!_ref_addr->is_register()) {
44 assert(_ref_addr->is_address(), "Must be an address");
45 if (_ref_addr->as_address_ptr()->index()->is_valid() ||
46 _ref_addr->as_address_ptr()->disp() != 0) {
47 // Has index or displacement, need tmp register to load address into
48 _tmp = access.gen()->new_pointer_register();
49 } else {
50 // No index or displacement, address available in base register
51 _ref_addr = _ref_addr->as_address_ptr()->base();
52 }
53 }
54
55 assert(_ref->is_register(), "Must be a register");
56 assert(_ref_addr->is_register() != _tmp->is_register(), "Only one should be a register");
57 }
58
59 DecoratorSet ZLoadBarrierStubC1::decorators() const {
60 return _decorators;
61 }
62
63 LIR_Opr ZLoadBarrierStubC1::ref() const {
64 return _ref;
65 }
66
67 LIR_Opr ZLoadBarrierStubC1::ref_addr() const {
68 return _ref_addr;
69 }
70
71 LIR_Opr ZLoadBarrierStubC1::tmp() const {
72 return _tmp;
73 }
74
75 LIR_PatchCode ZLoadBarrierStubC1::patch_code() const {
76 return (_decorators & C1_NEEDS_PATCHING) != 0 ? lir_patch_normal : lir_patch_none;
77 }
78
79 CodeEmitInfo*& ZLoadBarrierStubC1::patch_info() {
80 return _patch_info;
81 }
82
83 address ZLoadBarrierStubC1::runtime_stub() const {
84 return _runtime_stub;
85 }
86
87 void ZLoadBarrierStubC1::visit(LIR_OpVisitState* visitor) {
88 if (_patch_info != NULL) {
89 visitor->do_slow_case(_patch_info);
90 } else {
91 visitor->do_slow_case();
92 }
93
94 visitor->do_input(_ref_addr);
95 visitor->do_output(_ref);
96
97 if (_tmp->is_valid()) {
98 visitor->do_temp(_tmp);
99 }
100 }
101
102 void ZLoadBarrierStubC1::emit_code(LIR_Assembler* ce) {
103 ZBarrierSet::assembler()->generate_c1_load_barrier_stub(ce, this);
104 }
105
106 #ifndef PRODUCT
107 void ZLoadBarrierStubC1::print_name(outputStream* out) const {
108 out->print("ZLoadBarrierStubC1");
109 }
110 #endif // PRODUCT
111
112 class LIR_OpZLoadBarrierTest : public LIR_Op {
113 private:
114 LIR_Opr _opr;
115
116 public:
155 } else {
156 return _load_barrier_on_oop_field_preloaded_runtime_stub;
157 }
158 }
159
160 #ifdef ASSERT
161 #define __ access.gen()->lir(__FILE__, __LINE__)->
162 #else
163 #define __ access.gen()->lir()->
164 #endif
165
166 void ZBarrierSetC1::load_barrier(LIRAccess& access, LIR_Opr result) const {
167 // Fast path
168 __ append(new LIR_OpZLoadBarrierTest(result));
169
170 // Slow path
171 const address runtime_stub = load_barrier_on_oop_field_preloaded_runtime_stub(access.decorators());
172 CodeStub* const stub = new ZLoadBarrierStubC1(access, result, runtime_stub);
173 __ branch(lir_cond_notEqual, T_ADDRESS, stub);
174 __ branch_destination(stub->continuation());
175 }
176
177 #undef __
178
179 void ZBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
180 BarrierSetC1::load_at_resolved(access, result);
181
182 if (barrier_needed(access)) {
183 load_barrier(access, result);
184 }
185 }
186
187 static void pre_load_barrier(LIRAccess& access) {
188 DecoratorSet decorators = access.decorators();
189
190 // Downgrade access to MO_UNORDERED
191 decorators = (decorators & ~MO_DECORATOR_MASK) | MO_UNORDERED;
192
193 // Remove ACCESS_WRITE
194 decorators = (decorators & ~ACCESS_WRITE);
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include "precompiled.hpp"
25 #include "c1/c1_LIR.hpp"
26 #include "c1/c1_LIRGenerator.hpp"
27 #include "c1/c1_CodeStubs.hpp"
28 #include "gc/z/c1/zBarrierSetC1.hpp"
29 #include "gc/z/zBarrierSet.hpp"
30 #include "gc/z/zBarrierSetAssembler.hpp"
31 #include "gc/z/zThreadLocalData.hpp"
32 #include "utilities/macros.hpp"
33
34 ZLoadBarrierStubC1::ZLoadBarrierStubC1(LIRAccess& access, LIR_Opr ref, address runtime_stub) :
35 _decorators(access.decorators()),
36 _ref_addr(access.resolved_addr()),
37 _ref(ref),
38 _tmp(LIR_OprFact::illegalOpr),
39 _runtime_stub(runtime_stub) {
40
41 // Allocate tmp register if needed
42 if (!_ref_addr->is_register()) {
43 assert(_ref_addr->is_address(), "Must be an address");
44 if (_ref_addr->as_address_ptr()->index()->is_valid() ||
45 _ref_addr->as_address_ptr()->disp() != 0) {
46 // Has index or displacement, need tmp register to load address into
47 _tmp = access.gen()->new_pointer_register();
48 } else {
49 // No index or displacement, address available in base register
50 _ref_addr = _ref_addr->as_address_ptr()->base();
51 }
52 }
53
54 assert(_ref->is_register(), "Must be a register");
55 assert(_ref_addr->is_register() != _tmp->is_register(), "Only one should be a register");
56 }
57
58 DecoratorSet ZLoadBarrierStubC1::decorators() const {
59 return _decorators;
60 }
61
62 LIR_Opr ZLoadBarrierStubC1::ref() const {
63 return _ref;
64 }
65
66 LIR_Opr ZLoadBarrierStubC1::ref_addr() const {
67 return _ref_addr;
68 }
69
70 LIR_Opr ZLoadBarrierStubC1::tmp() const {
71 return _tmp;
72 }
73
74 address ZLoadBarrierStubC1::runtime_stub() const {
75 return _runtime_stub;
76 }
77
78 void ZLoadBarrierStubC1::visit(LIR_OpVisitState* visitor) {
79 visitor->do_slow_case();
80 visitor->do_input(_ref_addr);
81 visitor->do_output(_ref);
82 if (_tmp->is_valid()) {
83 visitor->do_temp(_tmp);
84 }
85 }
86
87 void ZLoadBarrierStubC1::emit_code(LIR_Assembler* ce) {
88 ZBarrierSet::assembler()->generate_c1_load_barrier_stub(ce, this);
89 }
90
91 #ifndef PRODUCT
92 void ZLoadBarrierStubC1::print_name(outputStream* out) const {
93 out->print("ZLoadBarrierStubC1");
94 }
95 #endif // PRODUCT
96
97 class LIR_OpZLoadBarrierTest : public LIR_Op {
98 private:
99 LIR_Opr _opr;
100
101 public:
140 } else {
141 return _load_barrier_on_oop_field_preloaded_runtime_stub;
142 }
143 }
144
145 #ifdef ASSERT
146 #define __ access.gen()->lir(__FILE__, __LINE__)->
147 #else
148 #define __ access.gen()->lir()->
149 #endif
150
151 void ZBarrierSetC1::load_barrier(LIRAccess& access, LIR_Opr result) const {
152 // Fast path
153 __ append(new LIR_OpZLoadBarrierTest(result));
154
155 // Slow path
156 const address runtime_stub = load_barrier_on_oop_field_preloaded_runtime_stub(access.decorators());
157 CodeStub* const stub = new ZLoadBarrierStubC1(access, result, runtime_stub);
158 __ branch(lir_cond_notEqual, T_ADDRESS, stub);
159 __ branch_destination(stub->continuation());
160 }
161
162 LIR_Opr ZBarrierSetC1::resolve_address(LIRAccess& access, bool resolve_in_register) {
163 // We must resolve in register when patching. This is to avoid
164 // having a patch area in the load barrier stub, since the call
165 // into the runtime to patch will not have the proper oop map.
166 const bool patch_before_barrier = barrier_needed(access) && (access.decorators() & C1_NEEDS_PATCHING) != 0;
167 return BarrierSetC1::resolve_address(access, resolve_in_register || patch_before_barrier);
168 }
169
170 #undef __
171
172 void ZBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
173 BarrierSetC1::load_at_resolved(access, result);
174
175 if (barrier_needed(access)) {
176 load_barrier(access, result);
177 }
178 }
179
180 static void pre_load_barrier(LIRAccess& access) {
181 DecoratorSet decorators = access.decorators();
182
183 // Downgrade access to MO_UNORDERED
184 decorators = (decorators & ~MO_DECORATOR_MASK) | MO_UNORDERED;
185
186 // Remove ACCESS_WRITE
187 decorators = (decorators & ~ACCESS_WRITE);
|