19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP
25 #define SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP
26
27 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
28 #include "memory/allocation.hpp"
29 #include "opto/addnode.hpp"
30 #include "opto/graphKit.hpp"
31 #include "opto/machnode.hpp"
32 #include "opto/memnode.hpp"
33 #include "opto/multnode.hpp"
34 #include "opto/node.hpp"
35
36 class PhaseGVN;
37 class MemoryGraphFixer;
38
39 class ShenandoahBarrierNode : public TypeNode {
40 private:
41 bool _allow_fromspace;
42
43 #ifdef ASSERT
44 enum verify_type {
45 ShenandoahLoad,
46 ShenandoahStore,
47 ShenandoahValue,
48 ShenandoahOopStore,
49 ShenandoahNone,
50 };
51
52 static bool verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used);
53 #endif
54
55 public:
56 enum { Control,
57 Memory,
58 ValueIn
59 };
60
61 ShenandoahBarrierNode(Node* ctrl, Node* mem, Node* obj, bool allow_fromspace)
62 : TypeNode(obj->bottom_type()->isa_oopptr() ? obj->bottom_type()->is_oopptr()->cast_to_nonconst() : obj->bottom_type(), 3),
63 _allow_fromspace(allow_fromspace) {
64
65 init_req(Control, ctrl);
66 init_req(Memory, mem);
67 init_req(ValueIn, obj);
68
69 init_class_id(Class_ShenandoahBarrier);
70 }
71
72 static Node* skip_through_barrier(Node* n);
73
74 static const TypeOopPtr* brooks_pointer_type(const Type* t) {
75 return t->is_oopptr()->cast_to_nonconst()->add_offset(ShenandoahBrooksPointer::byte_offset())->is_oopptr();
76 }
77
78 virtual const TypePtr* adr_type() const {
79 if (bottom_type() == Type::TOP) {
80 return NULL;
81 }
82 //const TypePtr* adr_type = in(MemNode::Address)->bottom_type()->is_ptr();
83 const TypePtr* adr_type = brooks_pointer_type(bottom_type());
84 assert(adr_type->offset() == ShenandoahBrooksPointer::byte_offset(), "sane offset");
85 assert(Compile::current()->alias_type(adr_type)->is_rewritable(), "brooks ptr must be rewritable");
86 return adr_type;
87 }
88
89 virtual uint ideal_reg() const { return Op_RegP; }
90 virtual uint match_edge(uint idx) const {
91 return idx >= ValueIn;
92 }
93
94 Node* Identity_impl(PhaseGVN* phase);
95
96 virtual const Type* Value(PhaseGVN* phase) const;
97 virtual bool depends_only_on_test() const {
98 return true;
99 };
100
101 static bool needs_barrier(PhaseGVN* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace);
102
103 #ifdef ASSERT
104 static void report_verify_failure(const char* msg, Node* n1 = NULL, Node* n2 = NULL);
105 static void verify(RootNode* root);
106 static void verify_raw_mem(RootNode* root);
107 #endif
108 #ifndef PRODUCT
109 virtual void dump_spec(outputStream *st) const;
110 #endif
111
112 // protected:
113 static Node* dom_mem(Node* mem, Node*& mem_ctrl, Node* n, Node* rep_ctrl, int alias, PhaseIdealLoop* phase);
114 static Node* dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase);
115 static bool is_dominator(Node *d_c, Node *n_c, Node* d, Node* n, PhaseIdealLoop* phase);
116 static bool is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase);
117 static Node* no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase);
118 static bool build_loop_late_post(PhaseIdealLoop* phase, Node* n);
119 bool sink_node(PhaseIdealLoop* phase, Node* ctrl, Node* n_ctrl);
120
121 protected:
122 uint hash() const;
123 bool cmp(const Node& n) const;
124 uint size_of() const;
125
126 private:
127 static bool needs_barrier_impl(PhaseGVN* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace, Unique_Node_List &visited);
128
129 static bool dominates_memory(PhaseGVN* phase, Node* b1, Node* b2, bool linear);
130 static bool dominates_memory_impl(PhaseGVN* phase, Node* b1, Node* b2, Node* current, bool linear);
131 };
132
133 class ShenandoahReadBarrierNode : public ShenandoahBarrierNode {
134 public:
135 ShenandoahReadBarrierNode(Node* ctrl, Node* mem, Node* obj)
136 : ShenandoahBarrierNode(ctrl, mem, obj, true) {
137 assert(UseShenandoahGC && (ShenandoahReadBarrier || ShenandoahStoreValReadBarrier ||
138 ShenandoahWriteBarrier || ShenandoahAcmpBarrier),
139 "should be enabled");
140 }
141 ShenandoahReadBarrierNode(Node* ctrl, Node* mem, Node* obj, bool allow_fromspace)
142 : ShenandoahBarrierNode(ctrl, mem, obj, allow_fromspace) {
143 assert(UseShenandoahGC && (ShenandoahReadBarrier || ShenandoahStoreValReadBarrier ||
144 ShenandoahWriteBarrier || ShenandoahAcmpBarrier),
145 "should be enabled");
146 }
147
148 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
149 virtual Node* Identity(PhaseGVN* phase);
150 virtual int Opcode() const;
151
152 bool is_independent(Node* mem);
153
154 void try_move(PhaseIdealLoop* phase);
155
156 private:
157 static bool is_independent(const Type* in_type, const Type* this_type);
158 static bool dominates_memory_rb(PhaseGVN* phase, Node* b1, Node* b2, bool linear);
159 static bool dominates_memory_rb_impl(PhaseGVN* phase, Node* b1, Node* b2, Node* current, bool linear);
160 };
161
162 class ShenandoahWriteBarrierNode : public ShenandoahBarrierNode {
163 public:
164 ShenandoahWriteBarrierNode(Compile* C, Node* ctrl, Node* mem, Node* obj);
165
166 virtual int Opcode() const;
167 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
168 virtual Node* Identity(PhaseGVN* phase);
169 virtual bool depends_only_on_test() const { return false; }
170
171 static bool expand(Compile* C, PhaseIterGVN& igvn);
172 static bool is_gc_state_load(Node *n);
173 static bool is_heap_state_test(Node* iff, int mask);
174 static bool is_heap_stable_test(Node* iff);
175 static bool try_common_gc_state_load(Node *n, PhaseIdealLoop *phase);
176 static bool has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase);
177
178 static LoopNode* try_move_before_pre_loop(Node* c, Node* val_ctrl, PhaseIdealLoop* phase);
179 static Node* move_above_predicates(LoopNode* cl, Node* val_ctrl, PhaseIdealLoop* phase);
180 #ifdef ASSERT
181 static bool memory_dominates_all_paths(Node* mem, Node* rep_ctrl, int alias, PhaseIdealLoop* phase);
182 static void memory_dominates_all_paths_helper(Node* c, Node* rep_ctrl, Unique_Node_List& controls, PhaseIdealLoop* phase);
183 #endif
184 void try_move_before_loop(GrowableArray<MemoryGraphFixer*>& memory_graph_fixers, PhaseIdealLoop* phase, bool include_lsm, Unique_Node_List& uses);
185 void try_move_before_loop_helper(LoopNode* cl, Node* val_ctrl, GrowableArray<MemoryGraphFixer*>& memory_graph_fixers, PhaseIdealLoop* phase, bool include_lsm, Unique_Node_List& uses);
186 static void pin_and_expand(PhaseIdealLoop* phase);
187 CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn);
188 void pin_and_expand_move_barrier(PhaseIdealLoop* phase, GrowableArray<MemoryGraphFixer*>& memory_graph_fixers, Unique_Node_List& uses);
189 void pin_and_expand_helper(PhaseIdealLoop* phase);
190 static Node* find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase);
191 static void follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase);
192 static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
193
194 static void test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
195 PhaseIdealLoop* phase);
196 static void call_wb_stub(Node*& ctrl, Node*& val, Node*& result_mem,
197 Node* raw_mem, Node* wb_mem, int alias,
198 PhaseIdealLoop* phase);
199 static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
200 static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
201 PhaseIdealLoop* phase);
202 static void in_cset_fast_test(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
203 static void move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
204
205 static void optimize_after_expansion(VectorSet &visited, Node_Stack &nstack, Node_List &old_new, PhaseIdealLoop* phase);
206 static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
207 static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase);
208 static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
209
210 static void optimize_before_expansion(PhaseIdealLoop* phase, GrowableArray<MemoryGraphFixer*> memory_graph_fixers, bool include_lsm);
211 Node* would_subsume(ShenandoahBarrierNode* other, PhaseIdealLoop* phase);
212 static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase);
213
214 Node* try_split_thru_phi(PhaseIdealLoop* phase);
215 };
216
217 class ShenandoahWBMemProjNode : public Node {
218 public:
219 enum { Control,
220 WriteBarrier };
221
222 ShenandoahWBMemProjNode(Node *src) : Node(NULL, src) {
223 assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled");
224 assert(src->Opcode() == Op_ShenandoahWriteBarrier || src->is_Mach(), "epxect wb");
225 }
226 virtual Node* Identity(PhaseGVN* phase);
227
228 virtual int Opcode() const;
229 virtual bool is_CFG() const { return false; }
230 virtual const Type *bottom_type() const {return Type::MEMORY;}
231 virtual const TypePtr *adr_type() const {
232 Node* wb = in(WriteBarrier);
233 if (wb == NULL || wb->is_top()) return NULL; // node is dead
234 assert(wb->Opcode() == Op_ShenandoahWriteBarrier || (wb->is_Mach() && wb->as_Mach()->ideal_Opcode() == Op_ShenandoahWriteBarrier) || wb->is_Phi(), "expect wb");
235 return ShenandoahBarrierNode::brooks_pointer_type(wb->bottom_type());
236 }
237
238 virtual uint ideal_reg() const { return 0;} // memory projections don't have a register
239 virtual const Type *Value(PhaseGVN* phase ) const {
240 return bottom_type();
241 }
242 #ifndef PRODUCT
243 virtual void dump_spec(outputStream *st) const {};
244 #endif
245 };
246
247 class ShenandoahEnqueueBarrierNode : public Node {
248 public:
249 ShenandoahEnqueueBarrierNode(Node* val) : Node(NULL, val) {
250 }
251
252 const Type *bottom_type() const;
253 const Type* Value(PhaseGVN* phase) const;
254 Node* Identity(PhaseGVN* phase);
255
256 int Opcode() const;
257
258 private:
259 enum { Needed, NotNeeded, MaybeNeeded };
260
261 static int needed(Node* n);
262 static Node* next(Node* n);
263 };
264
265 class MemoryGraphFixer : public ResourceObj {
266 private:
267 Node_List _memory_nodes;
268 int _alias;
269 PhaseIdealLoop* _phase;
270 bool _include_lsm;
272 void collect_memory_nodes();
273 Node* get_ctrl(Node* n) const;
274 Node* ctrl_or_self(Node* n) const;
275 bool mem_is_valid(Node* m, Node* c) const;
276 MergeMemNode* allocate_merge_mem(Node* mem, Node* rep_proj, Node* rep_ctrl) const;
277 MergeMemNode* clone_merge_mem(Node* u, Node* mem, Node* rep_proj, Node* rep_ctrl, DUIterator& i) const;
278 void fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl) const;
279 bool should_process_phi(Node* phi) const;
280 bool has_mem_phi(Node* region) const;
281
282 public:
283 MemoryGraphFixer(int alias, bool include_lsm, PhaseIdealLoop* phase) :
284 _alias(alias), _phase(phase), _include_lsm(include_lsm) {
285 assert(_alias != Compile::AliasIdxBot, "unsupported");
286 collect_memory_nodes();
287 }
288
289 Node* find_mem(Node* ctrl, Node* n) const;
290 void fix_mem(Node* ctrl, Node* region, Node* mem, Node* mem_for_ctrl, Node* mem_phi, Unique_Node_List& uses);
291 int alias() const { return _alias; }
292 void remove(Node* n);
293 };
294
295 class ShenandoahCompareAndSwapPNode : public CompareAndSwapPNode {
296 public:
297 ShenandoahCompareAndSwapPNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord)
298 : CompareAndSwapPNode(c, mem, adr, val, ex, mem_ord) { }
299
300 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
301 if (in(ExpectedIn) != NULL && phase->type(in(ExpectedIn)) == TypePtr::NULL_PTR) {
302 return new CompareAndSwapPNode(in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), in(MemNode::ValueIn), in(ExpectedIn), order());
303 }
304 return NULL;
305 }
306
307 virtual int Opcode() const;
308 };
309
310 class ShenandoahCompareAndSwapNNode : public CompareAndSwapNNode {
311 public:
312 ShenandoahCompareAndSwapNNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord)
364 return NULL;
365 }
366
367 virtual int Opcode() const;
368 };
369
370 class ShenandoahCompareAndExchangeNNode : public CompareAndExchangeNNode {
371 public:
372 ShenandoahCompareAndExchangeNNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, const Type* t, MemNode::MemOrd mem_ord)
373 : CompareAndExchangeNNode(c, mem, adr, val, ex, at, t, mem_ord) { }
374
375 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
376 if (in(ExpectedIn) != NULL && phase->type(in(ExpectedIn)) == TypeNarrowOop::NULL_PTR) {
377 return new CompareAndExchangeNNode(in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), in(MemNode::ValueIn), in(ExpectedIn), adr_type(), bottom_type(), order());
378 }
379 return NULL;
380 }
381
382 virtual int Opcode() const;
383 };
384
385 #endif // SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP
|
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP
25 #define SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP
26
27 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
28 #include "memory/allocation.hpp"
29 #include "opto/addnode.hpp"
30 #include "opto/graphKit.hpp"
31 #include "opto/machnode.hpp"
32 #include "opto/memnode.hpp"
33 #include "opto/multnode.hpp"
34 #include "opto/node.hpp"
35
36 class PhaseGVN;
37 class MemoryGraphFixer;
38
39 class ShenandoahBarrierC2Support : public AllStatic {
40 private:
41 #ifdef ASSERT
42 enum verify_type {
43 ShenandoahLoad,
44 ShenandoahStore,
45 ShenandoahValue,
46 ShenandoahOopStore,
47 ShenandoahNone,
48 };
49
50 static bool verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used);
51 static void report_verify_failure(const char* msg, Node* n1 = NULL, Node* n2 = NULL);
52 static void verify_raw_mem(RootNode* root);
53 #endif
54 static Node* dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase);
55 static Node* no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase);
56 static bool is_heap_state_test(Node* iff, int mask);
57 static bool try_common_gc_state_load(Node *n, PhaseIdealLoop *phase);
58 static bool has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase);
59 static Node* find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase);
60 static void follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase);
61 static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
62 static void test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
63 PhaseIdealLoop* phase);
64 static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase);
65 static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
66 static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
67 PhaseIdealLoop* phase);
68 static void in_cset_fast_test(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
69 static void move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
70 static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
71 static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase);
72 static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
73 static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase);
74
75 public:
76 static bool is_dominator(Node* d_c, Node* n_c, Node* d, Node* n, PhaseIdealLoop* phase);
77 static bool is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase);
78
79 static bool is_gc_state_load(Node* n);
80 static bool is_heap_stable_test(Node* iff);
81
82 static bool expand(Compile* C, PhaseIterGVN& igvn);
83 static void pin_and_expand(PhaseIdealLoop* phase);
84 static void optimize_after_expansion(VectorSet& visited, Node_Stack& nstack, Node_List& old_new, PhaseIdealLoop* phase);
85
86 #ifdef ASSERT
87 static void verify(RootNode* root);
88 #endif
89 };
90
91 class ShenandoahEnqueueBarrierNode : public Node {
92 public:
93 ShenandoahEnqueueBarrierNode(Node* val);
94
95 const Type *bottom_type() const;
96 const Type* Value(PhaseGVN* phase) const;
97 Node* Identity(PhaseGVN* phase);
98
99 int Opcode() const;
100
101 private:
102 enum { Needed, NotNeeded, MaybeNeeded };
103
104 static int needed(Node* n);
105 static Node* next(Node* n);
106 };
107
108 class MemoryGraphFixer : public ResourceObj {
109 private:
110 Node_List _memory_nodes;
111 int _alias;
112 PhaseIdealLoop* _phase;
113 bool _include_lsm;
115 void collect_memory_nodes();
116 Node* get_ctrl(Node* n) const;
117 Node* ctrl_or_self(Node* n) const;
118 bool mem_is_valid(Node* m, Node* c) const;
119 MergeMemNode* allocate_merge_mem(Node* mem, Node* rep_proj, Node* rep_ctrl) const;
120 MergeMemNode* clone_merge_mem(Node* u, Node* mem, Node* rep_proj, Node* rep_ctrl, DUIterator& i) const;
121 void fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl) const;
122 bool should_process_phi(Node* phi) const;
123 bool has_mem_phi(Node* region) const;
124
125 public:
126 MemoryGraphFixer(int alias, bool include_lsm, PhaseIdealLoop* phase) :
127 _alias(alias), _phase(phase), _include_lsm(include_lsm) {
128 assert(_alias != Compile::AliasIdxBot, "unsupported");
129 collect_memory_nodes();
130 }
131
132 Node* find_mem(Node* ctrl, Node* n) const;
133 void fix_mem(Node* ctrl, Node* region, Node* mem, Node* mem_for_ctrl, Node* mem_phi, Unique_Node_List& uses);
134 int alias() const { return _alias; }
135 };
136
137 class ShenandoahCompareAndSwapPNode : public CompareAndSwapPNode {
138 public:
139 ShenandoahCompareAndSwapPNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord)
140 : CompareAndSwapPNode(c, mem, adr, val, ex, mem_ord) { }
141
142 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
143 if (in(ExpectedIn) != NULL && phase->type(in(ExpectedIn)) == TypePtr::NULL_PTR) {
144 return new CompareAndSwapPNode(in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), in(MemNode::ValueIn), in(ExpectedIn), order());
145 }
146 return NULL;
147 }
148
149 virtual int Opcode() const;
150 };
151
152 class ShenandoahCompareAndSwapNNode : public CompareAndSwapNNode {
153 public:
154 ShenandoahCompareAndSwapNNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord)
206 return NULL;
207 }
208
209 virtual int Opcode() const;
210 };
211
212 class ShenandoahCompareAndExchangeNNode : public CompareAndExchangeNNode {
213 public:
214 ShenandoahCompareAndExchangeNNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, const Type* t, MemNode::MemOrd mem_ord)
215 : CompareAndExchangeNNode(c, mem, adr, val, ex, at, t, mem_ord) { }
216
217 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
218 if (in(ExpectedIn) != NULL && phase->type(in(ExpectedIn)) == TypeNarrowOop::NULL_PTR) {
219 return new CompareAndExchangeNNode(in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), in(MemNode::ValueIn), in(ExpectedIn), adr_type(), bottom_type(), order());
220 }
221 return NULL;
222 }
223
224 virtual int Opcode() const;
225 };
226
227 class ShenandoahLoadReferenceBarrierNode : public Node {
228 public:
229 enum {
230 Control,
231 ValueIn
232 };
233
234 enum Strength {
235 NONE, WEAK, STRONG, NA
236 };
237
238 ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val);
239
240 virtual int Opcode() const;
241 virtual const Type* bottom_type() const;
242 virtual const Type* Value(PhaseGVN* phase) const;
243 virtual const class TypePtr *adr_type() const { return TypeOopPtr::BOTTOM; }
244 virtual uint match_edge(uint idx) const {
245 return idx >= ValueIn;
246 }
247 virtual uint ideal_reg() const { return Op_RegP; }
248
249 virtual Node* Identity(PhaseGVN* phase);
250
251 uint size_of() const {
252 return sizeof(*this);
253 }
254
255 Strength get_barrier_strength();
256 CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn);
257
258 private:
259 bool needs_barrier(PhaseGVN* phase, Node* n);
260 bool needs_barrier_impl(PhaseGVN* phase, Node* n, Unique_Node_List &visited);
261 };
262
263
264 #endif // SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP
|