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; |