< prev index next >

src/share/vm/opto/library_call.cpp

Print this page
rev 9944 : 8145336: PPC64: fix string intrinsics after CompactStrings change


 954 }
 955 
 956 
 957 //------------------------------make_string_method_node------------------------
 958 // Helper method for String intrinsic functions. This version is called with
 959 // str1 and str2 pointing to byte[] nodes containing Latin1 or UTF16 encoded
 960 // characters (depending on 'is_byte'). cnt1 and cnt2 are pointing to Int nodes
 961 // containing the lengths of str1 and str2.
 962 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae) {
 963   Node* result = NULL;
 964   switch (opcode) {
 965   case Op_StrIndexOf:
 966     result = new StrIndexOfNode(control(), memory(TypeAryPtr::BYTES),
 967                                 str1_start, cnt1, str2_start, cnt2, ae);
 968     break;
 969   case Op_StrComp:
 970     result = new StrCompNode(control(), memory(TypeAryPtr::BYTES),
 971                              str1_start, cnt1, str2_start, cnt2, ae);
 972     break;
 973   case Op_StrEquals:


 974     result = new StrEqualsNode(control(), memory(TypeAryPtr::BYTES),
 975                                str1_start, str2_start, cnt1, ae);
 976     break;
 977   default:
 978     ShouldNotReachHere();
 979     return NULL;
 980   }
 981 
 982   // All these intrinsics have checks.
 983   C->set_has_split_ifs(true); // Has chance for split-if optimization
 984 
 985   return _gvn.transform(result);
 986 }
 987 
 988 //------------------------------inline_string_compareTo------------------------
 989 bool LibraryCallKit::inline_string_compareTo(StrIntrinsicNode::ArgEnc ae) {
 990   Node* arg1 = argument(0);
 991   Node* arg2 = argument(1);
 992 
 993   // Get start addr and length of first argument
 994   Node* arg1_start  = array_element_address(arg1, intcon(0), T_BYTE);
 995   Node* arg1_cnt    = load_array_length(arg1);


1114     PreserveJVMState pjvms(this);
1115     set_control(_gvn.transform(new IfFalseNode(rc)));
1116     uncommon_trap(Deoptimization::Reason_range_check,
1117                   Deoptimization::Action_make_not_entrant);
1118   }
1119 
1120   if (stopped()) {
1121     return false;
1122   }
1123 
1124   Node* result = new CastIINode(index, TypeInt::make(0, _gvn.type(length)->is_int()->_hi, Type::WidenMax));
1125   result->set_req(0, control());
1126   result = _gvn.transform(result);
1127   set_result(result);
1128   replace_in_map(index, result);
1129   return true;
1130 }
1131 
1132 //------------------------------inline_string_indexOf------------------------
1133 bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
1134   if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
1135     return false;
1136   }
1137   Node* src = argument(0);
1138   Node* tgt = argument(1);
1139 
1140   // Make the merge point
1141   RegionNode* result_rgn = new RegionNode(4);
1142   Node*       result_phi = new PhiNode(result_rgn, TypeInt::INT);
1143 
1144   // Get start addr and length of source string
1145   Node* src_start = array_element_address(src, intcon(0), T_BYTE);
1146   Node* src_count = load_array_length(src);
1147 
1148   // Get start addr and length of substring
1149   Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
1150   Node* tgt_count = load_array_length(tgt);
1151 
1152   if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
1153     // Divide src size by 2 if String is UTF16 encoded
1154     src_count = _gvn.transform(new RShiftINode(src_count, intcon(1)));


