1 /*
2 * Copyright (c) 2005, 2015, 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 *
248
249 void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) {
250 int i;
251
252 // retrieve information about the callee
253 ciInstanceKlass* klass = target->holder();
254 ciInstanceKlass* calling_klass = method()->holder();
255 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
256 ciInstanceKlass* actual_recv = callee_holder;
257
258 // Some methods are obviously bindable without any type checks so
259 // convert them directly to an invokespecial or invokestatic.
260 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
261 switch (code) {
262 case Bytecodes::_invokevirtual:
263 code = Bytecodes::_invokespecial;
264 break;
265 case Bytecodes::_invokehandle:
266 code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
267 break;
268 }
269 }
270
271 // compute size of arguments
272 int arg_size = target->invoke_arg_size(code);
273 int arg_base = MAX2(state._stack_height - arg_size, 0);
274
275 // direct recursive calls are skipped if they can be bound statically without introducing
276 // dependencies and if parameters are passed at the same position as in the current method
277 // other calls are skipped if there are no unescaped arguments passed to them
278 bool directly_recursive = (method() == target) &&
279 (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty());
280
281 // check if analysis of callee can safely be skipped
282 bool skip_callee = true;
283 for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) {
284 ArgumentMap arg = state._stack[i];
285 skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base));
286 }
287 // For now we conservatively skip invokedynamic.
288 if (code == Bytecodes::_invokedynamic) {
289 skip_callee = true;
290 }
291 if (skip_callee) {
292 TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8()));
293 for (i = 0; i < arg_size; i++) {
294 set_method_escape(state.raw_pop());
295 }
296 _unknown_modified = true; // assume the worst since we don't analyze the called method
297 return;
298 }
299
300 // determine actual method (use CHA if necessary)
301 ciMethod* inline_target = NULL;
302 if (target->is_loaded() && klass->is_loaded()
303 && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
304 && target->is_loaded()) {
305 if (code == Bytecodes::_invokestatic
306 || code == Bytecodes::_invokespecial
307 || code == Bytecodes::_invokevirtual && target->is_final_method()) {
308 inline_target = target;
309 } else {
310 inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
311 }
312 }
313
314 if (inline_target != NULL && !is_recursive_call(inline_target)) {
315 // analyze callee
316 BCEscapeAnalyzer analyzer(inline_target, this);
317
318 // adjust escape state of actual parameters
319 bool must_record_dependencies = false;
320 for (i = arg_size - 1; i >= 0; i--) {
321 ArgumentMap arg = state.raw_pop();
322 // Check if callee arg is a caller arg or an allocated object
323 bool allocated = arg.contains_allocated();
324 if (!(is_argument(arg) || allocated))
325 continue;
326 for (int j = 0; j < _arg_size; j++) {
327 if (arg.contains(j)) {
328 _arg_modified[j] |= analyzer._arg_modified[i];
329 }
330 }
331 if (!(is_arg_stack(arg) || allocated)) {
332 // arguments have already been recognized as escaping
333 } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
334 set_method_escape(arg);
335 must_record_dependencies = true;
336 } else {
337 set_global_escape(arg);
338 }
339 }
340 _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects();
341
342 // record dependencies if at least one parameter retained stack-allocatable
343 if (must_record_dependencies) {
344 if (code == Bytecodes::_invokeinterface || code == Bytecodes::_invokevirtual && !target->is_final_method()) {
345 _dependencies.append(actual_recv);
346 _dependencies.append(inline_target);
347 }
348 _dependencies.appendAll(analyzer.dependencies());
349 }
350 } else {
351 TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.",
352 target->name()->as_utf8()));
353 // conservatively mark all actual parameters as escaping globally
354 for (i = 0; i < arg_size; i++) {
355 ArgumentMap arg = state.raw_pop();
356 if (!is_argument(arg))
357 continue;
358 set_modified(arg, OFFSET_ANY, type2size[T_INT]*HeapWordSize);
359 set_global_escape(arg);
360 }
361 _unknown_modified = true; // assume the worst since we don't know the called method
362 }
363 }
364
|
1 /*
2 * Copyright (c) 2005, 2017, 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 *
248
249 void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) {
250 int i;
251
252 // retrieve information about the callee
253 ciInstanceKlass* klass = target->holder();
254 ciInstanceKlass* calling_klass = method()->holder();
255 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
256 ciInstanceKlass* actual_recv = callee_holder;
257
258 // Some methods are obviously bindable without any type checks so
259 // convert them directly to an invokespecial or invokestatic.
260 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
261 switch (code) {
262 case Bytecodes::_invokevirtual:
263 code = Bytecodes::_invokespecial;
264 break;
265 case Bytecodes::_invokehandle:
266 code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
267 break;
268 default:
269 break;
270 }
271 }
272
273 // compute size of arguments
274 int arg_size = target->invoke_arg_size(code);
275 int arg_base = MAX2(state._stack_height - arg_size, 0);
276
277 // direct recursive calls are skipped if they can be bound statically without introducing
278 // dependencies and if parameters are passed at the same position as in the current method
279 // other calls are skipped if there are no unescaped arguments passed to them
280 bool directly_recursive = (method() == target) &&
281 (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty());
282
283 // check if analysis of callee can safely be skipped
284 bool skip_callee = true;
285 for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) {
286 ArgumentMap arg = state._stack[i];
287 skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base));
288 }
289 // For now we conservatively skip invokedynamic.
290 if (code == Bytecodes::_invokedynamic) {
291 skip_callee = true;
292 }
293 if (skip_callee) {
294 TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8()));
295 for (i = 0; i < arg_size; i++) {
296 set_method_escape(state.raw_pop());
297 }
298 _unknown_modified = true; // assume the worst since we don't analyze the called method
299 return;
300 }
301
302 // determine actual method (use CHA if necessary)
303 ciMethod* inline_target = NULL;
304 if (target->is_loaded() && klass->is_loaded()
305 && (klass->is_initialized() || (klass->is_interface() && target->holder()->is_initialized()))
306 && target->is_loaded()) {
307 if (code == Bytecodes::_invokestatic
308 || code == Bytecodes::_invokespecial
309 || (code == Bytecodes::_invokevirtual && target->is_final_method())) {
310 inline_target = target;
311 } else {
312 inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
313 }
314 }
315
316 if (inline_target != NULL && !is_recursive_call(inline_target)) {
317 // analyze callee
318 BCEscapeAnalyzer analyzer(inline_target, this);
319
320 // adjust escape state of actual parameters
321 bool must_record_dependencies = false;
322 for (i = arg_size - 1; i >= 0; i--) {
323 ArgumentMap arg = state.raw_pop();
324 // Check if callee arg is a caller arg or an allocated object
325 bool allocated = arg.contains_allocated();
326 if (!(is_argument(arg) || allocated))
327 continue;
328 for (int j = 0; j < _arg_size; j++) {
329 if (arg.contains(j)) {
330 _arg_modified[j] |= analyzer._arg_modified[i];
331 }
332 }
333 if (!(is_arg_stack(arg) || allocated)) {
334 // arguments have already been recognized as escaping
335 } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
336 set_method_escape(arg);
337 must_record_dependencies = true;
338 } else {
339 set_global_escape(arg);
340 }
341 }
342 _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects();
343
344 // record dependencies if at least one parameter retained stack-allocatable
345 if (must_record_dependencies) {
346 if (code == Bytecodes::_invokeinterface ||
347 (code == Bytecodes::_invokevirtual && !target->is_final_method())) {
348 _dependencies.append(actual_recv);
349 _dependencies.append(inline_target);
350 }
351 _dependencies.appendAll(analyzer.dependencies());
352 }
353 } else {
354 TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.",
355 target->name()->as_utf8()));
356 // conservatively mark all actual parameters as escaping globally
357 for (i = 0; i < arg_size; i++) {
358 ArgumentMap arg = state.raw_pop();
359 if (!is_argument(arg))
360 continue;
361 set_modified(arg, OFFSET_ANY, type2size[T_INT]*HeapWordSize);
362 set_global_escape(arg);
363 }
364 _unknown_modified = true; // assume the worst since we don't know the called method
365 }
366 }
367
|