< prev index next >

src/share/vm/ci/bcEscapeAnalyzer.cpp

Print this page


   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 


< prev index next >