hotspot/src/share/vm/opto/callGenerator.cpp
changeset 14132 3c1437abcefd
parent 13895 f6dfe4123709
child 14621 fd9265ab0f67
equal deleted inserted replaced
14131:e376e3d428c9 14132:3c1437abcefd
   668   }
   668   }
   669   return NULL;
   669   return NULL;
   670 }
   670 }
   671 
   671 
   672 
   672 
       
   673 //------------------------PredictedIntrinsicGenerator------------------------------
       
   674 // Internal class which handles all predicted Intrinsic calls.
       
   675 class PredictedIntrinsicGenerator : public CallGenerator {
       
   676   CallGenerator* _intrinsic;
       
   677   CallGenerator* _cg;
       
   678 
       
   679 public:
       
   680   PredictedIntrinsicGenerator(CallGenerator* intrinsic,
       
   681                               CallGenerator* cg)
       
   682     : CallGenerator(cg->method())
       
   683   {
       
   684     _intrinsic = intrinsic;
       
   685     _cg        = cg;
       
   686   }
       
   687 
       
   688   virtual bool      is_virtual()   const    { return true; }
       
   689   virtual bool      is_inlined()   const    { return true; }
       
   690   virtual bool      is_intrinsic() const    { return true; }
       
   691 
       
   692   virtual JVMState* generate(JVMState* jvms);
       
   693 };
       
   694 
       
   695 
       
   696 CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic,
       
   697                                                       CallGenerator* cg) {
       
   698   return new PredictedIntrinsicGenerator(intrinsic, cg);
       
   699 }
       
   700 
       
   701 
       
   702 JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms) {
       
   703   GraphKit kit(jvms);
       
   704   PhaseGVN& gvn = kit.gvn();
       
   705 
       
   706   CompileLog* log = kit.C->log();
       
   707   if (log != NULL) {
       
   708     log->elem("predicted_intrinsic bci='%d' method='%d'",
       
   709               jvms->bci(), log->identify(method()));
       
   710   }
       
   711 
       
   712   Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms());
       
   713   if (kit.failing())
       
   714     return NULL;  // might happen because of NodeCountInliningCutoff
       
   715 
       
   716   SafePointNode* slow_map = NULL;
       
   717   JVMState* slow_jvms;
       
   718   if (slow_ctl != NULL) {
       
   719     PreserveJVMState pjvms(&kit);
       
   720     kit.set_control(slow_ctl);
       
   721     if (!kit.stopped()) {
       
   722       slow_jvms = _cg->generate(kit.sync_jvms());
       
   723       if (kit.failing())
       
   724         return NULL;  // might happen because of NodeCountInliningCutoff
       
   725       assert(slow_jvms != NULL, "must be");
       
   726       kit.add_exception_states_from(slow_jvms);
       
   727       kit.set_map(slow_jvms->map());
       
   728       if (!kit.stopped())
       
   729         slow_map = kit.stop();
       
   730     }
       
   731   }
       
   732 
       
   733   if (kit.stopped()) {
       
   734     // Predicate is always false.
       
   735     kit.set_jvms(slow_jvms);
       
   736     return kit.transfer_exceptions_into_jvms();
       
   737   }
       
   738 
       
   739   // Generate intrinsic code:
       
   740   JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms());
       
   741   if (new_jvms == NULL) {
       
   742     // Intrinsic failed, so use slow code or make a direct call.
       
   743     if (slow_map == NULL) {
       
   744       CallGenerator* cg = CallGenerator::for_direct_call(method());
       
   745       new_jvms = cg->generate(kit.sync_jvms());
       
   746     } else {
       
   747       kit.set_jvms(slow_jvms);
       
   748       return kit.transfer_exceptions_into_jvms();
       
   749     }
       
   750   }
       
   751   kit.add_exception_states_from(new_jvms);
       
   752   kit.set_jvms(new_jvms);
       
   753 
       
   754   // Need to merge slow and fast?
       
   755   if (slow_map == NULL) {
       
   756     // The fast path is the only path remaining.
       
   757     return kit.transfer_exceptions_into_jvms();
       
   758   }
       
   759 
       
   760   if (kit.stopped()) {
       
   761     // Intrinsic method threw an exception, so it's just the slow path after all.
       
   762     kit.set_jvms(slow_jvms);
       
   763     return kit.transfer_exceptions_into_jvms();
       
   764   }
       
   765 
       
   766   // Finish the diamond.
       
   767   kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
       
   768   RegionNode* region = new (kit.C) RegionNode(3);
       
   769   region->init_req(1, kit.control());
       
   770   region->init_req(2, slow_map->control());
       
   771   kit.set_control(gvn.transform(region));
       
   772   Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
       
   773   iophi->set_req(2, slow_map->i_o());
       
   774   kit.set_i_o(gvn.transform(iophi));
       
   775   kit.merge_memory(slow_map->merged_memory(), region, 2);
       
   776   uint tos = kit.jvms()->stkoff() + kit.sp();
       
   777   uint limit = slow_map->req();
       
   778   for (uint i = TypeFunc::Parms; i < limit; i++) {
       
   779     // Skip unused stack slots; fast forward to monoff();
       
   780     if (i == tos) {
       
   781       i = kit.jvms()->monoff();
       
   782       if( i >= limit ) break;
       
   783     }
       
   784     Node* m = kit.map()->in(i);
       
   785     Node* n = slow_map->in(i);
       
   786     if (m != n) {
       
   787       const Type* t = gvn.type(m)->meet(gvn.type(n));
       
   788       Node* phi = PhiNode::make(region, m, t);
       
   789       phi->set_req(2, n);
       
   790       kit.map()->set_req(i, gvn.transform(phi));
       
   791     }
       
   792   }
       
   793   return kit.transfer_exceptions_into_jvms();
       
   794 }
       
   795 
   673 //-------------------------UncommonTrapCallGenerator-----------------------------
   796 //-------------------------UncommonTrapCallGenerator-----------------------------
   674 // Internal class which handles all out-of-line calls checking receiver type.
   797 // Internal class which handles all out-of-line calls checking receiver type.
   675 class UncommonTrapCallGenerator : public CallGenerator {
   798 class UncommonTrapCallGenerator : public CallGenerator {
   676   Deoptimization::DeoptReason _reason;
   799   Deoptimization::DeoptReason _reason;
   677   Deoptimization::DeoptAction _action;
   800   Deoptimization::DeoptAction _action;