116 return generate_array_guard_common(kls, region, false, true);
117 }
118 Node* generate_objArray_guard(Node* kls, RegionNode* region) {
119 return generate_array_guard_common(kls, region, true, false);
120 }
121 Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
122 return generate_array_guard_common(kls, region, true, true);
123 }
124 Node* generate_array_guard_common(Node* kls, RegionNode* region,
125 bool obj_array, bool not_array);
126 Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
127 CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
128 bool is_virtual = false, bool is_static = false);
129 CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
130 return generate_method_call(method_id, false, true);
131 }
132 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
133 return generate_method_call(method_id, true, false);
134 }
135
136 bool inline_string_compareTo();
137 bool inline_string_indexOf();
138 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
139 bool inline_string_equals();
140 Node* pop_math_arg();
141 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
142 bool inline_math_native(vmIntrinsics::ID id);
143 bool inline_trig(vmIntrinsics::ID id);
144 bool inline_trans(vmIntrinsics::ID id);
145 bool inline_abs(vmIntrinsics::ID id);
146 bool inline_sqrt(vmIntrinsics::ID id);
147 bool inline_pow(vmIntrinsics::ID id);
148 bool inline_exp(vmIntrinsics::ID id);
149 bool inline_min_max(vmIntrinsics::ID id);
150 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
151 // This returns Type::AnyPtr, RawPtr, or OopPtr.
152 int classify_unsafe_addr(Node* &base, Node* &offset);
153 Node* make_unsafe_address(Node* base, Node* offset);
154 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
155 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
779 last = _gvn.transform( new (C, 3) AddINode(last, offset));
780 Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) );
781 Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
782 Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
783 return is_over;
784 }
785
786
787 //--------------------------generate_current_thread--------------------
788 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
789 ciKlass* thread_klass = env()->Thread_klass();
790 const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
791 Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode());
792 Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
793 Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
794 tls_output = thread;
795 return threadObj;
796 }
797
798
799 //------------------------------inline_string_compareTo------------------------
800 bool LibraryCallKit::inline_string_compareTo() {
801
802 if (!Matcher::has_match_rule(Op_StrComp)) return false;
803
804 const int value_offset = java_lang_String::value_offset_in_bytes();
805 const int count_offset = java_lang_String::count_offset_in_bytes();
806 const int offset_offset = java_lang_String::offset_offset_in_bytes();
807
808 _sp += 2;
809 Node *argument = pop(); // pop non-receiver first: it was pushed second
810 Node *receiver = pop();
811
812 // Null check on self without removing any arguments. The argument
813 // null check technically happens in the wrong place, which can lead to
814 // invalid stack traces when string compare is inlined into a method
815 // which handles NullPointerExceptions.
816 _sp += 2;
817 receiver = do_null_check(receiver, T_OBJECT);
818 argument = do_null_check(argument, T_OBJECT);
819 _sp -= 2;
820 if (stopped()) {
821 return true;
822 }
823
824 ciInstanceKlass* klass = env()->String_klass();
825 const TypeInstPtr* string_type =
826 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
827
828 Node* compare =
829 _gvn.transform(new (C, 7) StrCompNode(
830 control(),
831 memory(TypeAryPtr::CHARS),
832 memory(string_type->add_offset(value_offset)),
833 memory(string_type->add_offset(count_offset)),
834 memory(string_type->add_offset(offset_offset)),
835 receiver,
836 argument));
837 push(compare);
838 return true;
839 }
840
841 //------------------------------inline_string_equals------------------------
842 bool LibraryCallKit::inline_string_equals() {
843
844 if (!Matcher::has_match_rule(Op_StrEquals)) return false;
845
846 const int value_offset = java_lang_String::value_offset_in_bytes();
847 const int count_offset = java_lang_String::count_offset_in_bytes();
848 const int offset_offset = java_lang_String::offset_offset_in_bytes();
849
850 _sp += 2;
851 Node* argument = pop(); // pop non-receiver first: it was pushed second
852 Node* receiver = pop();
853
854 // Null check on self without removing any arguments. The argument
855 // null check technically happens in the wrong place, which can lead to
856 // invalid stack traces when string compare is inlined into a method
857 // which handles NullPointerExceptions.
858 _sp += 2;
859 receiver = do_null_check(receiver, T_OBJECT);
860 //should not do null check for argument for String.equals(), because spec
861 //allows to specify NULL as argument.
862 _sp -= 2;
863
864 if (stopped()) {
865 return true;
866 }
867
868 // get String klass for instanceOf
869 ciInstanceKlass* klass = env()->String_klass();
870
871 // two paths (plus control) merge
872 RegionNode* region = new (C, 3) RegionNode(3);
873 Node* phi = new (C, 3) PhiNode(region, TypeInt::BOOL);
874
875 Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
876 Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
877 Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
878
879 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
880
881 Node* if_true = _gvn.transform(new (C, 1) IfTrueNode(iff));
882 set_control(if_true);
883
884 const TypeInstPtr* string_type =
885 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
886
887 // instanceOf == true
888 Node* equals =
889 _gvn.transform(new (C, 7) StrEqualsNode(
890 control(),
891 memory(TypeAryPtr::CHARS),
892 memory(string_type->add_offset(value_offset)),
893 memory(string_type->add_offset(count_offset)),
894 memory(string_type->add_offset(offset_offset)),
895 receiver,
896 argument));
897
898 phi->init_req(1, _gvn.transform(equals));
899 region->init_req(1, if_true);
900
901 //instanceOf == false, fallthrough
902 Node* if_false = _gvn.transform(new (C, 1) IfFalseNode(iff));
903 set_control(if_false);
904
905 phi->init_req(2, _gvn.transform(intcon(0)));
906 region->init_req(2, if_false);
907
908 // post merge
909 set_control(_gvn.transform(region));
910 record_for_igvn(region);
911
912 push(_gvn.transform(phi));
913
914 return true;
915 }
916
917 //------------------------------inline_array_equals----------------------------
918 bool LibraryCallKit::inline_array_equals() {
919
920 if (!Matcher::has_match_rule(Op_AryEq)) return false;
921
922 _sp += 2;
923 Node *argument2 = pop();
924 Node *argument1 = pop();
925
926 Node* equals =
927 _gvn.transform(new (C, 3) AryEqNode(control(),
928 argument1,
929 argument2)
930 );
931 push(equals);
932 return true;
933 }
934
935 // Java version of String.indexOf(constant string)
936 // class StringDecl {
937 // StringDecl(char[] ca) {
938 // offset = 0;
939 // count = ca.length;
940 // value = ca;
941 // }
942 // int offset;
943 // int count;
944 // char[] value;
945 // }
946 //
947 // static int string_indexOf_J(StringDecl string_object, char[] target_object,
948 // int targetOffset, int cache_i, int md2) {
949 // int cache = cache_i;
950 // int sourceOffset = string_object.offset;
1091
1092 Node* result;
1093 if (Matcher::has_match_rule(Op_StrIndexOf) &&
1094 UseSSE42Intrinsics) {
1095 // Generate SSE4.2 version of indexOf
1096 // We currently only have match rules that use SSE4.2
1097
1098 // Null check on self without removing any arguments. The argument
1099 // null check technically happens in the wrong place, which can lead to
1100 // invalid stack traces when string compare is inlined into a method
1101 // which handles NullPointerExceptions.
1102 _sp += 2;
1103 receiver = do_null_check(receiver, T_OBJECT);
1104 argument = do_null_check(argument, T_OBJECT);
1105 _sp -= 2;
1106
1107 if (stopped()) {
1108 return true;
1109 }
1110
1111 ciInstanceKlass* klass = env()->String_klass();
1112 const TypeInstPtr* string_type =
1113 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
1114
1115 result =
1116 _gvn.transform(new (C, 7)
1117 StrIndexOfNode(control(),
1118 memory(TypeAryPtr::CHARS),
1119 memory(string_type->add_offset(value_offset)),
1120 memory(string_type->add_offset(count_offset)),
1121 memory(string_type->add_offset(offset_offset)),
1122 receiver,
1123 argument));
1124 } else { //Use LibraryCallKit::string_indexOf
1125 // don't intrinsify is argument isn't a constant string.
1126 if (!argument->is_Con()) {
1127 return false;
1128 }
1129 const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1130 if (str_type == NULL) {
1131 return false;
1132 }
1133 ciInstanceKlass* klass = env()->String_klass();
1134 ciObject* str_const = str_type->const_oop();
1135 if (str_const == NULL || str_const->klass() != klass) {
1136 return false;
1137 }
1138 ciInstance* str = str_const->as_instance();
1139 assert(str != NULL, "must be instance");
1140
1141 ciObject* v = str->field_value_by_offset(value_offset).as_object();
1142 int o = str->field_value_by_offset(offset_offset).as_int();
1143 int c = str->field_value_by_offset(count_offset).as_int();
|
116 return generate_array_guard_common(kls, region, false, true);
117 }
118 Node* generate_objArray_guard(Node* kls, RegionNode* region) {
119 return generate_array_guard_common(kls, region, true, false);
120 }
121 Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
122 return generate_array_guard_common(kls, region, true, true);
123 }
124 Node* generate_array_guard_common(Node* kls, RegionNode* region,
125 bool obj_array, bool not_array);
126 Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
127 CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
128 bool is_virtual = false, bool is_static = false);
129 CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
130 return generate_method_call(method_id, false, true);
131 }
132 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
133 return generate_method_call(method_id, true, false);
134 }
135
136 Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2);
137 bool inline_string_compareTo();
138 bool inline_string_indexOf();
139 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
140 bool inline_string_equals();
141 Node* pop_math_arg();
142 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
143 bool inline_math_native(vmIntrinsics::ID id);
144 bool inline_trig(vmIntrinsics::ID id);
145 bool inline_trans(vmIntrinsics::ID id);
146 bool inline_abs(vmIntrinsics::ID id);
147 bool inline_sqrt(vmIntrinsics::ID id);
148 bool inline_pow(vmIntrinsics::ID id);
149 bool inline_exp(vmIntrinsics::ID id);
150 bool inline_min_max(vmIntrinsics::ID id);
151 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
152 // This returns Type::AnyPtr, RawPtr, or OopPtr.
153 int classify_unsafe_addr(Node* &base, Node* &offset);
154 Node* make_unsafe_address(Node* base, Node* offset);
155 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
156 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
780 last = _gvn.transform( new (C, 3) AddINode(last, offset));
781 Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) );
782 Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
783 Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
784 return is_over;
785 }
786
787
788 //--------------------------generate_current_thread--------------------
789 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
790 ciKlass* thread_klass = env()->Thread_klass();
791 const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
792 Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode());
793 Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
794 Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
795 tls_output = thread;
796 return threadObj;
797 }
798
799
800 //------------------------------make_string_method_node------------------------
801 // Helper method for String intrinsic finctions.
802 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) {
803 const int value_offset = java_lang_String::value_offset_in_bytes();
804 const int count_offset = java_lang_String::count_offset_in_bytes();
805 const int offset_offset = java_lang_String::offset_offset_in_bytes();
806
807 Node* no_ctrl = NULL;
808
809 ciInstanceKlass* klass = env()->String_klass();
810 const TypeInstPtr* string_type =
811 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
812
813 const TypeAryPtr* value_type =
814 TypeAryPtr::make(TypePtr::NotNull,
815 TypeAry::make(TypeInt::CHAR,TypeInt::POS),
816 ciTypeArrayKlass::make(T_CHAR), true, 0);
817
818 // Get start addr of string and substring
819 Node* str1_valuea = basic_plus_adr(str1, str1, value_offset);
820 Node* str1_value = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
821 Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset);
822 Node* str1_offset = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
823 Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR);
824
825 // Pin loads from String::equals() argument since it could be NULL.
826 Node* str2_ctrl = (opcode == Op_StrEquals) ? control() : no_ctrl;
827 Node* str2_valuea = basic_plus_adr(str2, str2, value_offset);
828 Node* str2_value = make_load(str2_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
829 Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset);
830 Node* str2_offset = make_load(str2_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
831 Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR);
832
833 Node* result = NULL;
834 switch (opcode) {
835 case Op_StrIndexOf:
836 result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
837 str1_start, cnt1, str2_start, cnt2);
838 break;
839 case Op_StrComp:
840 result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
841 str1_start, cnt1, str2_start, cnt2);
842 break;
843 case Op_StrEquals:
844 result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
845 str1_start, str2_start, cnt1);
846 break;
847 default:
848 ShouldNotReachHere();
849 return NULL;
850 }
851
852 // All these intrinsics have checks.
853 C->set_has_split_ifs(true); // Has chance for split-if optimization
854
855 return _gvn.transform(result);
856 }
857
858 //------------------------------inline_string_compareTo------------------------
859 bool LibraryCallKit::inline_string_compareTo() {
860
861 if (!Matcher::has_match_rule(Op_StrComp)) return false;
862
863 const int value_offset = java_lang_String::value_offset_in_bytes();
864 const int count_offset = java_lang_String::count_offset_in_bytes();
865 const int offset_offset = java_lang_String::offset_offset_in_bytes();
866
867 _sp += 2;
868 Node *argument = pop(); // pop non-receiver first: it was pushed second
869 Node *receiver = pop();
870
871 // Null check on self without removing any arguments. The argument
872 // null check technically happens in the wrong place, which can lead to
873 // invalid stack traces when string compare is inlined into a method
874 // which handles NullPointerExceptions.
875 _sp += 2;
876 receiver = do_null_check(receiver, T_OBJECT);
877 argument = do_null_check(argument, T_OBJECT);
878 _sp -= 2;
879 if (stopped()) {
880 return true;
881 }
882
883 ciInstanceKlass* klass = env()->String_klass();
884 const TypeInstPtr* string_type =
885 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
886 Node* no_ctrl = NULL;
887
888 // Get counts for string and argument
889 Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
890 Node* receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
891
892 Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
893 Node* argument_cnt = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
894
895 Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt);
896 push(compare);
897 return true;
898 }
899
900 //------------------------------inline_string_equals------------------------
901 bool LibraryCallKit::inline_string_equals() {
902
903 if (!Matcher::has_match_rule(Op_StrEquals)) return false;
904
905 const int value_offset = java_lang_String::value_offset_in_bytes();
906 const int count_offset = java_lang_String::count_offset_in_bytes();
907 const int offset_offset = java_lang_String::offset_offset_in_bytes();
908
909 _sp += 2;
910 Node* argument = pop(); // pop non-receiver first: it was pushed second
911 Node* receiver = pop();
912
913 // Null check on self without removing any arguments. The argument
914 // null check technically happens in the wrong place, which can lead to
915 // invalid stack traces when string compare is inlined into a method
916 // which handles NullPointerExceptions.
917 _sp += 2;
918 receiver = do_null_check(receiver, T_OBJECT);
919 //should not do null check for argument for String.equals(), because spec
920 //allows to specify NULL as argument.
921 _sp -= 2;
922
923 if (stopped()) {
924 return true;
925 }
926
927 // paths (plus control) merge
928 RegionNode* region = new (C, 5) RegionNode(5);
929 Node* phi = new (C, 5) PhiNode(region, TypeInt::BOOL);
930
931 // does source == target string?
932 Node* cmp = _gvn.transform(new (C, 3) CmpPNode(receiver, argument));
933 Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
934
935 Node* if_eq = generate_slow_guard(bol, NULL);
936 if (if_eq != NULL) {
937 // receiver == argument
938 phi->init_req(2, intcon(1));
939 region->init_req(2, if_eq);
940 }
941
942 // get String klass for instanceOf
943 ciInstanceKlass* klass = env()->String_klass();
944
945 if (!stopped()) {
946 Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
947 Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
948 Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
949
950 Node* inst_false = generate_guard(bol, NULL, PROB_MIN);
951 //instanceOf == true, fallthrough
952
953 if (inst_false != NULL) {
954 phi->init_req(3, intcon(0));
955 region->init_req(3, inst_false);
956 }
957 }
958
959 const TypeInstPtr* string_type =
960 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
961
962 Node* no_ctrl = NULL;
963 Node* receiver_cnt;
964 Node* argument_cnt;
965
966 if (!stopped()) {
967 // Get counts for string and argument
968 Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
969 receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
970
971 // Pin load from argument string since it could be NULL.
972 Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
973 argument_cnt = make_load(control(), argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
974
975 // Check for receiver count != argument count
976 Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) );
977 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) );
978 Node* if_ne = generate_slow_guard(bol, NULL);
979 if (if_ne != NULL) {
980 phi->init_req(4, intcon(0));
981 region->init_req(4, if_ne);
982 }
983 }
984
985 // Check for count == 0 is done by mach node StrEquals.
986
987 if (!stopped()) {
988 Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt);
989 phi->init_req(1, equals);
990 region->init_req(1, control());
991 }
992
993 // post merge
994 set_control(_gvn.transform(region));
995 record_for_igvn(region);
996
997 push(_gvn.transform(phi));
998
999 return true;
1000 }
1001
1002 //------------------------------inline_array_equals----------------------------
1003 bool LibraryCallKit::inline_array_equals() {
1004
1005 if (!Matcher::has_match_rule(Op_AryEq)) return false;
1006
1007 _sp += 2;
1008 Node *argument2 = pop();
1009 Node *argument1 = pop();
1010
1011 Node* equals =
1012 _gvn.transform(new (C, 4) AryEqNode(control(), memory(TypeAryPtr::CHARS),
1013 argument1, argument2) );
1014 push(equals);
1015 return true;
1016 }
1017
1018 // Java version of String.indexOf(constant string)
1019 // class StringDecl {
1020 // StringDecl(char[] ca) {
1021 // offset = 0;
1022 // count = ca.length;
1023 // value = ca;
1024 // }
1025 // int offset;
1026 // int count;
1027 // char[] value;
1028 // }
1029 //
1030 // static int string_indexOf_J(StringDecl string_object, char[] target_object,
1031 // int targetOffset, int cache_i, int md2) {
1032 // int cache = cache_i;
1033 // int sourceOffset = string_object.offset;
1174
1175 Node* result;
1176 if (Matcher::has_match_rule(Op_StrIndexOf) &&
1177 UseSSE42Intrinsics) {
1178 // Generate SSE4.2 version of indexOf
1179 // We currently only have match rules that use SSE4.2
1180
1181 // Null check on self without removing any arguments. The argument
1182 // null check technically happens in the wrong place, which can lead to
1183 // invalid stack traces when string compare is inlined into a method
1184 // which handles NullPointerExceptions.
1185 _sp += 2;
1186 receiver = do_null_check(receiver, T_OBJECT);
1187 argument = do_null_check(argument, T_OBJECT);
1188 _sp -= 2;
1189
1190 if (stopped()) {
1191 return true;
1192 }
1193
1194 // Make the merge point
1195 RegionNode* result_rgn = new (C, 3) RegionNode(3);
1196 Node* result_phi = new (C, 3) PhiNode(result_rgn, TypeInt::INT);
1197 Node* no_ctrl = NULL;
1198
1199 ciInstanceKlass* klass = env()->String_klass();
1200 const TypeInstPtr* string_type =
1201 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
1202
1203 // Get counts for string and substr
1204 Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset);
1205 Node* source_cnt = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
1206
1207 Node* substr_cnta = basic_plus_adr(argument, argument, count_offset);
1208 Node* substr_cnt = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
1209
1210 // Check for substr count > string count
1211 Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) );
1212 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) );
1213 Node* if_gt = generate_slow_guard(bol, NULL);
1214 if (if_gt != NULL) {
1215 result_phi->init_req(2, intcon(-1));
1216 result_rgn->init_req(2, if_gt);
1217 }
1218
1219 if (!stopped()) {
1220 result = make_string_method_node(Op_StrIndexOf, receiver, source_cnt, argument, substr_cnt);
1221 result_phi->init_req(1, result);
1222 result_rgn->init_req(1, control());
1223 }
1224 set_control(_gvn.transform(result_rgn));
1225 record_for_igvn(result_rgn);
1226 result = _gvn.transform(result_phi);
1227
1228 } else { //Use LibraryCallKit::string_indexOf
1229 // don't intrinsify is argument isn't a constant string.
1230 if (!argument->is_Con()) {
1231 return false;
1232 }
1233 const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1234 if (str_type == NULL) {
1235 return false;
1236 }
1237 ciInstanceKlass* klass = env()->String_klass();
1238 ciObject* str_const = str_type->const_oop();
1239 if (str_const == NULL || str_const->klass() != klass) {
1240 return false;
1241 }
1242 ciInstance* str = str_const->as_instance();
1243 assert(str != NULL, "must be instance");
1244
1245 ciObject* v = str->field_value_by_offset(value_offset).as_object();
1246 int o = str->field_value_by_offset(offset_offset).as_int();
1247 int c = str->field_value_by_offset(count_offset).as_int();
|