comparison src/share/vm/opto/escape.hpp @ 20585:90297adbda9d

8041984: CompilerThread seems to occupy all CPU in a very rare situation Summary: Add new timeout checks to EA. Reviewed-by: iveresov, drchase
author kvn
date Fri, 24 Oct 2014 10:28:19 -0700
parents 7eca5de9e0b6
children
comparison
equal deleted inserted replaced
20584:ef9eda2c1abe 20585:90297adbda9d
123 class JavaObjectNode; 123 class JavaObjectNode;
124 class LocalVarNode; 124 class LocalVarNode;
125 class FieldNode; 125 class FieldNode;
126 class ArraycopyNode; 126 class ArraycopyNode;
127 127
128 class ConnectionGraph;
129
128 // ConnectionGraph nodes 130 // ConnectionGraph nodes
129 class PointsToNode : public ResourceObj { 131 class PointsToNode : public ResourceObj {
130 GrowableArray<PointsToNode*> _edges; // List of nodes this node points to 132 GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
131 GrowableArray<PointsToNode*> _uses; // List of nodes which point to this node 133 GrowableArray<PointsToNode*> _uses; // List of nodes which point to this node
132 134
135 u1 _escape; // EscapeState of object 137 u1 _escape; // EscapeState of object
136 u1 _fields_escape; // EscapeState of object's fields 138 u1 _fields_escape; // EscapeState of object's fields
137 139
138 Node* const _node; // Ideal node corresponding to this PointsTo node. 140 Node* const _node; // Ideal node corresponding to this PointsTo node.
139 const int _idx; // Cached ideal node's _idx 141 const int _idx; // Cached ideal node's _idx
142 const uint _pidx; // Index of this node
140 143
141 public: 144 public:
142 typedef enum { 145 typedef enum {
143 UnknownType = 0, 146 UnknownType = 0,
144 JavaObject = 1, 147 JavaObject = 1,
163 ArraycopySrc = 4, // Has edge from Arraycopy node 166 ArraycopySrc = 4, // Has edge from Arraycopy node
164 ArraycopyDst = 8 // Has edge to Arraycopy node 167 ArraycopyDst = 8 // Has edge to Arraycopy node
165 } NodeFlags; 168 } NodeFlags;
166 169
167 170
168 PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type): 171 inline PointsToNode(ConnectionGraph* CG, Node* n, EscapeState es, NodeType type);
169 _edges(C->comp_arena(), 2, 0, NULL), 172
170 _uses (C->comp_arena(), 2, 0, NULL), 173 uint pidx() const { return _pidx; }
171 _node(n),
172 _idx(n->_idx),
173 _type((u1)type),
174 _escape((u1)es),
175 _fields_escape((u1)es),
176 _flags(ScalarReplaceable) {
177 assert(n != NULL && es != UnknownEscape, "sanity");
178 }
179 174
180 Node* ideal_node() const { return _node; } 175 Node* ideal_node() const { return _node; }
181 int idx() const { return _idx; } 176 int idx() const { return _idx; }
182 177
183 bool is_JavaObject() const { return _type == (u1)JavaObject; } 178 bool is_JavaObject() const { return _type == (u1)JavaObject; }
241 236
242 }; 237 };
243 238
244 class LocalVarNode: public PointsToNode { 239 class LocalVarNode: public PointsToNode {
245 public: 240 public:
246 LocalVarNode(Compile *C, Node* n, EscapeState es): 241 LocalVarNode(ConnectionGraph *CG, Node* n, EscapeState es):
247 PointsToNode(C, n, es, LocalVar) {} 242 PointsToNode(CG, n, es, LocalVar) {}
248 }; 243 };
249 244
250 class JavaObjectNode: public PointsToNode { 245 class JavaObjectNode: public PointsToNode {
251 public: 246 public:
252 JavaObjectNode(Compile *C, Node* n, EscapeState es): 247 JavaObjectNode(ConnectionGraph *CG, Node* n, EscapeState es):
253 PointsToNode(C, n, es, JavaObject) { 248 PointsToNode(CG, n, es, JavaObject) {
254 if (es > NoEscape) 249 if (es > NoEscape)
255 set_scalar_replaceable(false); 250 set_scalar_replaceable(false);
256 } 251 }
257 }; 252 };
258 253
260 GrowableArray<PointsToNode*> _bases; // List of JavaObject nodes which point to this node 255 GrowableArray<PointsToNode*> _bases; // List of JavaObject nodes which point to this node
261 const int _offset; // Field's offset. 256 const int _offset; // Field's offset.
262 const bool _is_oop; // Field points to object 257 const bool _is_oop; // Field points to object
263 bool _has_unknown_base; // Has phantom_object base 258 bool _has_unknown_base; // Has phantom_object base
264 public: 259 public:
265 FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop): 260 FieldNode(ConnectionGraph *CG, Node* n, EscapeState es, int offs, bool is_oop):
266 PointsToNode(C, n, es, Field), 261 PointsToNode(CG, n, es, Field),
267 _offset(offs), _is_oop(is_oop), 262 _offset(offs), _is_oop(is_oop),
268 _has_unknown_base(false) {} 263 _has_unknown_base(false) {}
269 264
270 int offset() const { return _offset;} 265 int offset() const { return _offset;}
271 bool is_oop() const { return _is_oop;} 266 bool is_oop() const { return _is_oop;}
282 277
283 }; 278 };
284 279
285 class ArraycopyNode: public PointsToNode { 280 class ArraycopyNode: public PointsToNode {
286 public: 281 public:
287 ArraycopyNode(Compile *C, Node* n, EscapeState es): 282 ArraycopyNode(ConnectionGraph *CG, Node* n, EscapeState es):
288 PointsToNode(C, n, es, Arraycopy) {} 283 PointsToNode(CG, n, es, Arraycopy) {}
289 }; 284 };
290 285
291 // Iterators for PointsTo node's edges: 286 // Iterators for PointsTo node's edges:
292 // for (EdgeIterator i(n); i.has_next(); i.next()) { 287 // for (EdgeIterator i(n); i.has_next(); i.next()) {
293 // PointsToNode* u = i.get(); 288 // PointsToNode* u = i.get();
321 inline PointsToNode* get() const { return ((PointsToNode*)node)->as_Field()->base(i); } 316 inline PointsToNode* get() const { return ((PointsToNode*)node)->as_Field()->base(i); }
322 }; 317 };
323 318
324 319
325 class ConnectionGraph: public ResourceObj { 320 class ConnectionGraph: public ResourceObj {
321 friend class PointsToNode;
326 private: 322 private:
327 GrowableArray<PointsToNode*> _nodes; // Map from ideal nodes to 323 GrowableArray<PointsToNode*> _nodes; // Map from ideal nodes to
328 // ConnectionGraph nodes. 324 // ConnectionGraph nodes.
329 325
330 GrowableArray<PointsToNode*> _worklist; // Nodes to be processed 326 GrowableArray<PointsToNode*> _worklist; // Nodes to be processed
327 VectorSet _in_worklist;
328 uint _next_pidx;
331 329
332 bool _collecting; // Indicates whether escape information 330 bool _collecting; // Indicates whether escape information
333 // is still being collected. If false, 331 // is still being collected. If false,
334 // no new nodes will be processed. 332 // no new nodes will be processed.
335 333
350 // There should be no new ideal nodes during ConnectionGraph build, 348 // There should be no new ideal nodes during ConnectionGraph build,
351 // growableArray::at() will throw assert otherwise. 349 // growableArray::at() will throw assert otherwise.
352 return _nodes.at(idx); 350 return _nodes.at(idx);
353 } 351 }
354 uint nodes_size() const { return _nodes.length(); } 352 uint nodes_size() const { return _nodes.length(); }
353
354 uint next_pidx() { return _next_pidx++; }
355 355
356 // Add nodes to ConnectionGraph. 356 // Add nodes to ConnectionGraph.
357 void add_local_var(Node* n, PointsToNode::EscapeState es); 357 void add_local_var(Node* n, PointsToNode::EscapeState es);
358 void add_java_object(Node* n, PointsToNode::EscapeState es); 358 void add_java_object(Node* n, PointsToNode::EscapeState es);
359 void add_field(Node* n, PointsToNode::EscapeState es, int offset); 359 void add_field(Node* n, PointsToNode::EscapeState es, int offset);
394 394
395 // Add all references to this JavaObject node. 395 // Add all references to this JavaObject node.
396 int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist); 396 int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
397 397
398 // Put node on worklist if it is (or was) not there. 398 // Put node on worklist if it is (or was) not there.
399 void add_to_worklist(PointsToNode* pt) { 399 inline void add_to_worklist(PointsToNode* pt) {
400 _worklist.push(pt); 400 PointsToNode* ptf = pt;
401 return; 401 uint pidx_bias = 0;
402 if (PointsToNode::is_base_use(pt)) {
403 // Create a separate entry in _in_worklist for a marked base edge
404 // because _worklist may have an entry for a normal edge pointing
405 // to the same node. To separate them use _next_pidx as bias.
406 ptf = PointsToNode::get_use_node(pt)->as_Field();
407 pidx_bias = _next_pidx;
408 }
409 if (!_in_worklist.test_set(ptf->pidx() + pidx_bias)) {
410 _worklist.append(pt);
411 }
402 } 412 }
403 413
404 // Put on worklist all uses of this node. 414 // Put on worklist all uses of this node.
405 void add_uses_to_worklist(PointsToNode* pt) { 415 inline void add_uses_to_worklist(PointsToNode* pt) {
406 for (UseIterator i(pt); i.has_next(); i.next()) 416 for (UseIterator i(pt); i.has_next(); i.next()) {
407 _worklist.push(i.get()); 417 add_to_worklist(i.get());
418 }
408 } 419 }
409 420
410 // Put on worklist all field's uses and related field nodes. 421 // Put on worklist all field's uses and related field nodes.
411 void add_field_uses_to_worklist(FieldNode* field); 422 void add_field_uses_to_worklist(FieldNode* field);
412 423
515 } 526 }
516 add_edge(ptnode_adr(n->_idx), ptn); 527 add_edge(ptnode_adr(n->_idx), ptn);
517 } 528 }
518 // Helper functions 529 // Helper functions
519 bool is_oop_field(Node* n, int offset, bool* unsafe); 530 bool is_oop_field(Node* n, int offset, bool* unsafe);
520 static Node* get_addp_base(Node *addp); 531 static Node* get_addp_base(Node *addp);
521 static Node* find_second_addp(Node* addp, Node* n); 532 static Node* find_second_addp(Node* addp, Node* n);
522 // offset of a field reference 533 // offset of a field reference
523 int address_offset(Node* adr, PhaseTransform *phase); 534 int address_offset(Node* adr, PhaseTransform *phase);
524 535
525 536
526 // Propagate unique types created for unescaped allocated objects 537 // Propagate unique types created for unescaped allocated objects
585 #ifndef PRODUCT 596 #ifndef PRODUCT
586 void dump(GrowableArray<PointsToNode*>& ptnodes_worklist); 597 void dump(GrowableArray<PointsToNode*>& ptnodes_worklist);
587 #endif 598 #endif
588 }; 599 };
589 600
601 inline PointsToNode::PointsToNode(ConnectionGraph *CG, Node* n, EscapeState es, NodeType type):
602 _edges(CG->_compile->comp_arena(), 2, 0, NULL),
603 _uses (CG->_compile->comp_arena(), 2, 0, NULL),
604 _node(n),
605 _idx(n->_idx),
606 _pidx(CG->next_pidx()),
607 _type((u1)type),
608 _escape((u1)es),
609 _fields_escape((u1)es),
610 _flags(ScalarReplaceable) {
611 assert(n != NULL && es != UnknownEscape, "sanity");
612 }
613
590 #endif // SHARE_VM_OPTO_ESCAPE_HPP 614 #endif // SHARE_VM_OPTO_ESCAPE_HPP