202 203 }; 204 205 class ConnectionGraph: public ResourceObj { 206 private: 207 GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed 208 // by ideal node index. 209 210 Unique_Node_List _delayed_worklist; // Nodes to be processed before 211 // the call build_connection_graph(). 212 213 GrowableArray<MergeMemNode *> _mergemem_worklist; // List of all MergeMem nodes 214 215 VectorSet _processed; // Records which nodes have been 216 // processed. 217 218 bool _collecting; // Indicates whether escape information 219 // is still being collected. If false, 220 // no new nodes will be processed. 221 222 uint _phantom_object; // Index of globally escaping object 223 // that pointer values loaded from 224 // a field which has not been set 225 // are assumed to point to. 226 uint _oop_null; // ConP(#NULL) 227 uint _noop_null; // ConN(#NULL) 228 229 Compile * _compile; // Compile object for current compilation 230 PhaseIterGVN * _igvn; // Value numbering 231 232 // Address of an element in _nodes. Used when the element is to be modified 233 PointsToNode *ptnode_adr(uint idx) const { 234 // There should be no new ideal nodes during ConnectionGraph build, 235 // growableArray::adr_at() will throw assert otherwise. 236 return _nodes.adr_at(idx); 237 } 238 uint nodes_size() const { return _nodes.length(); } 239 240 // Add node to ConnectionGraph. 241 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); 249 // compute the escape state for the return value of a call 250 void process_call_result(ProjNode *resproj, PhaseTransform *phase); 251 252 // Populate Connection Graph with Ideal nodes. 253 void record_for_escape_analysis(Node *n, PhaseTransform *phase); 254 255 // Build Connection Graph and set nodes escape state. 256 void build_connection_graph(Node *n, PhaseTransform *phase); 257 258 // walk the connection graph starting at the node corresponding to "n" and 259 // add the index of everything it could point to, to "ptset". This may cause 260 // Phi's encountered to get (re)processed (which requires "phase".) 261 void PointsTo(VectorSet &ptset, Node * n); 262 263 // Edge manipulation. The "from_i" and "to_i" arguments are the 264 // node indices of the source and destination of the edge 265 void add_pointsto_edge(uint from_i, uint to_i); 266 void add_deferred_edge(uint from_i, uint to_i); 267 void add_field_edge(uint from_i, uint to_i, int offs); 268 269 270 // Add an edge to node given by "to_i" from any field of adr_i whose offset 271 // matches "offset" A deferred edge is added if to_i is a LocalVar, and 272 // a pointsto edge is added if it is a JavaObject 273 void add_edge_from_fields(uint adr, uint to_i, int offs); 274 275 // Add a deferred edge from node given by "from_i" to any field 276 // of adr_i whose offset matches "offset" 277 void add_deferred_edge_to_fields(uint from_i, uint adr, int offs); 278 279 280 // Remove outgoing deferred edges from the node referenced by "ni". 281 // Any outgoing edges from the target of the deferred edge are copied 282 // to "ni". 283 void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited); 284 285 Node_Array _node_map; // used for bookeeping during type splitting 286 // Used for the following purposes: 287 // Memory Phi - most recent unique Phi split out 288 // from this Phi | 202 203 }; 204 205 class ConnectionGraph: public ResourceObj { 206 private: 207 GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed 208 // by ideal node index. 209 210 Unique_Node_List _delayed_worklist; // Nodes to be processed before 211 // the call build_connection_graph(). 212 213 GrowableArray<MergeMemNode *> _mergemem_worklist; // List of all MergeMem nodes 214 215 VectorSet _processed; // Records which nodes have been 216 // processed. 217 218 bool _collecting; // Indicates whether escape information 219 // is still being collected. If false, 220 // no new nodes will be processed. 221 222 bool _progress; // Indicates whether new Graph's edges 223 // were created. 224 225 uint _phantom_object; // Index of globally escaping object 226 // that pointer values loaded from 227 // a field which has not been set 228 // are assumed to point to. 229 uint _oop_null; // ConP(#NULL) 230 uint _noop_null; // ConN(#NULL) 231 232 Compile * _compile; // Compile object for current compilation 233 PhaseIterGVN * _igvn; // Value numbering 234 235 // Address of an element in _nodes. Used when the element is to be modified 236 PointsToNode *ptnode_adr(uint idx) const { 237 // There should be no new ideal nodes during ConnectionGraph build, 238 // growableArray::adr_at() will throw assert otherwise. 239 return _nodes.adr_at(idx); 240 } 241 uint nodes_size() const { return _nodes.length(); } 242 243 // Add node to ConnectionGraph. 244 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); 252 // compute the escape state for the return value of a call 253 void process_call_result(ProjNode *resproj, PhaseTransform *phase); 254 255 // Populate Connection Graph with Ideal nodes. 256 void record_for_escape_analysis(Node *n, PhaseTransform *phase); 257 258 // Build Connection Graph and set nodes escape state. 259 void build_connection_graph(Node *n, PhaseTransform *phase); 260 261 // walk the connection graph starting at the node corresponding to "n" and 262 // add the index of everything it could point to, to "ptset". This may cause 263 // Phi's encountered to get (re)processed (which requires "phase".) 264 void PointsTo(VectorSet &ptset, Node * n); 265 266 // Edge manipulation. The "from_i" and "to_i" arguments are the 267 // node indices of the source and destination of the edge 268 void add_pointsto_edge(uint from_i, uint to_i); 269 void add_deferred_edge(uint from_i, uint to_i); 270 void add_field_edge(uint from_i, uint to_i, int offs); 271 272 // Add a edge of the specified type pointing to the specified target. 273 // Set _progress if new esge is added. 274 void add_edge(PointsToNode *f, uint to_i, PointsToNode::EdgeType et) { 275 uint e_cnt = f->edge_count(); 276 f->add_edge(to_i, et); 277 _progress |= (f->edge_count() != e_cnt); 278 } 279 280 // Add an edge to node given by "to_i" from any field of adr_i whose offset 281 // matches "offset" A deferred edge is added if to_i is a LocalVar, and 282 // a pointsto edge is added if it is a JavaObject 283 void add_edge_from_fields(uint adr, uint to_i, int offs); 284 285 // Add a deferred edge from node given by "from_i" to any field 286 // of adr_i whose offset matches "offset" 287 void add_deferred_edge_to_fields(uint from_i, uint adr, int offs); 288 289 290 // Remove outgoing deferred edges from the node referenced by "ni". 291 // Any outgoing edges from the target of the deferred edge are copied 292 // to "ni". 293 void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited); 294 295 Node_Array _node_map; // used for bookeeping during type splitting 296 // Used for the following purposes: 297 // Memory Phi - most recent unique Phi split out 298 // from this Phi |