805 ctrl = copy->is_copy();
806 } else { // a cast
807 assert(ctrl->req() == 3 &&
808 ctrl->in(1) != NULL && ctrl->in(1)->is_Proj() &&
809 ctrl->in(2) != NULL && ctrl->in(2)->is_Proj() &&
810 ctrl->in(1)->in(0) == ctrl->in(2)->in(0) &&
811 ctrl->in(1)->in(0) != NULL && ctrl->in(1)->in(0)->is_If(),
812 "must be a simple diamond");
813 Node* true_proj = ctrl->in(1)->is_IfTrue() ? ctrl->in(1) : ctrl->in(2);
814 for (SimpleDUIterator i(true_proj); i.has_next(); i.next()) {
815 Node* use = i.get();
816 assert(use == ctrl || use->is_ConstraintCast(),
817 err_msg_res("unexpected user: %s", use->Name()));
818 }
819
820 iff = ctrl->in(1)->in(0)->as_If();
821 ctrl = iff->in(0);
822 }
823 } else if (ctrl->is_IfTrue()) { // null checks, class checks
824 iff = ctrl->in(0)->as_If();
825 assert(iff->is_If(), "must be if");
826 // Verify that the other arm is an uncommon trap
827 Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con);
828 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
829 assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommond trap");
830 ctrl = iff->in(0);
831 } else {
832 break;
833 }
834 }
835
836 assert(ctrl->is_Proj(), "must be a projection");
837 assert(ctrl->in(0)->is_Initialize(), "should be initialize");
838 for (SimpleDUIterator i(ctrl); i.has_next(); i.next()) {
839 Node* use = i.get();
840 assert(use == copy || use == iff || use == curr || use->is_CheckCastPP() || use->is_Load(),
841 err_msg_res("unexpected user: %s", use->Name()));
842 }
843 #endif // ASSERT
844 }
845 }
846 }
847
848 #ifndef PRODUCT
849 if (PrintOptimizeStringConcat) {
894 ctrl_path.push(cn->proj_out(0)->unique_out());
895 if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
896 ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
897 }
898 } else {
899 ShouldNotReachHere();
900 }
901 }
902
903 // Skip backwards through the control checking for unexpected control flow
904 Node* ptr = _end;
905 bool fail = false;
906 while (ptr != _begin) {
907 if (ptr->is_Call() && ctrl_path.member(ptr)) {
908 ptr = ptr->in(0);
909 } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
910 ptr = ptr->in(0)->in(0)->in(0);
911 assert(ctrl_path.member(ptr), "should be a known piece of control");
912 } else if (ptr->is_IfTrue()) {
913 IfNode* iff = ptr->in(0)->as_If();
914 BoolNode* b = iff->in(1)->isa_Bool();
915
916 if (b == NULL) {
917 fail = true;
918 break;
919 }
920
921 Node* cmp = b->in(1);
922 Node* v1 = cmp->in(1);
923 Node* v2 = cmp->in(2);
924 Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
925
926 // Null check of the return of append which can simply be eliminated
927 if (b->_test._test == BoolTest::ne &&
928 v2->bottom_type() == TypePtr::NULL_PTR &&
929 v1->is_Proj() && ctrl_path.member(v1->in(0))) {
930 // NULL check of the return value of the append
931 null_check_count++;
932 if (otherproj->outcnt() == 1) {
933 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
934 if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
935 ctrl_path.push(call);
936 }
|
805 ctrl = copy->is_copy();
806 } else { // a cast
807 assert(ctrl->req() == 3 &&
808 ctrl->in(1) != NULL && ctrl->in(1)->is_Proj() &&
809 ctrl->in(2) != NULL && ctrl->in(2)->is_Proj() &&
810 ctrl->in(1)->in(0) == ctrl->in(2)->in(0) &&
811 ctrl->in(1)->in(0) != NULL && ctrl->in(1)->in(0)->is_If(),
812 "must be a simple diamond");
813 Node* true_proj = ctrl->in(1)->is_IfTrue() ? ctrl->in(1) : ctrl->in(2);
814 for (SimpleDUIterator i(true_proj); i.has_next(); i.next()) {
815 Node* use = i.get();
816 assert(use == ctrl || use->is_ConstraintCast(),
817 err_msg_res("unexpected user: %s", use->Name()));
818 }
819
820 iff = ctrl->in(1)->in(0)->as_If();
821 ctrl = iff->in(0);
822 }
823 } else if (ctrl->is_IfTrue()) { // null checks, class checks
824 iff = ctrl->in(0)->as_If();
825 // Verify that the other arm is an uncommon trap
826 if (iff->outcnt() == 2) {
827 Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con);
828 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
829 assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommon trap");
830 }
831 ctrl = iff->in(0);
832 } else {
833 break;
834 }
835 }
836
837 assert(ctrl->is_Proj(), "must be a projection");
838 assert(ctrl->in(0)->is_Initialize(), "should be initialize");
839 for (SimpleDUIterator i(ctrl); i.has_next(); i.next()) {
840 Node* use = i.get();
841 assert(use == copy || use == iff || use == curr || use->is_CheckCastPP() || use->is_Load(),
842 err_msg_res("unexpected user: %s", use->Name()));
843 }
844 #endif // ASSERT
845 }
846 }
847 }
848
849 #ifndef PRODUCT
850 if (PrintOptimizeStringConcat) {
895 ctrl_path.push(cn->proj_out(0)->unique_out());
896 if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
897 ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
898 }
899 } else {
900 ShouldNotReachHere();
901 }
902 }
903
904 // Skip backwards through the control checking for unexpected control flow
905 Node* ptr = _end;
906 bool fail = false;
907 while (ptr != _begin) {
908 if (ptr->is_Call() && ctrl_path.member(ptr)) {
909 ptr = ptr->in(0);
910 } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
911 ptr = ptr->in(0)->in(0)->in(0);
912 assert(ctrl_path.member(ptr), "should be a known piece of control");
913 } else if (ptr->is_IfTrue()) {
914 IfNode* iff = ptr->in(0)->as_If();
915 // Skip dead test
916 if (iff->in(1)->is_Con()) {
917 ptr = ptr->in(0)->in(0);
918 continue;
919 }
920
921 BoolNode* b = iff->in(1)->isa_Bool();
922 if (b == NULL) {
923 #ifndef PRODUCT
924 if (PrintOptimizeStringConcat) {
925 tty->print_cr("unexpected input to IfNode");
926 iff->in(1)->dump();
927 tty->cr();
928 }
929 #endif
930 fail = true;
931 break;
932 }
933
934 Node* cmp = b->in(1);
935 Node* v1 = cmp->in(1);
936 Node* v2 = cmp->in(2);
937 Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
938
939 // Null check of the return of append which can simply be eliminated
940 if (b->_test._test == BoolTest::ne &&
941 v2->bottom_type() == TypePtr::NULL_PTR &&
942 v1->is_Proj() && ctrl_path.member(v1->in(0))) {
943 // NULL check of the return value of the append
944 null_check_count++;
945 if (otherproj->outcnt() == 1) {
946 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
947 if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
948 ctrl_path.push(call);
949 }
|