src/share/vm/opto/doCall.cpp

Print this page
rev 3898 : 8005031: Some cleanup in c2 to prepare for incremental inlining support
Summary: collection of small changes to prepare for incremental inlining.
Reviewed-by:


  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciCallSite.hpp"
  27 #include "ci/ciMethodHandle.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "compiler/compileLog.hpp"
  31 #include "interpreter/linkResolver.hpp"
  32 #include "opto/addnode.hpp"
  33 #include "opto/callGenerator.hpp"
  34 #include "opto/cfgnode.hpp"
  35 #include "opto/mulnode.hpp"
  36 #include "opto/parse.hpp"
  37 #include "opto/rootnode.hpp"
  38 #include "opto/runtime.hpp"
  39 #include "opto/subnode.hpp"
  40 #include "prims/nativeLookup.hpp"
  41 #include "runtime/sharedRuntime.hpp"
  42 
  43 void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
  44   if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) {

  45     if (!PrintInlining) {
  46       if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
  47         method->print_short_name();
  48         tty->cr();
  49       }
  50       CompileTask::print_inlining(prof_method, depth, bci);


  51     }
  52     CompileTask::print_inline_indent(depth);
  53     tty->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
  54     prof_klass->name()->print_symbol();
  55     tty->cr();


  56   }
  57 }
  58 
  59 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual,
  60                                        JVMState* jvms, bool allow_inline,
  61                                        float prof_factor, bool allow_intrinsics) {
  62   ciMethod*       caller   = jvms->method();
  63   int             bci      = jvms->bci();
  64   Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
  65   guarantee(callee != NULL, "failed method resolution");
  66 
  67   // Dtrace currently doesn't work unless all calls are vanilla
  68   if (env()->dtrace_method_probes()) {
  69     allow_inline = false;
  70   }
  71 
  72   // Note: When we get profiling during stage-1 compiles, we want to pull
  73   // from more specific profile data which pertains to this inlining.
  74   // Right now, ignore the information in jvms->caller(), and do method[bci].
  75   ciCallProfile profile = caller->call_profile_at_bci(bci);


 216           }
 217           CallGenerator* miss_cg;
 218           Deoptimization::DeoptReason reason = (profile.morphism() == 2) ?
 219                                     Deoptimization::Reason_bimorphic :
 220                                     Deoptimization::Reason_class_check;
 221           if (( profile.morphism() == 1 ||
 222                (profile.morphism() == 2 && next_hit_cg != NULL) ) &&
 223               !too_many_traps(jvms->method(), jvms->bci(), reason)
 224              ) {
 225             // Generate uncommon trap for class check failure path
 226             // in case of monomorphic or bimorphic virtual call site.
 227             miss_cg = CallGenerator::for_uncommon_trap(callee, reason,
 228                         Deoptimization::Action_maybe_recompile);
 229           } else {
 230             // Generate virtual call for class check failure path
 231             // in case of polymorphic virtual call site.
 232             miss_cg = CallGenerator::for_virtual_call(callee, vtable_index);
 233           }
 234           if (miss_cg != NULL) {
 235             if (next_hit_cg != NULL) {
 236               trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1));
 237               // We don't need to record dependency on a receiver here and below.
 238               // Whenever we inline, the dependency is added by Parse::Parse().
 239               miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
 240             }
 241             if (miss_cg != NULL) {
 242               trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count);
 243               CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
 244               if (cg != NULL)  return cg;
 245             }
 246           }
 247         }
 248       }
 249     }
 250   }
 251 
 252   // There was no special inlining tactic, or it bailed out.
 253   // Use a more generic tactic, like a simple call.
 254   if (call_is_virtual) {
 255     return CallGenerator::for_virtual_call(callee, vtable_index);
 256   } else {
 257     // Class Hierarchy Analysis or Type Profile reveals a unique target,
 258     // or it is a static or special call.
 259     return CallGenerator::for_direct_call(callee, should_delay_inlining(callee, jvms));
 260   }
 261 }
 262 




  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciCallSite.hpp"
  27 #include "ci/ciMethodHandle.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "compiler/compileLog.hpp"
  31 #include "interpreter/linkResolver.hpp"
  32 #include "opto/addnode.hpp"
  33 #include "opto/callGenerator.hpp"
  34 #include "opto/cfgnode.hpp"
  35 #include "opto/mulnode.hpp"
  36 #include "opto/parse.hpp"
  37 #include "opto/rootnode.hpp"
  38 #include "opto/runtime.hpp"
  39 #include "opto/subnode.hpp"
  40 #include "prims/nativeLookup.hpp"
  41 #include "runtime/sharedRuntime.hpp"
  42 
  43 void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
  44   if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) {
  45     outputStream* out = tty;
  46     if (!PrintInlining) {
  47       if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
  48         method->print_short_name();
  49         tty->cr();
  50       }
  51       CompileTask::print_inlining(prof_method, depth, bci);
  52     } else {
  53       out = C->print_inlining_stream();
  54     }
  55     CompileTask::print_inline_indent(depth, out);
  56     out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
  57     stringStream ss;
  58     prof_klass->name()->print_symbol_on(&ss);
  59     out->print(ss.as_string());
  60     out->cr();
  61   }
  62 }
  63 
  64 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual,
  65                                        JVMState* jvms, bool allow_inline,
  66                                        float prof_factor, bool allow_intrinsics) {
  67   ciMethod*       caller   = jvms->method();
  68   int             bci      = jvms->bci();
  69   Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
  70   guarantee(callee != NULL, "failed method resolution");
  71 
  72   // Dtrace currently doesn't work unless all calls are vanilla
  73   if (env()->dtrace_method_probes()) {
  74     allow_inline = false;
  75   }
  76 
  77   // Note: When we get profiling during stage-1 compiles, we want to pull
  78   // from more specific profile data which pertains to this inlining.
  79   // Right now, ignore the information in jvms->caller(), and do method[bci].
  80   ciCallProfile profile = caller->call_profile_at_bci(bci);


 221           }
 222           CallGenerator* miss_cg;
 223           Deoptimization::DeoptReason reason = (profile.morphism() == 2) ?
 224                                     Deoptimization::Reason_bimorphic :
 225                                     Deoptimization::Reason_class_check;
 226           if (( profile.morphism() == 1 ||
 227                (profile.morphism() == 2 && next_hit_cg != NULL) ) &&
 228               !too_many_traps(jvms->method(), jvms->bci(), reason)
 229              ) {
 230             // Generate uncommon trap for class check failure path
 231             // in case of monomorphic or bimorphic virtual call site.
 232             miss_cg = CallGenerator::for_uncommon_trap(callee, reason,
 233                         Deoptimization::Action_maybe_recompile);
 234           } else {
 235             // Generate virtual call for class check failure path
 236             // in case of polymorphic virtual call site.
 237             miss_cg = CallGenerator::for_virtual_call(callee, vtable_index);
 238           }
 239           if (miss_cg != NULL) {
 240             if (next_hit_cg != NULL) {
 241               trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1));
 242               // We don't need to record dependency on a receiver here and below.
 243               // Whenever we inline, the dependency is added by Parse::Parse().
 244               miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
 245             }
 246             if (miss_cg != NULL) {
 247               trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count);
 248               CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
 249               if (cg != NULL)  return cg;
 250             }
 251           }
 252         }
 253       }
 254     }
 255   }
 256 
 257   // There was no special inlining tactic, or it bailed out.
 258   // Use a more generic tactic, like a simple call.
 259   if (call_is_virtual) {
 260     return CallGenerator::for_virtual_call(callee, vtable_index);
 261   } else {
 262     // Class Hierarchy Analysis or Type Profile reveals a unique target,
 263     // or it is a static or special call.
 264     return CallGenerator::for_direct_call(callee, should_delay_inlining(callee, jvms));
 265   }
 266 }
 267