src/share/vm/opto/doCall.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7042122 Sdiff src/share/vm/opto

src/share/vm/opto/doCall.cpp

Print this page




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

  77 
  78   // See how many times this site has been invoked.
  79   int site_count = profile.count();
  80   int receiver_count = -1;
  81   if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) {
  82     // Receivers in the profile structure are ordered by call counts
  83     // so that the most called (major) receiver is profile.receiver(0).
  84     receiver_count = profile.receiver_count(0);
  85   }
  86 
  87   CompileLog* log = this->log();
  88   if (log != NULL) {
  89     int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
  90     int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
  91     log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
  92                     log->identify(call_method), site_count, prof_factor);
  93     if (call_is_virtual)  log->print(" virtual='1'");
  94     if (allow_inline)     log->print(" inline='1'");
  95     if (receiver_count >= 0) {
  96       log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);


  99       }
 100     }
 101     log->end_elem();
 102   }
 103 
 104   // Special case the handling of certain common, profitable library
 105   // methods.  If these methods are replaced with specialized code,
 106   // then we return it as the inlined version of the call.
 107   // We do this before the strict f.p. check below because the
 108   // intrinsics handle strict f.p. correctly.
 109   if (allow_inline) {
 110     cg = find_intrinsic(call_method, call_is_virtual);
 111     if (cg != NULL)  return cg;
 112   }
 113 
 114   // Do MethodHandle calls.
 115   // NOTE: This must happen before normal inlining logic below since
 116   // MethodHandle.invoke* are native methods which obviously don't
 117   // have bytecodes and so normal inlining fails.
 118   if (call_method->is_method_handle_invoke()) {
 119     if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) {
 120       GraphKit kit(jvms);
 121       Node* n = kit.argument(0);
 122 
 123       if (n->Opcode() == Op_ConP) {
 124         const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
 125         ciObject* const_oop = oop_ptr->const_oop();
 126         ciMethodHandle* method_handle = const_oop->as_method_handle();
 127 
 128         // Set the actually called method to have access to the class
 129         // and signature in the MethodHandleCompiler.
 130         method_handle->set_callee(call_method);

 131 
 132         // Get an adapter for the MethodHandle.
 133         ciMethod* target_method = method_handle->get_method_handle_adapter();
 134         CallGenerator* hit_cg = NULL;
 135         if (target_method != NULL)
 136           hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
 137         if (hit_cg != NULL && hit_cg->is_inline())
 138           return hit_cg;
 139       }

 140 
 141       return CallGenerator::for_direct_call(call_method);
 142     }
 143     else {
 144       // Get the MethodHandle from the CallSite.
 145       ciMethod* caller_method = jvms->method();
 146       ciBytecodeStream str(caller_method);
 147       str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
 148       ciCallSite*     call_site     = str.get_call_site();
 149       ciMethodHandle* method_handle = call_site->get_target();
 150 
 151       // Set the actually called method to have access to the class
 152       // and signature in the MethodHandleCompiler.
 153       method_handle->set_callee(call_method);

 154 
 155       // Get an adapter for the MethodHandle.
 156       ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 157       CallGenerator* hit_cg = NULL;
 158       if (target_method != NULL)
 159         hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
 160       if (hit_cg != NULL && hit_cg->is_inline()) {
 161         CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
 162         return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
 163       }

 164 
 165       // If something failed, generate a normal dynamic call.
 166       return CallGenerator::for_dynamic_call(call_method);
 167     }
 168   }
 169 
 170   // Do not inline strict fp into non-strict code, or the reverse
 171   bool caller_method_is_strict = jvms->method()->is_strict();
 172   if( caller_method_is_strict ^ call_method->is_strict() ) {
 173     allow_inline = false;
 174   }
 175 
 176   // Attempt to inline...
 177   if (allow_inline) {
 178     // The profile data is only partly attributable to this caller,
 179     // scale back the call site information.
 180     float past_uses = jvms->method()->scale_count(site_count, prof_factor);
 181     // This is the number of times we expect the call code to be used.
 182     float expected_uses = past_uses;
 183 




  57     tty->cr();
  58   }
  59 }
  60 #endif
  61 
  62 CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual,
  63                                        JVMState* jvms, bool allow_inline,
  64                                        float prof_factor) {
  65   CallGenerator* cg;
  66   guarantee(call_method != NULL, "failed method resolution");
  67 
  68   // Dtrace currently doesn't work unless all calls are vanilla
  69   if (env()->dtrace_method_probes()) {
  70     allow_inline = false;
  71   }
  72 
  73   // Note: When we get profiling during stage-1 compiles, we want to pull
  74   // from more specific profile data which pertains to this inlining.
  75   // Right now, ignore the information in jvms->caller(), and do method[bci].
  76   ciCallProfile profile    = jvms->method()->call_profile_at_bci(jvms->bci());
  77   Bytecodes::Code bytecode = jvms->method()->java_code_at_bci(jvms->bci());
  78 
  79   // See how many times this site has been invoked.
  80   int site_count = profile.count();
  81   int receiver_count = -1;
  82   if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) {
  83     // Receivers in the profile structure are ordered by call counts
  84     // so that the most called (major) receiver is profile.receiver(0).
  85     receiver_count = profile.receiver_count(0);
  86   }
  87 
  88   CompileLog* log = this->log();
  89   if (log != NULL) {
  90     int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
  91     int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
  92     log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
  93                     log->identify(call_method), site_count, prof_factor);
  94     if (call_is_virtual)  log->print(" virtual='1'");
  95     if (allow_inline)     log->print(" inline='1'");
  96     if (receiver_count >= 0) {
  97       log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);


 100       }
 101     }
 102     log->end_elem();
 103   }
 104 
 105   // Special case the handling of certain common, profitable library
 106   // methods.  If these methods are replaced with specialized code,
 107   // then we return it as the inlined version of the call.
 108   // We do this before the strict f.p. check below because the
 109   // intrinsics handle strict f.p. correctly.
 110   if (allow_inline) {
 111     cg = find_intrinsic(call_method, call_is_virtual);
 112     if (cg != NULL)  return cg;
 113   }
 114 
 115   // Do MethodHandle calls.
 116   // NOTE: This must happen before normal inlining logic below since
 117   // MethodHandle.invoke* are native methods which obviously don't
 118   // have bytecodes and so normal inlining fails.
 119   if (call_method->is_method_handle_invoke()) {
 120     if (bytecode != Bytecodes::_invokedynamic) {
 121       GraphKit kit(jvms);
 122       Node* n = kit.argument(0);
 123 
 124       if (n->Opcode() == Op_ConP) {
 125         const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
 126         ciObject* const_oop = oop_ptr->const_oop();
 127         ciMethodHandle* method_handle = const_oop->as_method_handle();
 128 
 129         // Set the actually called method to have access to the class
 130         // and signature in the MethodHandleCompiler.
 131         method_handle->set_callee(call_method);
 132         method_handle->set_call_profile(&profile);
 133 
 134         // Get an adapter for the MethodHandle.
 135         ciMethod* target_method = method_handle->get_method_handle_adapter();
 136         if (target_method != NULL) {
 137           CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);

 138           if (hit_cg != NULL && hit_cg->is_inline())
 139             return hit_cg;
 140         }
 141       }
 142 
 143       return CallGenerator::for_direct_call(call_method);
 144     }
 145     else {
 146       // Get the MethodHandle from the CallSite.
 147       ciMethod* caller_method = jvms->method();
 148       ciBytecodeStream str(caller_method);
 149       str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
 150       ciCallSite*     call_site     = str.get_call_site();
 151       ciMethodHandle* method_handle = call_site->get_target();
 152 
 153       // Set the actually called method to have access to the class
 154       // and signature in the MethodHandleCompiler.
 155       method_handle->set_callee(call_method);
 156       method_handle->set_call_profile(&profile);
 157 
 158       // Get an adapter for the MethodHandle.
 159       ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 160       if (target_method != NULL) {
 161         CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);

 162         if (hit_cg != NULL && hit_cg->is_inline()) {
 163           CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
 164           return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
 165         }
 166       }
 167 
 168       // If something failed, generate a normal dynamic call.
 169       return CallGenerator::for_dynamic_call(call_method);
 170     }
 171   }
 172 
 173   // Do not inline strict fp into non-strict code, or the reverse
 174   bool caller_method_is_strict = jvms->method()->is_strict();
 175   if( caller_method_is_strict ^ call_method->is_strict() ) {
 176     allow_inline = false;
 177   }
 178 
 179   // Attempt to inline...
 180   if (allow_inline) {
 181     // The profile data is only partly attributable to this caller,
 182     // scale back the call site information.
 183     float past_uses = jvms->method()->scale_count(site_count, prof_factor);
 184     // This is the number of times we expect the call code to be used.
 185     float expected_uses = past_uses;
 186 


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