1 /*
2 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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);
340 }
341 }
|
1 /*
2 * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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 sfn->set_not_global_escape_in_scope(has_not_global_escape_in_scope(sfn));
336 if (sfn->is_CallJava()) {
337 CallJavaNode* call = sfn->as_CallJava();
338 call->set_arg_escape(has_arg_escape(call));
339 }
340 }
341 }
342
343 return has_non_escaping_obj;
344 }
345
346 // Returns true if an object in the scope of sfn does not escape globally.
347 bool ConnectionGraph::has_not_global_escape_in_scope(SafePointNode* sfn) {
348 Compile* C = _compile;
349 for (JVMState* jvms = sfn->jvms(); jvms != NULL; jvms = jvms->caller()) {
350 if (C->env()->should_retain_local_variables() || C->env()->jvmti_can_walk_any_space() ||
351 DeoptimizeObjectsALot) {
352 // Jvmti agents can access locals. Must provide info about local objects at runtime.
353 int num_locs = jvms->loc_size();
354 for (int idx = 0; idx < num_locs; idx++) {
355 Node* l = sfn->local(jvms, idx);
356 if (not_global_escape(l)) {
357 return true;
358 }
359 }
360 }
361 if (C->env()->jvmti_can_get_owned_monitor_info() ||
362 C->env()->jvmti_can_walk_any_space() || DeoptimizeObjectsALot) {
363 // Jvmti agents can read monitors. Must provide info about locked objects at runtime.
364 int num_mon = jvms->nof_monitors();
365 for (int idx = 0; idx < num_mon; idx++) {
366 Node* m = sfn->monitor_obj(jvms, idx);
367 if (m != NULL && not_global_escape(m)) {
368 return true;
369 }
370 }
371 }
372 }
373 return false;
374 }
375
376 // Returns true if at least one of the arguments to the call is an object
377 // that does not escape globally.
378 bool ConnectionGraph::has_arg_escape(CallJavaNode* call) {
379 if (call->method() != NULL) {
380 uint max_idx = TypeFunc::Parms + call->method()->arg_size();
381 for (uint idx = TypeFunc::Parms; idx < max_idx; idx++) {
382 Node* p = call->in(idx);
383 if (not_global_escape(p)) {
384 return true;
385 }
386 }
387 } else {
388 const char* name = call->as_CallStaticJava()->_name;
389 assert(name != NULL, "no name");
390 // no arg escapes through uncommon traps
391 if (strcmp(name, "uncommon_trap") != 0) {
392 // process_call_arguments() assumes that all arguments escape globally
393 const TypeTuple* d = call->tf()->domain();
394 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
395 const Type* at = d->field_at(i);
396 if (at->isa_oopptr() != NULL) {
397 return true;
398 }
399 }
400 }
401 }
402 return false;
403 }
404
405
406
407 // Utility function for nodes that load an object
408 void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
409 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
410 // ThreadLocal has RawPtr type.
411 const Type* t = _igvn->type(n);
412 if (t->make_ptr() != NULL) {
413 Node* adr = n->in(MemNode::Address);
414 #ifdef ASSERT
415 if (!adr->is_AddP()) {
416 assert(_igvn->type(adr)->isa_rawptr(), "sanity");
417 } else {
418 assert((ptnode_adr(adr->_idx) == NULL ||
419 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
420 }
421 #endif
422 add_local_var_and_edge(n, PointsToNode::NoEscape,
423 adr, delayed_worklist);
424 }
425 }
|