47 const DecoratorSet C2_UNSAFE_ACCESS = DECORATOR_LAST << 6; |
47 const DecoratorSet C2_UNSAFE_ACCESS = DECORATOR_LAST << 6; |
48 // This denotes that the access mutates state. |
48 // This denotes that the access mutates state. |
49 const DecoratorSet C2_WRITE_ACCESS = DECORATOR_LAST << 7; |
49 const DecoratorSet C2_WRITE_ACCESS = DECORATOR_LAST << 7; |
50 // This denotes that the access reads state. |
50 // This denotes that the access reads state. |
51 const DecoratorSet C2_READ_ACCESS = DECORATOR_LAST << 8; |
51 const DecoratorSet C2_READ_ACCESS = DECORATOR_LAST << 8; |
|
52 // A nearby allocation? |
|
53 const DecoratorSet C2_TIGHLY_COUPLED_ALLOC = DECORATOR_LAST << 9; |
|
54 // Loads and stores from an arraycopy being optimized |
|
55 const DecoratorSet C2_ARRAY_COPY = DECORATOR_LAST << 10; |
52 |
56 |
53 class GraphKit; |
57 class GraphKit; |
54 class IdealKit; |
58 class IdealKit; |
55 class Node; |
59 class Node; |
56 class Type; |
60 class Type; |
86 |
90 |
87 // This class wraps a bunch of context parameters thare are passed around in the |
91 // This class wraps a bunch of context parameters thare are passed around in the |
88 // BarrierSetC2 backend hierarchy, for loads and stores, to reduce boiler plate. |
92 // BarrierSetC2 backend hierarchy, for loads and stores, to reduce boiler plate. |
89 class C2Access: public StackObj { |
93 class C2Access: public StackObj { |
90 protected: |
94 protected: |
91 GraphKit* _kit; |
|
92 DecoratorSet _decorators; |
95 DecoratorSet _decorators; |
93 BasicType _type; |
96 BasicType _type; |
94 Node* _base; |
97 Node* _base; |
95 C2AccessValuePtr& _addr; |
98 C2AccessValuePtr& _addr; |
96 Node* _raw_access; |
99 Node* _raw_access; |
97 |
100 |
98 void fixup_decorators(); |
101 void fixup_decorators(); |
99 void* barrier_set_state() const; |
102 |
100 |
103 public: |
101 public: |
104 C2Access(DecoratorSet decorators, |
102 C2Access(GraphKit* kit, DecoratorSet decorators, |
|
103 BasicType type, Node* base, C2AccessValuePtr& addr) : |
105 BasicType type, Node* base, C2AccessValuePtr& addr) : |
104 _kit(kit), |
|
105 _decorators(decorators), |
106 _decorators(decorators), |
106 _type(type), |
107 _type(type), |
107 _base(base), |
108 _base(base), |
108 _addr(addr), |
109 _addr(addr), |
109 _raw_access(NULL) |
110 _raw_access(NULL) |
110 { |
111 {} |
111 fixup_decorators(); |
112 |
112 } |
|
113 |
|
114 GraphKit* kit() const { return _kit; } |
|
115 DecoratorSet decorators() const { return _decorators; } |
113 DecoratorSet decorators() const { return _decorators; } |
116 Node* base() const { return _base; } |
114 Node* base() const { return _base; } |
117 C2AccessValuePtr& addr() const { return _addr; } |
115 C2AccessValuePtr& addr() const { return _addr; } |
118 BasicType type() const { return _type; } |
116 BasicType type() const { return _type; } |
119 bool is_oop() const { return _type == T_OBJECT || _type == T_ARRAY; } |
117 bool is_oop() const { return _type == T_OBJECT || _type == T_ARRAY; } |
124 virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses. |
122 virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses. |
125 |
123 |
126 MemNode::MemOrd mem_node_mo() const; |
124 MemNode::MemOrd mem_node_mo() const; |
127 bool needs_cpu_membar() const; |
125 bool needs_cpu_membar() const; |
128 |
126 |
|
127 virtual PhaseGVN& gvn() const = 0; |
|
128 virtual bool is_parse_access() const { return false; } |
|
129 virtual bool is_opt_access() const { return false; } |
|
130 }; |
|
131 |
|
132 // C2Access for parse time calls to the BarrierSetC2 backend. |
|
133 class C2ParseAccess: public C2Access { |
|
134 protected: |
|
135 GraphKit* _kit; |
|
136 |
|
137 void* barrier_set_state() const; |
|
138 |
|
139 public: |
|
140 C2ParseAccess(GraphKit* kit, DecoratorSet decorators, |
|
141 BasicType type, Node* base, C2AccessValuePtr& addr) : |
|
142 C2Access(decorators, type, base, addr), |
|
143 _kit(kit) { |
|
144 fixup_decorators(); |
|
145 } |
|
146 |
|
147 GraphKit* kit() const { return _kit; } |
|
148 |
129 template <typename T> |
149 template <typename T> |
130 T barrier_set_state_as() const { |
150 T barrier_set_state_as() const { |
131 return reinterpret_cast<T>(barrier_set_state()); |
151 return reinterpret_cast<T>(barrier_set_state()); |
132 } |
152 } |
|
153 |
|
154 virtual PhaseGVN& gvn() const; |
|
155 virtual bool is_parse_access() const { return true; } |
133 }; |
156 }; |
134 |
157 |
135 // This class wraps a bunch of context parameters thare are passed around in the |
158 // This class wraps a bunch of context parameters thare are passed around in the |
136 // BarrierSetC2 backend hierarchy, for atomic accesses, to reduce boiler plate. |
159 // BarrierSetC2 backend hierarchy, for atomic accesses, to reduce boiler plate. |
137 class C2AtomicAccess: public C2Access { |
160 class C2AtomicParseAccess: public C2ParseAccess { |
138 Node* _memory; |
161 Node* _memory; |
139 uint _alias_idx; |
162 uint _alias_idx; |
140 bool _needs_pinning; |
163 bool _needs_pinning; |
141 |
164 |
142 public: |
165 public: |
143 C2AtomicAccess(GraphKit* kit, DecoratorSet decorators, BasicType type, |
166 C2AtomicParseAccess(GraphKit* kit, DecoratorSet decorators, BasicType type, |
144 Node* base, C2AccessValuePtr& addr, uint alias_idx) : |
167 Node* base, C2AccessValuePtr& addr, uint alias_idx) : |
145 C2Access(kit, decorators, type, base, addr), |
168 C2ParseAccess(kit, decorators, type, base, addr), |
146 _memory(NULL), |
169 _memory(NULL), |
147 _alias_idx(alias_idx), |
170 _alias_idx(alias_idx), |
148 _needs_pinning(true) {} |
171 _needs_pinning(true) {} |
149 |
172 |
150 // Set the memory node based on the current memory slice. |
173 // Set the memory node based on the current memory slice. |
154 uint alias_idx() const { return _alias_idx; } |
177 uint alias_idx() const { return _alias_idx; } |
155 bool needs_pinning() const { return _needs_pinning; } |
178 bool needs_pinning() const { return _needs_pinning; } |
156 |
179 |
157 void set_needs_pinning(bool value) { _needs_pinning = value; } |
180 void set_needs_pinning(bool value) { _needs_pinning = value; } |
158 }; |
181 }; |
|
182 |
|
183 // C2Access for optimization time calls to the BarrierSetC2 backend. |
|
184 class C2OptAccess: public C2Access { |
|
185 PhaseGVN& _gvn; |
|
186 MergeMemNode* _mem; |
|
187 Node* _ctl; |
|
188 |
|
189 public: |
|
190 C2OptAccess(PhaseGVN& gvn, Node* ctl, MergeMemNode* mem, DecoratorSet decorators, |
|
191 BasicType type, Node* base, C2AccessValuePtr& addr) : |
|
192 C2Access(decorators, type, base, addr), |
|
193 _gvn(gvn), _mem(mem), _ctl(ctl) { |
|
194 fixup_decorators(); |
|
195 } |
|
196 |
|
197 |
|
198 MergeMemNode* mem() const { return _mem; } |
|
199 Node* ctl() const { return _ctl; } |
|
200 // void set_mem(Node* mem) { _mem = mem; } |
|
201 void set_ctl(Node* ctl) { _ctl = ctl; } |
|
202 |
|
203 virtual PhaseGVN& gvn() const { return _gvn; } |
|
204 virtual bool is_opt_access() const { return true; } |
|
205 }; |
|
206 |
159 |
207 |
160 // This is the top-level class for the backend of the Access API in C2. |
208 // This is the top-level class for the backend of the Access API in C2. |
161 // The top-level class is responsible for performing raw accesses. The |
209 // The top-level class is responsible for performing raw accesses. The |
162 // various GC barrier sets inherit from the BarrierSetC2 class to sprinkle |
210 // various GC barrier sets inherit from the BarrierSetC2 class to sprinkle |
163 // barriers into the accesses. |
211 // barriers into the accesses. |
165 protected: |
213 protected: |
166 virtual void resolve_address(C2Access& access) const; |
214 virtual void resolve_address(C2Access& access) const; |
167 virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; |
215 virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; |
168 virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const; |
216 virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const; |
169 |
217 |
170 virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val, |
218 virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, |
171 Node* new_val, const Type* val_type) const; |
219 Node* new_val, const Type* val_type) const; |
172 virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val, |
220 virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, |
173 Node* new_val, const Type* value_type) const; |
221 Node* new_val, const Type* value_type) const; |
174 virtual Node* atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const; |
222 virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const; |
175 virtual Node* atomic_add_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const; |
223 virtual Node* atomic_add_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const; |
176 void pin_atomic_op(C2AtomicAccess& access) const; |
224 void pin_atomic_op(C2AtomicParseAccess& access) const; |
177 |
225 |
178 public: |
226 public: |
179 // This is the entry-point for the backend to perform accesses through the Access API. |
227 // This is the entry-point for the backend to perform accesses through the Access API. |
180 virtual Node* store_at(C2Access& access, C2AccessValue& val) const; |
228 virtual Node* store_at(C2Access& access, C2AccessValue& val) const; |
181 virtual Node* load_at(C2Access& access, const Type* val_type) const; |
229 virtual Node* load_at(C2Access& access, const Type* val_type) const; |
182 |
230 |
183 virtual Node* atomic_cmpxchg_val_at(C2AtomicAccess& access, Node* expected_val, |
231 virtual Node* atomic_cmpxchg_val_at(C2AtomicParseAccess& access, Node* expected_val, |
184 Node* new_val, const Type* val_type) const; |
232 Node* new_val, const Type* val_type) const; |
185 virtual Node* atomic_cmpxchg_bool_at(C2AtomicAccess& access, Node* expected_val, |
233 virtual Node* atomic_cmpxchg_bool_at(C2AtomicParseAccess& access, Node* expected_val, |
186 Node* new_val, const Type* val_type) const; |
234 Node* new_val, const Type* val_type) const; |
187 virtual Node* atomic_xchg_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const; |
235 virtual Node* atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; |
188 virtual Node* atomic_add_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const; |
236 virtual Node* atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; |
189 |
237 |
190 virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const; |
238 virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const; |
191 |
239 |
192 virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; } |
240 virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; } |
193 |
241 |
201 Parsing, |
249 Parsing, |
202 Optimization, |
250 Optimization, |
203 Expansion |
251 Expansion |
204 }; |
252 }; |
205 virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const { return false; } |
253 virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const { return false; } |
|
254 virtual void clone_barrier_at_expansion(ArrayCopyNode* ac, Node* call, PhaseIterGVN& igvn) const; |
206 |
255 |
207 // Support for GC barriers emitted during parsing |
256 // Support for GC barriers emitted during parsing |
208 virtual bool has_load_barriers() const { return false; } |
257 virtual bool has_load_barriers() const { return false; } |
209 virtual bool is_gc_barrier_node(Node* node) const { return false; } |
258 virtual bool is_gc_barrier_node(Node* node) const { return false; } |
210 virtual Node* step_over_gc_barrier(Node* c) const { return c; } |
259 virtual Node* step_over_gc_barrier(Node* c) const { return c; } |