145 } |
145 } |
146 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) { |
146 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) { |
147 return generate_method_call(method_id, true, false); |
147 return generate_method_call(method_id, true, false); |
148 } |
148 } |
149 |
149 |
150 Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2); |
150 Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2); |
|
151 Node* make_string_method_node(int opcode, Node* str1, Node* str2); |
151 bool inline_string_compareTo(); |
152 bool inline_string_compareTo(); |
152 bool inline_string_indexOf(); |
153 bool inline_string_indexOf(); |
153 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i); |
154 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i); |
154 bool inline_string_equals(); |
155 bool inline_string_equals(); |
155 Node* pop_math_arg(); |
156 Node* pop_math_arg(); |
871 return threadObj; |
872 return threadObj; |
872 } |
873 } |
873 |
874 |
874 |
875 |
875 //------------------------------make_string_method_node------------------------ |
876 //------------------------------make_string_method_node------------------------ |
876 // Helper method for String intrinsic finctions. |
877 // Helper method for String intrinsic functions. This version is called |
877 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) { |
878 // with str1 and str2 pointing to String object nodes. |
878 const int value_offset = java_lang_String::value_offset_in_bytes(); |
879 // |
879 const int count_offset = java_lang_String::count_offset_in_bytes(); |
880 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* str2) { |
880 const int offset_offset = java_lang_String::offset_offset_in_bytes(); |
|
881 |
|
882 Node* no_ctrl = NULL; |
881 Node* no_ctrl = NULL; |
883 |
882 |
884 ciInstanceKlass* klass = env()->String_klass(); |
883 // Get start addr of string |
885 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
884 Node* str1_value = load_String_value(no_ctrl, str1); |
886 |
885 Node* str1_offset = load_String_offset(no_ctrl, str1); |
887 const TypeAryPtr* value_type = |
|
888 TypeAryPtr::make(TypePtr::NotNull, |
|
889 TypeAry::make(TypeInt::CHAR,TypeInt::POS), |
|
890 ciTypeArrayKlass::make(T_CHAR), true, 0); |
|
891 |
|
892 // Get start addr of string and substring |
|
893 Node* str1_valuea = basic_plus_adr(str1, str1, value_offset); |
|
894 Node* str1_value = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset)); |
|
895 Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset); |
|
896 Node* str1_offset = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset)); |
|
897 Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR); |
886 Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR); |
898 |
887 |
899 Node* str2_valuea = basic_plus_adr(str2, str2, value_offset); |
888 // Get length of string 1 |
900 Node* str2_value = make_load(no_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset)); |
889 Node* str1_len = load_String_length(no_ctrl, str1); |
901 Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset); |
890 |
902 Node* str2_offset = make_load(no_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset)); |
891 Node* str2_value = load_String_value(no_ctrl, str2); |
|
892 Node* str2_offset = load_String_offset(no_ctrl, str2); |
903 Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR); |
893 Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR); |
|
894 |
|
895 Node* str2_len = NULL; |
|
896 Node* result = NULL; |
|
897 |
|
898 switch (opcode) { |
|
899 case Op_StrIndexOf: |
|
900 // Get length of string 2 |
|
901 str2_len = load_String_length(no_ctrl, str2); |
|
902 |
|
903 result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), |
|
904 str1_start, str1_len, str2_start, str2_len); |
|
905 break; |
|
906 case Op_StrComp: |
|
907 // Get length of string 2 |
|
908 str2_len = load_String_length(no_ctrl, str2); |
|
909 |
|
910 result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS), |
|
911 str1_start, str1_len, str2_start, str2_len); |
|
912 break; |
|
913 case Op_StrEquals: |
|
914 result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), |
|
915 str1_start, str2_start, str1_len); |
|
916 break; |
|
917 default: |
|
918 ShouldNotReachHere(); |
|
919 return NULL; |
|
920 } |
|
921 |
|
922 // All these intrinsics have checks. |
|
923 C->set_has_split_ifs(true); // Has chance for split-if optimization |
|
924 |
|
925 return _gvn.transform(result); |
|
926 } |
|
927 |
|
928 // Helper method for String intrinsic functions. This version is called |
|
929 // with str1 and str2 pointing to char[] nodes, with cnt1 and cnt2 pointing |
|
930 // to Int nodes containing the lenghts of str1 and str2. |
|
931 // |
|
932 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2) { |
904 |
933 |
905 Node* result = NULL; |
934 Node* result = NULL; |
906 switch (opcode) { |
935 switch (opcode) { |
907 case Op_StrIndexOf: |
936 case Op_StrIndexOf: |
908 result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), |
937 result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), |
909 str1_start, cnt1, str2_start, cnt2); |
938 str1_start, cnt1, str2_start, cnt2); |
910 break; |
939 break; |
911 case Op_StrComp: |
940 case Op_StrComp: |
912 result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS), |
941 result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS), |
913 str1_start, cnt1, str2_start, cnt2); |
942 str1_start, cnt1, str2_start, cnt2); |
914 break; |
943 break; |
915 case Op_StrEquals: |
944 case Op_StrEquals: |
916 result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), |
945 result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), |
917 str1_start, str2_start, cnt1); |
946 str1_start, str2_start, cnt1); |
918 break; |
947 break; |
919 default: |
948 default: |
920 ShouldNotReachHere(); |
949 ShouldNotReachHere(); |
921 return NULL; |
950 return NULL; |
922 } |
951 } |
950 _sp -= 2; |
975 _sp -= 2; |
951 if (stopped()) { |
976 if (stopped()) { |
952 return true; |
977 return true; |
953 } |
978 } |
954 |
979 |
955 ciInstanceKlass* klass = env()->String_klass(); |
980 Node* compare = make_string_method_node(Op_StrComp, receiver, argument); |
956 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
|
957 Node* no_ctrl = NULL; |
|
958 |
|
959 // Get counts for string and argument |
|
960 Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset); |
|
961 Node* receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
|
962 |
|
963 Node* argument_cnta = basic_plus_adr(argument, argument, count_offset); |
|
964 Node* argument_cnt = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
|
965 |
|
966 Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt); |
|
967 push(compare); |
981 push(compare); |
968 return true; |
982 return true; |
969 } |
983 } |
970 |
984 |
971 //------------------------------inline_string_equals------------------------ |
985 //------------------------------inline_string_equals------------------------ |
972 bool LibraryCallKit::inline_string_equals() { |
986 bool LibraryCallKit::inline_string_equals() { |
973 |
987 |
974 if (!Matcher::has_match_rule(Op_StrEquals)) return false; |
988 if (!Matcher::has_match_rule(Op_StrEquals)) return false; |
975 |
|
976 const int value_offset = java_lang_String::value_offset_in_bytes(); |
|
977 const int count_offset = java_lang_String::count_offset_in_bytes(); |
|
978 const int offset_offset = java_lang_String::offset_offset_in_bytes(); |
|
979 |
989 |
980 int nargs = 2; |
990 int nargs = 2; |
981 _sp += nargs; |
991 _sp += nargs; |
982 Node* argument = pop(); // pop non-receiver first: it was pushed second |
992 Node* argument = pop(); // pop non-receiver first: it was pushed second |
983 Node* receiver = pop(); |
993 Node* receiver = pop(); |
1028 phi->init_req(3, intcon(0)); |
1038 phi->init_req(3, intcon(0)); |
1029 region->init_req(3, inst_false); |
1039 region->init_req(3, inst_false); |
1030 } |
1040 } |
1031 } |
1041 } |
1032 |
1042 |
1033 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
|
1034 |
|
1035 Node* no_ctrl = NULL; |
|
1036 Node* receiver_cnt; |
|
1037 Node* argument_cnt; |
|
1038 |
|
1039 if (!stopped()) { |
1043 if (!stopped()) { |
|
1044 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
|
1045 |
1040 // Properly cast the argument to String |
1046 // Properly cast the argument to String |
1041 argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type)); |
1047 argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type)); |
1042 // This path is taken only when argument's type is String:NotNull. |
1048 // This path is taken only when argument's type is String:NotNull. |
1043 argument = cast_not_null(argument, false); |
1049 argument = cast_not_null(argument, false); |
1044 |
1050 |
1045 // Get counts for string and argument |
1051 Node* no_ctrl = NULL; |
1046 Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset); |
1052 |
1047 receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
1053 // Get start addr of receiver |
1048 |
1054 Node* receiver_val = load_String_value(no_ctrl, receiver); |
1049 Node* argument_cnta = basic_plus_adr(argument, argument, count_offset); |
1055 Node* receiver_offset = load_String_offset(no_ctrl, receiver); |
1050 argument_cnt = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
1056 Node* receiver_start = array_element_address(receiver_val, receiver_offset, T_CHAR); |
|
1057 |
|
1058 // Get length of receiver |
|
1059 Node* receiver_cnt = load_String_length(no_ctrl, receiver); |
|
1060 |
|
1061 // Get start addr of argument |
|
1062 Node* argument_val = load_String_value(no_ctrl, argument); |
|
1063 Node* argument_offset = load_String_offset(no_ctrl, argument); |
|
1064 Node* argument_start = array_element_address(argument_val, argument_offset, T_CHAR); |
|
1065 |
|
1066 // Get length of argument |
|
1067 Node* argument_cnt = load_String_length(no_ctrl, argument); |
1051 |
1068 |
1052 // Check for receiver count != argument count |
1069 // Check for receiver count != argument count |
1053 Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) ); |
1070 Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) ); |
1054 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) ); |
1071 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) ); |
1055 Node* if_ne = generate_slow_guard(bol, NULL); |
1072 Node* if_ne = generate_slow_guard(bol, NULL); |
1056 if (if_ne != NULL) { |
1073 if (if_ne != NULL) { |
1057 phi->init_req(4, intcon(0)); |
1074 phi->init_req(4, intcon(0)); |
1058 region->init_req(4, if_ne); |
1075 region->init_req(4, if_ne); |
1059 } |
1076 } |
1060 } |
1077 |
1061 |
1078 // Check for count == 0 is done by assembler code for StrEquals. |
1062 // Check for count == 0 is done by mach node StrEquals. |
1079 |
1063 |
1080 if (!stopped()) { |
1064 if (!stopped()) { |
1081 Node* equals = make_string_method_node(Op_StrEquals, receiver_start, receiver_cnt, argument_start, argument_cnt); |
1065 Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt); |
1082 phi->init_req(1, equals); |
1066 phi->init_req(1, equals); |
1083 region->init_req(1, control()); |
1067 region->init_req(1, control()); |
1084 } |
1068 } |
1085 } |
1069 |
1086 |
1070 // post merge |
1087 // post merge |
1071 set_control(_gvn.transform(region)); |
1088 set_control(_gvn.transform(region)); |
1072 record_for_igvn(region); |
1089 record_for_igvn(region); |
1160 float likely = PROB_LIKELY(0.9); |
1177 float likely = PROB_LIKELY(0.9); |
1161 float unlikely = PROB_UNLIKELY(0.9); |
1178 float unlikely = PROB_UNLIKELY(0.9); |
1162 |
1179 |
1163 const int nargs = 2; // number of arguments to push back for uncommon trap in predicate |
1180 const int nargs = 2; // number of arguments to push back for uncommon trap in predicate |
1164 |
1181 |
1165 const int value_offset = java_lang_String::value_offset_in_bytes(); |
1182 Node* source = load_String_value(no_ctrl, string_object); |
1166 const int count_offset = java_lang_String::count_offset_in_bytes(); |
1183 Node* sourceOffset = load_String_offset(no_ctrl, string_object); |
1167 const int offset_offset = java_lang_String::offset_offset_in_bytes(); |
1184 Node* sourceCount = load_String_length(no_ctrl, string_object); |
1168 |
|
1169 ciInstanceKlass* klass = env()->String_klass(); |
|
1170 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
|
1171 const TypeAryPtr* source_type = TypeAryPtr::make(TypePtr::NotNull, TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0); |
|
1172 |
|
1173 Node* sourceOffseta = basic_plus_adr(string_object, string_object, offset_offset); |
|
1174 Node* sourceOffset = make_load(no_ctrl, sourceOffseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset)); |
|
1175 Node* sourceCounta = basic_plus_adr(string_object, string_object, count_offset); |
|
1176 Node* sourceCount = make_load(no_ctrl, sourceCounta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
|
1177 Node* sourcea = basic_plus_adr(string_object, string_object, value_offset); |
|
1178 Node* source = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset)); |
|
1179 |
1185 |
1180 Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) ); |
1186 Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) ); |
1181 jint target_length = target_array->length(); |
1187 jint target_length = target_array->length(); |
1182 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); |
1188 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); |
1183 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); |
1189 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); |
1278 // Make the merge point |
1280 // Make the merge point |
1279 RegionNode* result_rgn = new (C, 4) RegionNode(4); |
1281 RegionNode* result_rgn = new (C, 4) RegionNode(4); |
1280 Node* result_phi = new (C, 4) PhiNode(result_rgn, TypeInt::INT); |
1282 Node* result_phi = new (C, 4) PhiNode(result_rgn, TypeInt::INT); |
1281 Node* no_ctrl = NULL; |
1283 Node* no_ctrl = NULL; |
1282 |
1284 |
1283 // Get counts for string and substr |
1285 // Get start addr of source string |
1284 Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset); |
1286 Node* source = load_String_value(no_ctrl, receiver); |
1285 Node* source_cnt = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
1287 Node* source_offset = load_String_offset(no_ctrl, receiver); |
1286 |
1288 Node* source_start = array_element_address(source, source_offset, T_CHAR); |
1287 Node* substr_cnta = basic_plus_adr(argument, argument, count_offset); |
1289 |
1288 Node* substr_cnt = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
1290 // Get length of source string |
|
1291 Node* source_cnt = load_String_length(no_ctrl, receiver); |
|
1292 |
|
1293 // Get start addr of substring |
|
1294 Node* substr = load_String_value(no_ctrl, argument); |
|
1295 Node* substr_offset = load_String_offset(no_ctrl, argument); |
|
1296 Node* substr_start = array_element_address(substr, substr_offset, T_CHAR); |
|
1297 |
|
1298 // Get length of source string |
|
1299 Node* substr_cnt = load_String_length(no_ctrl, argument); |
1289 |
1300 |
1290 // Check for substr count > string count |
1301 // Check for substr count > string count |
1291 Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) ); |
1302 Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) ); |
1292 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) ); |
1303 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) ); |
1293 Node* if_gt = generate_slow_guard(bol, NULL); |
1304 Node* if_gt = generate_slow_guard(bol, NULL); |