src/share/vm/ci/bcEscapeAnalyzer.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7011839 Sdiff src/share/vm/ci

src/share/vm/ci/bcEscapeAnalyzer.cpp

Print this page


   1 /*
   2  * Copyright (c) 2005, 2010, 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  *


 216 }
 217 
 218 void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) {
 219   int i;
 220 
 221   // retrieve information about the callee
 222   ciInstanceKlass* klass = target->holder();
 223   ciInstanceKlass* calling_klass = method()->holder();
 224   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
 225   ciInstanceKlass* actual_recv = callee_holder;
 226 
 227   // some methods are obviously bindable without any type checks so
 228   // convert them directly to an invokespecial.
 229   if (target->is_loaded() && !target->is_abstract() &&
 230       target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
 231     code = Bytecodes::_invokespecial;
 232   }
 233 
 234   // compute size of arguments
 235   int arg_size = target->arg_size();




 236   if (!target->is_loaded() && code == Bytecodes::_invokestatic) {
 237     arg_size--;
 238   }
 239   int arg_base = MAX2(state._stack_height - arg_size, 0);
 240 
 241   // direct recursive calls are skipped if they can be bound statically without introducing
 242   // dependencies and if parameters are passed at the same position as in the current method
 243   // other calls are skipped if there are no unescaped arguments passed to them
 244   bool directly_recursive = (method() == target) &&
 245                (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty());
 246 
 247   // check if analysis of callee can safely be skipped
 248   bool skip_callee = true;
 249   for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) {
 250     ArgumentMap arg = state._stack[i];
 251     skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base));
 252   }




 253   if (skip_callee) {
 254     TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8()));
 255     for (i = 0; i < arg_size; i++) {
 256       set_method_escape(state.raw_pop());
 257     }
 258     _unknown_modified = true;  // assume the worst since we don't analyze the called method
 259     return;
 260   }
 261 
 262   // determine actual method (use CHA if necessary)
 263   ciMethod* inline_target = NULL;
 264   if (target->is_loaded() && klass->is_loaded()
 265       && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
 266       && target->will_link(klass, callee_holder, code)) {
 267     if (code == Bytecodes::_invokestatic
 268         || code == Bytecodes::_invokespecial
 269         || code == Bytecodes::_invokevirtual && target->is_final_method()) {
 270       inline_target = target;
 271     } else {
 272       inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);


   1 /*
   2  * Copyright (c) 2005, 2011, 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  *


 216 }
 217 
 218 void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) {
 219   int i;
 220 
 221   // retrieve information about the callee
 222   ciInstanceKlass* klass = target->holder();
 223   ciInstanceKlass* calling_klass = method()->holder();
 224   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
 225   ciInstanceKlass* actual_recv = callee_holder;
 226 
 227   // some methods are obviously bindable without any type checks so
 228   // convert them directly to an invokespecial.
 229   if (target->is_loaded() && !target->is_abstract() &&
 230       target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
 231     code = Bytecodes::_invokespecial;
 232   }
 233 
 234   // compute size of arguments
 235   int arg_size = target->arg_size();
 236   if (code == Bytecodes::_invokedynamic) {
 237     assert(!target->is_static(), "receiver explicit in method");
 238     arg_size--;  // implicit, not really on stack
 239   }
 240   if (!target->is_loaded() && code == Bytecodes::_invokestatic) {
 241     arg_size--;
 242   }
 243   int arg_base = MAX2(state._stack_height - arg_size, 0);
 244 
 245   // direct recursive calls are skipped if they can be bound statically without introducing
 246   // dependencies and if parameters are passed at the same position as in the current method
 247   // other calls are skipped if there are no unescaped arguments passed to them
 248   bool directly_recursive = (method() == target) &&
 249                (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty());
 250 
 251   // check if analysis of callee can safely be skipped
 252   bool skip_callee = true;
 253   for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) {
 254     ArgumentMap arg = state._stack[i];
 255     skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base));
 256   }
 257   // For now we conservatively skip invokedynamic.
 258   if (code == Bytecodes::_invokedynamic) {
 259     skip_callee = true;
 260   }
 261   if (skip_callee) {
 262     TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8()));
 263     for (i = 0; i < arg_size; i++) {
 264       set_method_escape(state.raw_pop());
 265     }
 266     _unknown_modified = true;  // assume the worst since we don't analyze the called method
 267     return;
 268   }
 269 
 270   // determine actual method (use CHA if necessary)
 271   ciMethod* inline_target = NULL;
 272   if (target->is_loaded() && klass->is_loaded()
 273       && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
 274       && target->will_link(klass, callee_holder, code)) {
 275     if (code == Bytecodes::_invokestatic
 276         || code == Bytecodes::_invokespecial
 277         || code == Bytecodes::_invokevirtual && target->is_final_method()) {
 278       inline_target = target;
 279     } else {
 280       inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);


src/share/vm/ci/bcEscapeAnalyzer.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File