1.1 --- a/src/share/vm/opto/escape.hpp Fri Nov 04 13:55:31 2011 -0700 1.2 +++ b/src/share/vm/opto/escape.hpp Mon Nov 07 14:33:57 2011 -0800 1.3 @@ -74,7 +74,7 @@ 1.4 // C2 does not have local variables. However for the purposes of constructing 1.5 // the connection graph, the following IR nodes are treated as local variables: 1.6 // Phi (pointer values) 1.7 -// LoadP 1.8 +// LoadP, LoadN 1.9 // Proj#5 (value returned from callnodes including allocations) 1.10 // CheckCastPP, CastPP 1.11 // 1.12 @@ -84,7 +84,7 @@ 1.13 // 1.14 // The following node types are JavaObject: 1.15 // 1.16 -// top() 1.17 +// phantom_object (general globally escaped object) 1.18 // Allocate 1.19 // AllocateArray 1.20 // Parm (for incoming arguments) 1.21 @@ -93,6 +93,7 @@ 1.22 // ConP 1.23 // LoadKlass 1.24 // ThreadLocal 1.25 +// CallStaticJava (which returns Object) 1.26 // 1.27 // AddP nodes are fields. 1.28 // 1.29 @@ -130,10 +131,12 @@ 1.30 1.31 typedef enum { 1.32 UnknownEscape = 0, 1.33 - NoEscape = 1, // A scalar replaceable object with unique type. 1.34 - ArgEscape = 2, // An object passed as argument or referenced by 1.35 - // argument (and not globally escape during call). 1.36 - GlobalEscape = 3 // An object escapes the method and thread. 1.37 + NoEscape = 1, // An object does not escape method or thread and it is 1.38 + // not passed to call. It could be replaced with scalar. 1.39 + ArgEscape = 2, // An object does not escape method or thread but it is 1.40 + // passed as argument to call or referenced by argument 1.41 + // and it does not escape during call. 1.42 + GlobalEscape = 3 // An object escapes the method or thread. 1.43 } EscapeState; 1.44 1.45 typedef enum { 1.46 @@ -153,28 +156,25 @@ 1.47 1.48 NodeType _type; 1.49 EscapeState _escape; 1.50 - GrowableArray<uint>* _edges; // outgoing edges 1.51 + GrowableArray<uint>* _edges; // outgoing edges 1.52 + Node* _node; // Ideal node corresponding to this PointsTo node. 1.53 + int _offset; // Object fields offsets. 1.54 + bool _scalar_replaceable; // Not escaped object could be replaced with scalar 1.55 1.56 public: 1.57 - Node* _node; // Ideal node corresponding to this PointsTo node. 1.58 - int _offset; // Object fields offsets. 1.59 - bool _scalar_replaceable;// Not escaped object could be replaced with scalar 1.60 - bool _hidden_alias; // This node is an argument to a function. 1.61 - // which may return it creating a hidden alias. 1.62 - 1.63 PointsToNode(): 1.64 _type(UnknownType), 1.65 _escape(UnknownEscape), 1.66 _edges(NULL), 1.67 _node(NULL), 1.68 _offset(-1), 1.69 - _scalar_replaceable(true), 1.70 - _hidden_alias(false) {} 1.71 + _scalar_replaceable(true) {} 1.72 1.73 1.74 EscapeState escape_state() const { return _escape; } 1.75 NodeType node_type() const { return _type;} 1.76 int offset() { return _offset;} 1.77 + bool scalar_replaceable() { return _scalar_replaceable;} 1.78 1.79 void set_offset(int offs) { _offset = offs;} 1.80 void set_escape_state(EscapeState state) { _escape = state; } 1.81 @@ -182,6 +182,7 @@ 1.82 assert(_type == UnknownType || _type == ntype, "Can't change node type"); 1.83 _type = ntype; 1.84 } 1.85 + void set_scalar_replaceable(bool v) { _scalar_replaceable = v; } 1.86 1.87 // count of outgoing edges 1.88 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); } 1.89 @@ -233,8 +234,8 @@ 1.90 // that pointer values loaded from 1.91 // a field which has not been set 1.92 // are assumed to point to. 1.93 - uint _oop_null; // ConP(#NULL) 1.94 - uint _noop_null; // ConN(#NULL) 1.95 + uint _oop_null; // ConP(#NULL)->_idx 1.96 + uint _noop_null; // ConN(#NULL)->_idx 1.97 1.98 Compile * _compile; // Compile object for current compilation 1.99 PhaseIterGVN * _igvn; // Value numbering 1.100 @@ -339,8 +340,16 @@ 1.101 // Set the escape state of a node 1.102 void set_escape_state(uint ni, PointsToNode::EscapeState es); 1.103 1.104 + // Find fields initializing values for allocations. 1.105 + void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase); 1.106 + 1.107 // Adjust escape state after Connection Graph is built. 1.108 - void adjust_escape_state(int nidx, PhaseTransform* phase); 1.109 + void adjust_escape_state(Node* n); 1.110 + 1.111 + // Propagate escape states to referenced nodes. 1.112 + bool propagate_escape_state(GrowableArray<int>* cg_worklist, 1.113 + GrowableArray<uint>* worklist, 1.114 + PointsToNode::EscapeState esc_state); 1.115 1.116 // Compute the escape information 1.117 bool compute_escape(); 1.118 @@ -357,21 +366,6 @@ 1.119 // escape state of a node 1.120 PointsToNode::EscapeState escape_state(Node *n); 1.121 1.122 - // other information we have collected 1.123 - bool is_scalar_replaceable(Node *n) { 1.124 - if (_collecting || (n->_idx >= nodes_size())) 1.125 - return false; 1.126 - PointsToNode* ptn = ptnode_adr(n->_idx); 1.127 - return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable; 1.128 - } 1.129 - 1.130 - bool hidden_alias(Node *n) { 1.131 - if (_collecting || (n->_idx >= nodes_size())) 1.132 - return true; 1.133 - PointsToNode* ptn = ptnode_adr(n->_idx); 1.134 - return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias; 1.135 - } 1.136 - 1.137 #ifndef PRODUCT 1.138 void dump(); 1.139 #endif