src/share/vm/opto/doCall.cpp

changeset 5991
b2ee5dc63353
parent 5981
3213ba4d3dff
child 6198
55fb97c4c58d
     1.1 --- a/src/share/vm/opto/doCall.cpp	Wed Oct 23 10:00:39 2013 +0200
     1.2 +++ b/src/share/vm/opto/doCall.cpp	Wed Oct 23 12:40:23 2013 +0200
     1.3 @@ -63,7 +63,8 @@
     1.4  
     1.5  CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_does_dispatch,
     1.6                                         JVMState* jvms, bool allow_inline,
     1.7 -                                       float prof_factor, bool allow_intrinsics, bool delayed_forbidden) {
     1.8 +                                       float prof_factor, ciKlass* speculative_receiver_type,
     1.9 +                                       bool allow_intrinsics, bool delayed_forbidden) {
    1.10    ciMethod*       caller   = jvms->method();
    1.11    int             bci      = jvms->bci();
    1.12    Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
    1.13 @@ -117,7 +118,7 @@
    1.14        if (cg->is_predicted()) {
    1.15          // Code without intrinsic but, hopefully, inlined.
    1.16          CallGenerator* inline_cg = this->call_generator(callee,
    1.17 -              vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, false);
    1.18 +              vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, speculative_receiver_type, false);
    1.19          if (inline_cg != NULL) {
    1.20            cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
    1.21          }
    1.22 @@ -212,8 +213,24 @@
    1.23        // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count.
    1.24        bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent);
    1.25        ciMethod* receiver_method = NULL;
    1.26 -      if (have_major_receiver || profile.morphism() == 1 ||
    1.27 -          (profile.morphism() == 2 && UseBimorphicInlining)) {
    1.28 +
    1.29 +      int morphism = profile.morphism();
    1.30 +      if (speculative_receiver_type != NULL) {
    1.31 +        // We have a speculative type, we should be able to resolve
    1.32 +        // the call. We do that before looking at the profiling at
    1.33 +        // this invoke because it may lead to bimorphic inlining which
    1.34 +        // a speculative type should help us avoid.
    1.35 +        receiver_method = callee->resolve_invoke(jvms->method()->holder(),
    1.36 +                                                 speculative_receiver_type);
    1.37 +        if (receiver_method == NULL) {
    1.38 +          speculative_receiver_type = NULL;
    1.39 +        } else {
    1.40 +          morphism = 1;
    1.41 +        }
    1.42 +      }
    1.43 +      if (receiver_method == NULL &&
    1.44 +          (have_major_receiver || morphism == 1 ||
    1.45 +           (morphism == 2 && UseBimorphicInlining))) {
    1.46          // receiver_method = profile.method();
    1.47          // Profiles do not suggest methods now.  Look it up in the major receiver.
    1.48          receiver_method = callee->resolve_invoke(jvms->method()->holder(),
    1.49 @@ -227,7 +244,7 @@
    1.50            // Look up second receiver.
    1.51            CallGenerator* next_hit_cg = NULL;
    1.52            ciMethod* next_receiver_method = NULL;
    1.53 -          if (profile.morphism() == 2 && UseBimorphicInlining) {
    1.54 +          if (morphism == 2 && UseBimorphicInlining) {
    1.55              next_receiver_method = callee->resolve_invoke(jvms->method()->holder(),
    1.56                                                                 profile.receiver(1));
    1.57              if (next_receiver_method != NULL) {
    1.58 @@ -242,11 +259,10 @@
    1.59              }
    1.60            }
    1.61            CallGenerator* miss_cg;
    1.62 -          Deoptimization::DeoptReason reason = (profile.morphism() == 2) ?
    1.63 +          Deoptimization::DeoptReason reason = morphism == 2 ?
    1.64                                      Deoptimization::Reason_bimorphic :
    1.65                                      Deoptimization::Reason_class_check;
    1.66 -          if (( profile.morphism() == 1 ||
    1.67 -               (profile.morphism() == 2 && next_hit_cg != NULL) ) &&
    1.68 +          if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL)) &&
    1.69                !too_many_traps(jvms->method(), jvms->bci(), reason)
    1.70               ) {
    1.71              // Generate uncommon trap for class check failure path
    1.72 @@ -260,6 +276,7 @@
    1.73            }
    1.74            if (miss_cg != NULL) {
    1.75              if (next_hit_cg != NULL) {
    1.76 +              assert(speculative_receiver_type == NULL, "shouldn't end up here if we used speculation");
    1.77                trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1));
    1.78                // We don't need to record dependency on a receiver here and below.
    1.79                // Whenever we inline, the dependency is added by Parse::Parse().
    1.80 @@ -267,7 +284,9 @@
    1.81              }
    1.82              if (miss_cg != NULL) {
    1.83                trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count);
    1.84 -              CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
    1.85 +              ciKlass* k = speculative_receiver_type != NULL ? speculative_receiver_type : profile.receiver(0);
    1.86 +              float hit_prob = speculative_receiver_type != NULL ? 1.0 : profile.receiver_prob(0);
    1.87 +              CallGenerator* cg = CallGenerator::for_predicted_call(k, miss_cg, hit_cg, hit_prob);
    1.88                if (cg != NULL)  return cg;
    1.89              }
    1.90            }
    1.91 @@ -446,13 +465,16 @@
    1.92    int       vtable_index       = Method::invalid_vtable_index;
    1.93    bool      call_does_dispatch = false;
    1.94  
    1.95 +  // Speculative type of the receiver if any
    1.96 +  ciKlass* speculative_receiver_type = NULL;
    1.97    if (is_virtual_or_interface) {
    1.98 -    Node*             receiver_node = stack(sp() - nargs);
    1.99 +    Node* receiver_node             = stack(sp() - nargs);
   1.100      const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
   1.101      // call_does_dispatch and vtable_index are out-parameters.  They might be changed.
   1.102      callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type,
   1.103                                        is_virtual,
   1.104                                        call_does_dispatch, vtable_index);  // out-parameters
   1.105 +    speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
   1.106    }
   1.107  
   1.108    // Note:  It's OK to try to inline a virtual call.
   1.109 @@ -468,7 +490,7 @@
   1.110    // Decide call tactic.
   1.111    // This call checks with CHA, the interpreter profile, intrinsics table, etc.
   1.112    // It decides whether inlining is desirable or not.
   1.113 -  CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor());
   1.114 +  CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type);
   1.115  
   1.116    // NOTE:  Don't use orig_callee and callee after this point!  Use cg->method() instead.
   1.117    orig_callee = callee = NULL;
   1.118 @@ -477,6 +499,10 @@
   1.119    // Round double arguments before call
   1.120    round_double_arguments(cg->method());
   1.121  
   1.122 +  // Feed profiling data for arguments to the type system so it can
   1.123 +  // propagate it as speculative types
   1.124 +  record_profiled_arguments_for_speculation(cg->method(), bc());
   1.125 +
   1.126  #ifndef PRODUCT
   1.127    // bump global counters for calls
   1.128    count_compiled_calls(/*at_method_entry*/ false, cg->is_inline());
   1.129 @@ -491,6 +517,13 @@
   1.130    // save across call, for a subsequent cast_not_null.
   1.131    Node* receiver = has_receiver ? argument(0) : NULL;
   1.132  
   1.133 +  // The extra CheckCastPP for speculative types mess with PhaseStringOpts
   1.134 +  if (receiver != NULL && !call_does_dispatch && !cg->is_string_late_inline()) {
   1.135 +    // Feed profiling data for a single receiver to the type system so
   1.136 +    // it can propagate it as a speculative type
   1.137 +    receiver = record_profiled_receiver_for_speculation(receiver);
   1.138 +  }
   1.139 +
   1.140    // Bump method data counters (We profile *before* the call is made
   1.141    // because exceptions don't return to the call site.)
   1.142    profile_call(receiver);
   1.143 @@ -508,7 +541,7 @@
   1.144      // the call site, perhaps because it did not match a pattern the
   1.145      // intrinsic was expecting to optimize. Should always be possible to
   1.146      // get a normal java call that may inline in that case
   1.147 -    cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false);
   1.148 +    cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type, /* allow_intrinsics= */ false);
   1.149      if ((new_jvms = cg->generate(jvms, this)) == NULL) {
   1.150        guarantee(failing(), "call failed to generate:  calls should work");
   1.151        return;
   1.152 @@ -607,6 +640,16 @@
   1.153        null_assert(peek());
   1.154        set_bci(iter().cur_bci()); // put it back
   1.155      }
   1.156 +    BasicType ct = ctype->basic_type();
   1.157 +    if (ct == T_OBJECT || ct == T_ARRAY) {
   1.158 +      ciKlass* better_type = method()->return_profiled_type(bci());
   1.159 +      if (UseTypeSpeculation && better_type != NULL) {
   1.160 +        // If profiling reports a single type for the return value,
   1.161 +        // feed it to the type system so it can propagate it as a
   1.162 +        // speculative type
   1.163 +        record_profile_for_speculation(stack(sp()-1), better_type);
   1.164 +      }
   1.165 +    }
   1.166    }
   1.167  
   1.168    // Restart record of parsing work after possible inlining of call

mercurial