176 _type = ntype; |
176 _type = ntype; |
177 } |
177 } |
178 |
178 |
179 // count of outgoing edges |
179 // count of outgoing edges |
180 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); } |
180 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); } |
|
181 |
181 // node index of target of outgoing edge "e" |
182 // node index of target of outgoing edge "e" |
182 uint edge_target(uint e) const; |
183 uint edge_target(uint e) const { |
|
184 assert(_edges != NULL, "valid edge index"); |
|
185 return (_edges->at(e) >> EdgeShift); |
|
186 } |
183 // type of outgoing edge "e" |
187 // type of outgoing edge "e" |
184 EdgeType edge_type(uint e) const; |
188 EdgeType edge_type(uint e) const { |
|
189 assert(_edges != NULL, "valid edge index"); |
|
190 return (EdgeType) (_edges->at(e) & EdgeMask); |
|
191 } |
|
192 |
185 // add a edge of the specified type pointing to the specified target |
193 // add a edge of the specified type pointing to the specified target |
186 void add_edge(uint targIdx, EdgeType et); |
194 void add_edge(uint targIdx, EdgeType et); |
|
195 |
187 // remove an edge of the specified type pointing to the specified target |
196 // remove an edge of the specified type pointing to the specified target |
188 void remove_edge(uint targIdx, EdgeType et); |
197 void remove_edge(uint targIdx, EdgeType et); |
|
198 |
189 #ifndef PRODUCT |
199 #ifndef PRODUCT |
190 void dump() const; |
200 void dump() const; |
191 #endif |
201 #endif |
192 |
202 |
193 }; |
203 }; |
194 |
204 |
195 class ConnectionGraph: public ResourceObj { |
205 class ConnectionGraph: public ResourceObj { |
196 private: |
206 private: |
197 GrowableArray<PointsToNode>* _nodes; // Connection graph nodes indexed |
207 GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed |
198 // by ideal node index. |
208 // by ideal node index. |
199 |
209 |
200 Unique_Node_List _delayed_worklist; // Nodes to be processed before |
210 Unique_Node_List _delayed_worklist; // Nodes to be processed before |
201 // the call build_connection_graph(). |
211 // the call build_connection_graph(). |
202 |
212 |
204 // processed. |
214 // processed. |
205 |
215 |
206 bool _collecting; // Indicates whether escape information |
216 bool _collecting; // Indicates whether escape information |
207 // is still being collected. If false, |
217 // is still being collected. If false, |
208 // no new nodes will be processed. |
218 // no new nodes will be processed. |
209 |
|
210 bool _has_allocations; // Indicates whether method has any |
|
211 // non-escaping allocations. |
|
212 |
219 |
213 uint _phantom_object; // Index of globally escaping object |
220 uint _phantom_object; // Index of globally escaping object |
214 // that pointer values loaded from |
221 // that pointer values loaded from |
215 // a field which has not been set |
222 // a field which has not been set |
216 // are assumed to point to. |
223 // are assumed to point to. |
217 |
224 |
218 Compile * _compile; // Compile object for current compilation |
225 Compile * _compile; // Compile object for current compilation |
219 |
226 |
220 // address of an element in _nodes. Used when the element is to be modified |
227 // Address of an element in _nodes. Used when the element is to be modified |
221 PointsToNode *ptnode_adr(uint idx) { |
228 PointsToNode *ptnode_adr(uint idx) const { |
222 if ((uint)_nodes->length() <= idx) { |
229 // There should be no new ideal nodes during ConnectionGraph build, |
223 // expand _nodes array |
230 // growableArray::adr_at() will throw assert otherwise. |
224 PointsToNode dummy = _nodes->at_grow(idx); |
231 return _nodes.adr_at(idx); |
225 } |
232 } |
226 return _nodes->adr_at(idx); |
233 uint nodes_size() const { return _nodes.length(); } |
227 } |
|
228 |
234 |
229 // Add node to ConnectionGraph. |
235 // Add node to ConnectionGraph. |
230 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); |
236 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); |
231 |
237 |
232 // offset of a field reference |
238 // offset of a field reference |
305 } |
311 } |
306 |
312 |
307 // Set the escape state of a node |
313 // Set the escape state of a node |
308 void set_escape_state(uint ni, PointsToNode::EscapeState es); |
314 void set_escape_state(uint ni, PointsToNode::EscapeState es); |
309 |
315 |
310 // Get Compile object for current compilation. |
|
311 Compile *C() const { return _compile; } |
|
312 |
|
313 public: |
316 public: |
314 ConnectionGraph(Compile *C); |
317 ConnectionGraph(Compile *C); |
315 |
318 |
|
319 // Check for non-escaping candidates |
|
320 static bool has_candidates(Compile *C); |
|
321 |
316 // Compute the escape information |
322 // Compute the escape information |
317 void compute_escape(); |
323 bool compute_escape(); |
318 |
324 |
319 // escape state of a node |
325 // escape state of a node |
320 PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); |
326 PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); |
321 // other information we have collected |
327 // other information we have collected |
322 bool is_scalar_replaceable(Node *n) { |
328 bool is_scalar_replaceable(Node *n) { |
323 if (_collecting) |
329 if (_collecting || (n->_idx >= nodes_size())) |
324 return false; |
330 return false; |
325 PointsToNode ptn = _nodes->at_grow(n->_idx); |
331 PointsToNode* ptn = ptnode_adr(n->_idx); |
326 return ptn.escape_state() == PointsToNode::NoEscape && ptn._scalar_replaceable; |
332 return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable; |
327 } |
333 } |
328 |
334 |
329 bool hidden_alias(Node *n) { |
335 bool hidden_alias(Node *n) { |
330 if (_collecting) |
336 if (_collecting || (n->_idx >= nodes_size())) |
331 return true; |
337 return true; |
332 PointsToNode ptn = _nodes->at_grow(n->_idx); |
338 PointsToNode* ptn = ptnode_adr(n->_idx); |
333 return (ptn.escape_state() != PointsToNode::NoEscape) || ptn._hidden_alias; |
339 return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias; |
334 } |
340 } |
335 |
341 |
336 #ifndef PRODUCT |
342 #ifndef PRODUCT |
337 void dump(); |
343 void dump(); |
338 #endif |
344 #endif |