comparison src/share/vm/opto/library_call.cpp @ 681:fbde8ec322d0

6761600: Use sse 4.2 in intrinsics Summary: Use SSE 4.2 in intrinsics for String.{compareTo/equals/indexOf} and Arrays.equals. Reviewed-by: kvn, never, jrose
author cfang
date Tue, 31 Mar 2009 14:07:08 -0700
parents c771b7f43bbf
children 9c6be3edf0dc
comparison
equal deleted inserted replaced
676:d3676b4cb78c 681:fbde8ec322d0
134 } 134 }
135 135
136 bool inline_string_compareTo(); 136 bool inline_string_compareTo();
137 bool inline_string_indexOf(); 137 bool inline_string_indexOf();
138 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i); 138 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
139 bool inline_string_equals();
139 Node* pop_math_arg(); 140 Node* pop_math_arg();
140 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName); 141 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
141 bool inline_math_native(vmIntrinsics::ID id); 142 bool inline_math_native(vmIntrinsics::ID id);
142 bool inline_trig(vmIntrinsics::ID id); 143 bool inline_trig(vmIntrinsics::ID id);
143 bool inline_trans(vmIntrinsics::ID id); 144 bool inline_trans(vmIntrinsics::ID id);
259 // -XX:-InlineNatives disables nearly all intrinsics: 260 // -XX:-InlineNatives disables nearly all intrinsics:
260 if (!InlineNatives) { 261 if (!InlineNatives) {
261 switch (id) { 262 switch (id) {
262 case vmIntrinsics::_indexOf: 263 case vmIntrinsics::_indexOf:
263 case vmIntrinsics::_compareTo: 264 case vmIntrinsics::_compareTo:
265 case vmIntrinsics::_equals:
264 case vmIntrinsics::_equalsC: 266 case vmIntrinsics::_equalsC:
265 break; // InlineNatives does not control String.compareTo 267 break; // InlineNatives does not control String.compareTo
266 default: 268 default:
267 return NULL; 269 return NULL;
268 } 270 }
272 case vmIntrinsics::_compareTo: 274 case vmIntrinsics::_compareTo:
273 if (!SpecialStringCompareTo) return NULL; 275 if (!SpecialStringCompareTo) return NULL;
274 break; 276 break;
275 case vmIntrinsics::_indexOf: 277 case vmIntrinsics::_indexOf:
276 if (!SpecialStringIndexOf) return NULL; 278 if (!SpecialStringIndexOf) return NULL;
279 break;
280 case vmIntrinsics::_equals:
281 if (!SpecialStringEquals) return NULL;
277 break; 282 break;
278 case vmIntrinsics::_equalsC: 283 case vmIntrinsics::_equalsC:
279 if (!SpecialArraysEquals) return NULL; 284 if (!SpecialArraysEquals) return NULL;
280 break; 285 break;
281 case vmIntrinsics::_arraycopy: 286 case vmIntrinsics::_arraycopy:
440 445
441 case vmIntrinsics::_compareTo: 446 case vmIntrinsics::_compareTo:
442 return inline_string_compareTo(); 447 return inline_string_compareTo();
443 case vmIntrinsics::_indexOf: 448 case vmIntrinsics::_indexOf:
444 return inline_string_indexOf(); 449 return inline_string_indexOf();
450 case vmIntrinsics::_equals:
451 return inline_string_equals();
445 452
446 case vmIntrinsics::_getObject: 453 case vmIntrinsics::_getObject:
447 return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, false); 454 return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, false);
448 case vmIntrinsics::_getBoolean: 455 case vmIntrinsics::_getBoolean:
449 return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, false); 456 return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, false);
791 798
792 799
793 //------------------------------inline_string_compareTo------------------------ 800 //------------------------------inline_string_compareTo------------------------
794 bool LibraryCallKit::inline_string_compareTo() { 801 bool LibraryCallKit::inline_string_compareTo() {
795 802
803 if (!Matcher::has_match_rule(Op_StrComp)) return false;
804
796 const int value_offset = java_lang_String::value_offset_in_bytes(); 805 const int value_offset = java_lang_String::value_offset_in_bytes();
797 const int count_offset = java_lang_String::count_offset_in_bytes(); 806 const int count_offset = java_lang_String::count_offset_in_bytes();
798 const int offset_offset = java_lang_String::offset_offset_in_bytes(); 807 const int offset_offset = java_lang_String::offset_offset_in_bytes();
799 808
800 _sp += 2; 809 _sp += 2;
825 memory(string_type->add_offset(count_offset)), 834 memory(string_type->add_offset(count_offset)),
826 memory(string_type->add_offset(offset_offset)), 835 memory(string_type->add_offset(offset_offset)),
827 receiver, 836 receiver,
828 argument)); 837 argument));
829 push(compare); 838 push(compare);
839 return true;
840 }
841
842 //------------------------------inline_string_equals------------------------
843 bool LibraryCallKit::inline_string_equals() {
844
845 if (!Matcher::has_match_rule(Op_StrEquals)) return false;
846
847 const int value_offset = java_lang_String::value_offset_in_bytes();
848 const int count_offset = java_lang_String::count_offset_in_bytes();
849 const int offset_offset = java_lang_String::offset_offset_in_bytes();
850
851 _sp += 2;
852 Node* argument = pop(); // pop non-receiver first: it was pushed second
853 Node* receiver = pop();
854
855 // Null check on self without removing any arguments. The argument
856 // null check technically happens in the wrong place, which can lead to
857 // invalid stack traces when string compare is inlined into a method
858 // which handles NullPointerExceptions.
859 _sp += 2;
860 receiver = do_null_check(receiver, T_OBJECT);
861 //should not do null check for argument for String.equals(), because spec
862 //allows to specify NULL as argument.
863 _sp -= 2;
864
865 if (stopped()) {
866 return true;
867 }
868
869 // get String klass for instanceOf
870 ciInstanceKlass* klass = env()->String_klass();
871
872 // two paths (plus control) merge
873 RegionNode* region = new (C, 3) RegionNode(3);
874 Node* phi = new (C, 3) PhiNode(region, TypeInt::BOOL);
875
876 Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
877 Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
878 Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
879
880 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
881
882 Node* if_true = _gvn.transform(new (C, 1) IfTrueNode(iff));
883 set_control(if_true);
884
885 const TypeInstPtr* string_type =
886 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
887
888 // instanceOf == true
889 Node* equals =
890 _gvn.transform(new (C, 7) StrEqualsNode(
891 control(),
892 memory(TypeAryPtr::CHARS),
893 memory(string_type->add_offset(value_offset)),
894 memory(string_type->add_offset(count_offset)),
895 memory(string_type->add_offset(offset_offset)),
896 receiver,
897 argument));
898
899 phi->init_req(1, _gvn.transform(equals));
900 region->init_req(1, if_true);
901
902 //instanceOf == false, fallthrough
903 Node* if_false = _gvn.transform(new (C, 1) IfFalseNode(iff));
904 set_control(if_false);
905
906 phi->init_req(2, _gvn.transform(intcon(0)));
907 region->init_req(2, if_false);
908
909 // post merge
910 set_control(_gvn.transform(region));
911 record_for_igvn(region);
912
913 push(_gvn.transform(phi));
914
830 return true; 915 return true;
831 } 916 }
832 917
833 //------------------------------inline_array_equals---------------------------- 918 //------------------------------inline_array_equals----------------------------
834 bool LibraryCallKit::inline_array_equals() { 919 bool LibraryCallKit::inline_array_equals() {
992 #undef __ 1077 #undef __
993 C->set_has_loops(true); 1078 C->set_has_loops(true);
994 return result; 1079 return result;
995 } 1080 }
996 1081
997
998 //------------------------------inline_string_indexOf------------------------ 1082 //------------------------------inline_string_indexOf------------------------
999 bool LibraryCallKit::inline_string_indexOf() { 1083 bool LibraryCallKit::inline_string_indexOf() {
1084
1085 const int value_offset = java_lang_String::value_offset_in_bytes();
1086 const int count_offset = java_lang_String::count_offset_in_bytes();
1087 const int offset_offset = java_lang_String::offset_offset_in_bytes();
1000 1088
1001 _sp += 2; 1089 _sp += 2;
1002 Node *argument = pop(); // pop non-receiver first: it was pushed second 1090 Node *argument = pop(); // pop non-receiver first: it was pushed second
1003 Node *receiver = pop(); 1091 Node *receiver = pop();
1004 1092
1005 // don't intrinsify if argument isn't a constant string. 1093 Node* result;
1006 if (!argument->is_Con()) { 1094 if (Matcher::has_match_rule(Op_StrIndexOf) &&
1007 return false; 1095 UseSSE42Intrinsics) {
1008 } 1096 // Generate SSE4.2 version of indexOf
1009 const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr(); 1097 // We currently only have match rules that use SSE4.2
1010 if (str_type == NULL) { 1098
1011 return false; 1099 // Null check on self without removing any arguments. The argument
1012 } 1100 // null check technically happens in the wrong place, which can lead to
1013 ciInstanceKlass* klass = env()->String_klass(); 1101 // invalid stack traces when string compare is inlined into a method
1014 ciObject* str_const = str_type->const_oop(); 1102 // which handles NullPointerExceptions.
1015 if (str_const == NULL || str_const->klass() != klass) { 1103 _sp += 2;
1016 return false; 1104 receiver = do_null_check(receiver, T_OBJECT);
1017 } 1105 argument = do_null_check(argument, T_OBJECT);
1018 ciInstance* str = str_const->as_instance(); 1106 _sp -= 2;
1019 assert(str != NULL, "must be instance"); 1107
1020 1108 if (stopped()) {
1021 const int value_offset = java_lang_String::value_offset_in_bytes(); 1109 return true;
1022 const int count_offset = java_lang_String::count_offset_in_bytes(); 1110 }
1023 const int offset_offset = java_lang_String::offset_offset_in_bytes(); 1111
1024 1112 ciInstanceKlass* klass = env()->String_klass();
1025 ciObject* v = str->field_value_by_offset(value_offset).as_object(); 1113 const TypeInstPtr* string_type =
1026 int o = str->field_value_by_offset(offset_offset).as_int(); 1114 TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
1027 int c = str->field_value_by_offset(count_offset).as_int(); 1115
1028 ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array 1116 result =
1029 1117 _gvn.transform(new (C, 7)
1030 // constant strings have no offset and count == length which 1118 StrIndexOfNode(control(),
1031 // simplifies the resulting code somewhat so lets optimize for that. 1119 memory(TypeAryPtr::CHARS),
1032 if (o != 0 || c != pat->length()) { 1120 memory(string_type->add_offset(value_offset)),
1033 return false; 1121 memory(string_type->add_offset(count_offset)),
1034 } 1122 memory(string_type->add_offset(offset_offset)),
1035 1123 receiver,
1036 // Null check on self without removing any arguments. The argument 1124 argument));
1037 // null check technically happens in the wrong place, which can lead to 1125 } else { //Use LibraryCallKit::string_indexOf
1038 // invalid stack traces when string compare is inlined into a method 1126 // don't intrinsify is argument isn't a constant string.
1039 // which handles NullPointerExceptions. 1127 if (!argument->is_Con()) {
1040 _sp += 2; 1128 return false;
1041 receiver = do_null_check(receiver, T_OBJECT); 1129 }
1042 // No null check on the argument is needed since it's a constant String oop. 1130 const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1043 _sp -= 2; 1131 if (str_type == NULL) {
1044 if (stopped()) { 1132 return false;
1045 return true; 1133 }
1046 } 1134 ciInstanceKlass* klass = env()->String_klass();
1047 1135 ciObject* str_const = str_type->const_oop();
1048 // The null string as a pattern always returns 0 (match at beginning of string) 1136 if (str_const == NULL || str_const->klass() != klass) {
1049 if (c == 0) { 1137 return false;
1050 push(intcon(0)); 1138 }
1051 return true; 1139 ciInstance* str = str_const->as_instance();
1052 } 1140 assert(str != NULL, "must be instance");
1053 1141
1054 jchar lastChar = pat->char_at(o + (c - 1)); 1142 ciObject* v = str->field_value_by_offset(value_offset).as_object();
1055 int cache = 0; 1143 int o = str->field_value_by_offset(offset_offset).as_int();
1056 int i; 1144 int c = str->field_value_by_offset(count_offset).as_int();
1057 for (i = 0; i < c - 1; i++) { 1145 ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
1058 assert(i < pat->length(), "out of range"); 1146
1059 cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1))); 1147 // constant strings have no offset and count == length which
1060 } 1148 // simplifies the resulting code somewhat so lets optimize for that.
1061 1149 if (o != 0 || c != pat->length()) {
1062 int md2 = c; 1150 return false;
1063 for (i = 0; i < c - 1; i++) { 1151 }
1064 assert(i < pat->length(), "out of range"); 1152
1065 if (pat->char_at(o + i) == lastChar) { 1153 // Null check on self without removing any arguments. The argument
1066 md2 = (c - 1) - i; 1154 // null check technically happens in the wrong place, which can lead to
1067 } 1155 // invalid stack traces when string compare is inlined into a method
1068 } 1156 // which handles NullPointerExceptions.
1069 1157 _sp += 2;
1070 Node* result = string_indexOf(receiver, pat, o, cache, md2); 1158 receiver = do_null_check(receiver, T_OBJECT);
1159 // No null check on the argument is needed since it's a constant String oop.
1160 _sp -= 2;
1161 if (stopped()) {
1162 return true;
1163 }
1164
1165 // The null string as a pattern always returns 0 (match at beginning of string)
1166 if (c == 0) {
1167 push(intcon(0));
1168 return true;
1169 }
1170
1171 // Generate default indexOf
1172 jchar lastChar = pat->char_at(o + (c - 1));
1173 int cache = 0;
1174 int i;
1175 for (i = 0; i < c - 1; i++) {
1176 assert(i < pat->length(), "out of range");
1177 cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
1178 }
1179
1180 int md2 = c;
1181 for (i = 0; i < c - 1; i++) {
1182 assert(i < pat->length(), "out of range");
1183 if (pat->char_at(o + i) == lastChar) {
1184 md2 = (c - 1) - i;
1185 }
1186 }
1187
1188 result = string_indexOf(receiver, pat, o, cache, md2);
1189 }
1190
1071 push(result); 1191 push(result);
1072 return true; 1192 return true;
1073 } 1193 }
1074 1194
1075 //--------------------------pop_math_arg-------------------------------- 1195 //--------------------------pop_math_arg--------------------------------