1158     tgt_count = _gvn.transform(new RShiftINode(tgt_count, intcon(1)));
1159   }
1160 
1161   Node* result = make_indexOf_node(src_start, src_count, tgt_start, tgt_count, result_rgn, result_phi, ae);
1162   if (result != NULL) {
1163     result_phi->init_req(3, result);
1164     result_rgn->init_req(3, control());
1165   }
1166   set_control(_gvn.transform(result_rgn));
1167   record_for_igvn(result_rgn);
1168   set_result(_gvn.transform(result_phi));
1169 
1170   return true;
1171 }
1172 
1173 //-----------------------------inline_string_indexOf-----------------------
1174 bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
1175   if (too_many_traps(Deoptimization::Reason_intrinsic)) {
1176     return false;
1177   }
1178   if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
1179     return false;
1180   }
1181   assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
1182   Node* src         = argument(0); // byte[]
1183   Node* src_count   = argument(1); // char count
1184   Node* tgt         = argument(2); // byte[]
1185   Node* tgt_count   = argument(3); // char count
1186   Node* from_index  = argument(4); // char index
1187 
1188   // Multiply byte array index by 2 if String is UTF16 encoded
1189   Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform(new LShiftINode(from_index, intcon(1)));
1190   src_count = _gvn.transform(new SubINode(src_count, from_index));
1191   Node* src_start = array_element_address(src, src_offset, T_BYTE);
1192   Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
1193 
1194   // Range checks
1195   generate_string_range_check(src, src_offset, src_count, ae != StrIntrinsicNode::LL);
1196   generate_string_range_check(tgt, intcon(0), tgt_count, ae == StrIntrinsicNode::UU);
1197   if (stopped()) {
1198     return true;


1243     // Check for substr count == 0
1244     cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
1245     bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
1246     Node* if_zero = generate_slow_guard(bol, NULL);
1247     if (if_zero != NULL) {
1248       phi->init_req(2, intcon(0));
1249       region->init_req(2, if_zero);
1250     }
1251   }
1252   if (!stopped()) {
1253     return make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
1254   }
1255   return NULL;
1256 }
1257 
1258 //-----------------------------inline_string_indexOfChar-----------------------
1259 bool LibraryCallKit::inline_string_indexOfChar() {
1260   if (too_many_traps(Deoptimization::Reason_intrinsic)) {
1261     return false;
1262   }
1263   if (!Matcher::has_match_rule(Op_StrIndexOfChar) || !(UseSSE > 4)) {
1264     return false;
1265   }
1266   assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments");
1267   Node* src         = argument(0); // byte[]
1268   Node* tgt         = argument(1); // tgt is int ch
1269   Node* from_index  = argument(2);
1270   Node* max         = argument(3);
1271 
1272   Node* src_offset = _gvn.transform(new LShiftINode(from_index, intcon(1)));
1273   Node* src_start = array_element_address(src, src_offset, T_BYTE);
1274   Node* src_count = _gvn.transform(new SubINode(max, from_index));
1275 
1276   // Range checks
1277   generate_string_range_check(src, src_offset, src_count, true);
1278   if (stopped()) {
1279     return true;
1280   }
1281 
1282   RegionNode* region = new RegionNode(3);
1283   Node* phi = new PhiNode(region, TypeInt::INT);




 954 }
 955 
 956 
 957 //------------------------------make_string_method_node------------------------
 958 // Helper method for String intrinsic functions. This version is called with
 959 // str1 and str2 pointing to byte[] nodes containing Latin1 or UTF16 encoded
 960 // characters (depending on 'is_byte'). cnt1 and cnt2 are pointing to Int nodes
 961 // containing the lengths of str1 and str2.
 962 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae) {
 963   Node* result = NULL;
 964   switch (opcode) {
 965   case Op_StrIndexOf:
 966     result = new StrIndexOfNode(control(), memory(TypeAryPtr::BYTES),
 967                                 str1_start, cnt1, str2_start, cnt2, ae);
 968     break;
 969   case Op_StrComp:
 970     result = new StrCompNode(control(), memory(TypeAryPtr::BYTES),
 971                              str1_start, cnt1, str2_start, cnt2, ae);
 972     break;
 973   case Op_StrEquals:
 974     // We already know that cnt1 == cnt2 here (checked in 'inline_string_equals').
 975     // Use the constant length if there is one because optimzed match rule may exist.
 976     result = new StrEqualsNode(control(), memory(TypeAryPtr::BYTES),
 977                                str1_start, str2_start, cnt2->is_Con() ? cnt2 : cnt1, ae);
 978     break;
 979   default:
 980     ShouldNotReachHere();
 981     return NULL;
 982   }
 983 
 984   // All these intrinsics have checks.
 985   C->set_has_split_ifs(true); // Has chance for split-if optimization
 986 
 987   return _gvn.transform(result);
 988 }
 989 
 990 //------------------------------inline_string_compareTo------------------------
 991 bool LibraryCallKit::inline_string_compareTo(StrIntrinsicNode::ArgEnc ae) {
 992   Node* arg1 = argument(0);
 993   Node* arg2 = argument(1);
 994 
 995   // Get start addr and length of first argument
 996   Node* arg1_start  = array_element_address(arg1, intcon(0), T_BYTE);
 997   Node* arg1_cnt    = load_array_length(arg1);


1116     PreserveJVMState pjvms(this);
1117     set_control(_gvn.transform(new IfFalseNode(rc)));
1118     uncommon_trap(Deoptimization::Reason_range_check,
1119                   Deoptimization::Action_make_not_entrant);
1120   }
1121 
1122   if (stopped()) {
1123     return false;
1124   }
1125 
1126   Node* result = new CastIINode(index, TypeInt::make(0, _gvn.type(length)->is_int()->_hi, Type::WidenMax));
1127   result->set_req(0, control());
1128   result = _gvn.transform(result);
1129   set_result(result);
1130   replace_in_map(index, result);
1131   return true;
1132 }
1133 
1134 //------------------------------inline_string_indexOf------------------------
1135 bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
1136   if (!Matcher::match_rule_supported(Op_StrIndexOf)) {
1137     return false;
1138   }
1139   Node* src = argument(0);
1140   Node* tgt = argument(1);
1141 
1142   // Make the merge point
1143   RegionNode* result_rgn = new RegionNode(4);
1144   Node*       result_phi = new PhiNode(result_rgn, TypeInt::INT);
1145 
1146   // Get start addr and length of source string
1147   Node* src_start = array_element_address(src, intcon(0), T_BYTE);
1148   Node* src_count = load_array_length(src);
1149 
1150   // Get start addr and length of substring
1151   Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
1152   Node* tgt_count = load_array_length(tgt);
1153 
1154   if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
1155     // Divide src size by 2 if String is UTF16 encoded
1156     src_count = _gvn.transform(new RShiftINode(src_count, intcon(1)));


