106 if (oop_null->outcnt() == 0)
107 igvn->hash_delete(oop_null);
108 if (noop_null->outcnt() == 0)
109 igvn->hash_delete(noop_null);
110 }
111
112 bool ConnectionGraph::compute_escape() {
113 Compile* C = _compile;
114 PhaseGVN* igvn = _igvn;
115
116 // Worklists used by EA.
117 Unique_Node_List delayed_worklist;
118 GrowableArray<Node*> alloc_worklist;
119 GrowableArray<Node*> ptr_cmp_worklist;
120 GrowableArray<Node*> storestore_worklist;
121 GrowableArray<ArrayCopyNode*> arraycopy_worklist;
122 GrowableArray<PointsToNode*> ptnodes_worklist;
123 GrowableArray<JavaObjectNode*> java_objects_worklist;
124 GrowableArray<JavaObjectNode*> non_escaped_worklist;
125 GrowableArray<FieldNode*> oop_fields_worklist;
126 DEBUG_ONLY( GrowableArray<Node*> addp_worklist; )
127
128 { Compile::TracePhase tp("connectionGraph", &Phase::timers[Phase::_t_connectionGraph]);
129
130 // 1. Populate Connection Graph (CG) with PointsTo nodes.
131 ideal_nodes.map(C->live_nodes(), NULL); // preallocate space
132 // Initialize worklist
133 if (C->root() != NULL) {
134 ideal_nodes.push(C->root());
135 }
136 // Processed ideal nodes are unique on ideal_nodes list
137 // but several ideal nodes are mapped to the phantom_obj.
138 // To avoid duplicated entries on the following worklists
139 // add the phantom_obj only once to them.
140 ptnodes_worklist.append(phantom_obj);
141 java_objects_worklist.append(phantom_obj);
142 for( uint next = 0; next < ideal_nodes.size(); ++next ) {
143 Node* n = ideal_nodes.at(next);
144 // Create PointsTo nodes and add them to Connection Graph. Called
145 // only once per ideal node since ideal_nodes is Unique_Node list.
171 // escape status of the associated Allocate node some of them
172 // may be eliminated.
173 storestore_worklist.append(n);
174 } else if (n->is_MemBar() && (n->Opcode() == Op_MemBarRelease) &&
175 (n->req() > MemBarNode::Precedent)) {
176 record_for_optimizer(n);
177 #ifdef ASSERT
178 } else if (n->is_AddP()) {
179 // Collect address nodes for graph verification.
180 addp_worklist.append(n);
181 #endif
182 } else if (n->is_ArrayCopy()) {
183 // Keep a list of ArrayCopy nodes so if one of its input is non
184 // escaping, we can record a unique type
185 arraycopy_worklist.append(n->as_ArrayCopy());
186 }
187 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
188 Node* m = n->fast_out(i); // Get user
189 ideal_nodes.push(m);
190 }
191 }
192 if (non_escaped_worklist.length() == 0) {
193 _collecting = false;
194 return false; // Nothing to do.
195 }
196 // Add final simple edges to graph.
197 while(delayed_worklist.size() > 0) {
198 Node* n = delayed_worklist.pop();
199 add_final_edges(n);
200 }
201 int ptnodes_length = ptnodes_worklist.length();
202
203 #ifdef ASSERT
204 if (VerifyConnectionGraph) {
205 // Verify that no new simple edges could be created and all
206 // local vars has edges.
207 _verify = true;
208 for (int next = 0; next < ptnodes_length; ++next) {
209 PointsToNode* ptn = ptnodes_worklist.at(next);
210 add_final_edges(ptn->ideal_node());
300 // Now use the escape information to create unique types for
301 // scalar replaceable objects.
302 split_unique_types(alloc_worklist, arraycopy_worklist);
303 if (C->failing()) return false;
304 C->print_method(PHASE_AFTER_EA, 2);
305
306 #ifdef ASSERT
307 } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
308 tty->print("=== No allocations eliminated for ");
309 C->method()->print_short_name();
310 if(!EliminateAllocations) {
311 tty->print(" since EliminateAllocations is off ===");
312 } else if(!has_scalar_replaceable_candidates) {
313 tty->print(" since there are no scalar replaceable candidates ===");
314 } else if(C->AliasLevel() < 3) {
315 tty->print(" since AliasLevel < 3 ===");
316 }
317 tty->cr();
318 #endif
319 }
320 return has_non_escaping_obj;
321 }
322
323 // Utility function for nodes that load an object
324 void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
325 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
326 // ThreadLocal has RawPtr type.
327 const Type* t = _igvn->type(n);
328 if (t->make_ptr() != NULL) {
329 Node* adr = n->in(MemNode::Address);
330 #ifdef ASSERT
331 if (!adr->is_AddP()) {
332 assert(_igvn->type(adr)->isa_rawptr(), "sanity");
333 } else {
334 assert((ptnode_adr(adr->_idx) == NULL ||
335 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
336 }
337 #endif
338 add_local_var_and_edge(n, PointsToNode::NoEscape,
339 adr, delayed_worklist);
2161 if (e->is_JavaObject()) {
2162 Node* n = e->ideal_node();
2163 if ((e->escape_state() != PointsToNode::NoEscape) ||
2164 !(n->is_Allocate() || n->is_CallStaticJava())) {
2165 return false;
2166 }
2167 }
2168 }
2169 return true;
2170 }
2171
2172 // Return true if we know the node does not escape globally.
2173 bool ConnectionGraph::not_global_escape(Node *n) {
2174 assert(!_collecting, "should not call during graph construction");
2175 // If the node was created after the escape computation we can't answer.
2176 uint idx = n->_idx;
2177 if (idx >= nodes_size()) {
2178 return false;
2179 }
2180 PointsToNode* ptn = ptnode_adr(idx);
2181 PointsToNode::EscapeState es = ptn->escape_state();
2182 // If we have already computed a value, return it.
2183 if (es >= PointsToNode::GlobalEscape)
2184 return false;
2185 if (ptn->is_JavaObject()) {
2186 return true; // (es < PointsToNode::GlobalEscape);
2187 }
2188 assert(ptn->is_LocalVar(), "sanity");
2189 // Check all java objects it points to.
2190 for (EdgeIterator i(ptn); i.has_next(); i.next()) {
2191 if (i.get()->escape_state() >= PointsToNode::GlobalEscape)
2192 return false;
2193 }
2194 return true;
2195 }
2196
2197
2198 // Helper functions
2199
2200 // Return true if this node points to specified node or nodes it points to.
|
106 if (oop_null->outcnt() == 0)
107 igvn->hash_delete(oop_null);
108 if (noop_null->outcnt() == 0)
109 igvn->hash_delete(noop_null);
110 }
111
112 bool ConnectionGraph::compute_escape() {
113 Compile* C = _compile;
114 PhaseGVN* igvn = _igvn;
115
116 // Worklists used by EA.
117 Unique_Node_List delayed_worklist;
118 GrowableArray<Node*> alloc_worklist;
119 GrowableArray<Node*> ptr_cmp_worklist;
120 GrowableArray<Node*> storestore_worklist;
121 GrowableArray<ArrayCopyNode*> arraycopy_worklist;
122 GrowableArray<PointsToNode*> ptnodes_worklist;
123 GrowableArray<JavaObjectNode*> java_objects_worklist;
124 GrowableArray<JavaObjectNode*> non_escaped_worklist;
125 GrowableArray<FieldNode*> oop_fields_worklist;
126 GrowableArray<SafePointNode*> sfn_worklist;
127 DEBUG_ONLY( GrowableArray<Node*> addp_worklist; )
128
129 { Compile::TracePhase tp("connectionGraph", &Phase::timers[Phase::_t_connectionGraph]);
130
131 // 1. Populate Connection Graph (CG) with PointsTo nodes.
132 ideal_nodes.map(C->live_nodes(), NULL); // preallocate space
133 // Initialize worklist
134 if (C->root() != NULL) {
135 ideal_nodes.push(C->root());
136 }
137 // Processed ideal nodes are unique on ideal_nodes list
138 // but several ideal nodes are mapped to the phantom_obj.
139 // To avoid duplicated entries on the following worklists
140 // add the phantom_obj only once to them.
141 ptnodes_worklist.append(phantom_obj);
142 java_objects_worklist.append(phantom_obj);
143 for( uint next = 0; next < ideal_nodes.size(); ++next ) {
144 Node* n = ideal_nodes.at(next);
145 // Create PointsTo nodes and add them to Connection Graph. Called
146 // only once per ideal node since ideal_nodes is Unique_Node list.
172 // escape status of the associated Allocate node some of them
173 // may be eliminated.
174 storestore_worklist.append(n);
175 } else if (n->is_MemBar() && (n->Opcode() == Op_MemBarRelease) &&
176 (n->req() > MemBarNode::Precedent)) {
177 record_for_optimizer(n);
178 #ifdef ASSERT
179 } else if (n->is_AddP()) {
180 // Collect address nodes for graph verification.
181 addp_worklist.append(n);
182 #endif
183 } else if (n->is_ArrayCopy()) {
184 // Keep a list of ArrayCopy nodes so if one of its input is non
185 // escaping, we can record a unique type
186 arraycopy_worklist.append(n->as_ArrayCopy());
187 }
188 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
189 Node* m = n->fast_out(i); // Get user
190 ideal_nodes.push(m);
191 }
192 if (n-> is_SafePoint()) {
193 sfn_worklist.append(n->as_SafePoint());
194 }
195 }
196 if (non_escaped_worklist.length() == 0) {
197 _collecting = false;
198 return false; // Nothing to do.
199 }
200 // Add final simple edges to graph.
201 while(delayed_worklist.size() > 0) {
202 Node* n = delayed_worklist.pop();
203 add_final_edges(n);
204 }
205 int ptnodes_length = ptnodes_worklist.length();
206
207 #ifdef ASSERT
208 if (VerifyConnectionGraph) {
209 // Verify that no new simple edges could be created and all
210 // local vars has edges.
211 _verify = true;
212 for (int next = 0; next < ptnodes_length; ++next) {
213 PointsToNode* ptn = ptnodes_worklist.at(next);
214 add_final_edges(ptn->ideal_node());
304 // Now use the escape information to create unique types for
305 // scalar replaceable objects.
306 split_unique_types(alloc_worklist, arraycopy_worklist);
307 if (C->failing()) return false;
308 C->print_method(PHASE_AFTER_EA, 2);
309
310 #ifdef ASSERT
311 } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
312 tty->print("=== No allocations eliminated for ");
313 C->method()->print_short_name();
314 if(!EliminateAllocations) {
315 tty->print(" since EliminateAllocations is off ===");
316 } else if(!has_scalar_replaceable_candidates) {
317 tty->print(" since there are no scalar replaceable candidates ===");
318 } else if(C->AliasLevel() < 3) {
319 tty->print(" since AliasLevel < 3 ===");
320 }
321 tty->cr();
322 #endif
323 }
324
325 // Annotate at safepoints if they have <= ArgEscape objects in their scope and at
326 // java calls if they pass ArgEscape objects as parameters.
327 if (has_non_escaping_obj &&
328 (C->env()->should_retain_local_variables() ||
329 C->env()->jvmti_can_get_owned_monitor_info() ||
330 C->env()->jvmti_can_walk_any_space() ||
331 DeoptimizeObjectsALot)) {
332 int sfn_length = sfn_worklist.length();
333 for (int next = 0; next < sfn_length; next++) {
334 SafePointNode* sfn = sfn_worklist.at(next);
335 bool found_not_global_escape = false;
336 for (JVMState* jvms = sfn->jvms(); jvms && !found_not_global_escape; jvms = jvms->caller()) {
337 if (C->env()->should_retain_local_variables() || C->env()->jvmti_can_walk_any_space() ||
338 DeoptimizeObjectsALot) {
339 // Jvmti agents can access locals. Must provide info about local objects at runtime.
340 int num_locs = jvms->loc_size();
341 for(int idx = 0; idx < num_locs && !found_not_global_escape; idx++ ) {
342 Node* l = sfn->local(jvms, idx);
343 found_not_global_escape = not_global_escape(l);
344 }
345 }
346 if (C->env()->jvmti_can_get_owned_monitor_info() ||
347 C->env()->jvmti_can_walk_any_space() || DeoptimizeObjectsALot) {
348 // Jvmti agents can read monitors. Must provide info about locked objects at runtime.
349 int num_mon = jvms->nof_monitors();
350 for(int idx = 0; idx < num_mon && !found_not_global_escape; idx++ ) {
351 Node* m = sfn->monitor_obj(jvms, idx);
352 found_not_global_escape = m != NULL && not_global_escape(m);
353 }
354 }
355 }
356 sfn->set_not_global_escape_in_scope(found_not_global_escape);
357
358 if (sfn->is_CallJava()) {
359 CallJavaNode* call = sfn->as_CallJava();
360 bool found_arg_escape_in_args = false;
361 if (call->method() != NULL) {
362 uint max_idx = TypeFunc::Parms + call->method()->arg_size();
363 for(uint idx = TypeFunc::Parms; idx < max_idx && !found_arg_escape_in_args; idx++) {
364 Node* p = call->in(idx);
365 found_arg_escape_in_args = not_global_escape(p);
366 }
367 } else {
368 const char* name = call->as_CallStaticJava()->_name;
369 assert(name != NULL, "no name");
370 // no arg escapes through uncommon traps
371 if (strcmp(name, "uncommon_trap") != 0) {
372 // process_call_arguments() assumes that all arguments escape globally
373 const TypeTuple* d = call->tf()->domain();
374 for (uint i = TypeFunc::Parms; i < d->cnt() && !found_arg_escape_in_args; i++) {
375 const Type* at = d->field_at(i);
376 if (at->isa_oopptr() != NULL) {
377 found_arg_escape_in_args = true;
378 }
379 }
380 }
381 }
382 call->set_arg_escape(found_arg_escape_in_args);
383 }
384 }
385 }
386
387 return has_non_escaping_obj;
388 }
389
390 // Utility function for nodes that load an object
391 void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
392 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
393 // ThreadLocal has RawPtr type.
394 const Type* t = _igvn->type(n);
395 if (t->make_ptr() != NULL) {
396 Node* adr = n->in(MemNode::Address);
397 #ifdef ASSERT
398 if (!adr->is_AddP()) {
399 assert(_igvn->type(adr)->isa_rawptr(), "sanity");
400 } else {
401 assert((ptnode_adr(adr->_idx) == NULL ||
402 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
403 }
404 #endif
405 add_local_var_and_edge(n, PointsToNode::NoEscape,
406 adr, delayed_worklist);
2228 if (e->is_JavaObject()) {
2229 Node* n = e->ideal_node();
2230 if ((e->escape_state() != PointsToNode::NoEscape) ||
2231 !(n->is_Allocate() || n->is_CallStaticJava())) {
2232 return false;
2233 }
2234 }
2235 }
2236 return true;
2237 }
2238
2239 // Return true if we know the node does not escape globally.
2240 bool ConnectionGraph::not_global_escape(Node *n) {
2241 assert(!_collecting, "should not call during graph construction");
2242 // If the node was created after the escape computation we can't answer.
2243 uint idx = n->_idx;
2244 if (idx >= nodes_size()) {
2245 return false;
2246 }
2247 PointsToNode* ptn = ptnode_adr(idx);
2248 if (!ptn) {
2249 return false; // not in congraph (e.g. ConI)
2250 }
2251 PointsToNode::EscapeState es = ptn->escape_state();
2252 // If we have already computed a value, return it.
2253 if (es >= PointsToNode::GlobalEscape)
2254 return false;
2255 if (ptn->is_JavaObject()) {
2256 return true; // (es < PointsToNode::GlobalEscape);
2257 }
2258 assert(ptn->is_LocalVar(), "sanity");
2259 // Check all java objects it points to.
2260 for (EdgeIterator i(ptn); i.has_next(); i.next()) {
2261 if (i.get()->escape_state() >= PointsToNode::GlobalEscape)
2262 return false;
2263 }
2264 return true;
2265 }
2266
2267
2268 // Helper functions
2269
2270 // Return true if this node points to specified node or nodes it points to.
|