1160     tgt_count = _gvn.transform(new RShiftINode(tgt_count, intcon(1)));
1161   }
1162 
1163   Node* result = make_indexOf_node(src_start, src_count, tgt_start, tgt_count, result_rgn, result_phi, ae);
1164   if (result != NULL) {
1165     result_phi->init_req(3, result);
1166     result_rgn->init_req(3, control());
1167   }
1168   set_control(_gvn.transform(result_rgn));
1169   record_for_igvn(result_rgn);
1170   set_result(_gvn.transform(result_phi));
1171 
1172   return true;
1173 }
1174 
1175 //-----------------------------inline_string_indexOf-----------------------
1176 bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
1177   if (too_many_traps(Deoptimization::Reason_intrinsic)) {
1178     return false;
1179   }
1180   if (!Matcher::match_rule_supported(Op_StrIndexOf)) {
1181     return false;
1182   }
1183   assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
1184   Node* src         = argument(0); // byte[]
1185   Node* src_count   = argument(1); // char count
1186   Node* tgt         = argument(2); // byte[]
1187   Node* tgt_count   = argument(3); // char count
1188   Node* from_index  = argument(4); // char index
1189 
1190   // Multiply byte array index by 2 if String is UTF16 encoded
1191   Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform(new LShiftINode(from_index, intcon(1)));
1192   src_count = _gvn.transform(new SubINode(src_count, from_index));
1193   Node* src_start = array_element_address(src, src_offset, T_BYTE);
1194   Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
1195 
1196   // Range checks
1197   generate_string_range_check(src, src_offset, src_count, ae != StrIntrinsicNode::LL);
1198   generate_string_range_check(tgt, intcon(0), tgt_count, ae == StrIntrinsicNode::UU);
1199   if (stopped()) {
1200     return true;


1245     // Check for substr count == 0
1246     cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
1247     bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
1248     Node* if_zero = generate_slow_guard(bol, NULL);
1249     if (if_zero != NULL) {
1250       phi->init_req(2, intcon(0));
1251       region->init_req(2, if_zero);
1252     }
1253   }
1254   if (!stopped()) {
1255     return make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
1256   }
1257   return NULL;
1258 }
1259 
1260 //-----------------------------inline_string_indexOfChar-----------------------
1261 bool LibraryCallKit::inline_string_indexOfChar() {
1262   if (too_many_traps(Deoptimization::Reason_intrinsic)) {
1263     return false;
1264   }
1265   if (!Matcher::match_rule_supported(Op_StrIndexOfChar)) {
1266     return false;
1267   }
1268   assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments");
1269   Node* src         = argument(0); // byte[]
1270   Node* tgt         = argument(1); // tgt is int ch
1271   Node* from_index  = argument(2);
1272   Node* max         = argument(3);
1273 
1274   Node* src_offset = _gvn.transform(new LShiftINode(from_index, intcon(1)));
1275   Node* src_start = array_element_address(src, src_offset, T_BYTE);
1276   Node* src_count = _gvn.transform(new SubINode(max, from_index));
1277 
1278   // Range checks
1279   generate_string_range_check(src, src_offset, src_count, true);
1280   if (stopped()) {
1281     return true;
1282   }
1283 
1284   RegionNode* region = new RegionNode(3);
1285   Node* phi = new PhiNode(region, TypeInt::INT);


< prev index next >