| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 BranchOrBacktrack(not_equal, on_not_at_start); | 202 BranchOrBacktrack(not_equal, on_not_at_start); |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { | 206 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { |
| 207 __ cmp(current_character(), limit); | 207 __ cmp(current_character(), limit); |
| 208 BranchOrBacktrack(less, on_less); | 208 BranchOrBacktrack(less, on_less); |
| 209 } | 209 } |
| 210 | 210 |
| 211 | 211 |
| 212 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str, | |
| 213 int cp_offset, | |
| 214 Label* on_failure, | |
| 215 bool check_end_of_string) { | |
| 216 #ifdef DEBUG | |
| 217 // If input is ASCII, don't even bother calling here if the string to | |
| 218 // match contains a non-ASCII character. | |
| 219 if (mode_ == ASCII) { | |
| 220 ASSERT(String::IsOneByte(str.start(), str.length())); | |
| 221 } | |
| 222 #endif | |
| 223 int byte_length = str.length() * char_size(); | |
| 224 int byte_offset = cp_offset * char_size(); | |
| 225 if (check_end_of_string) { | |
| 226 // Check that there are at least str.length() characters left in the input. | |
| 227 __ cmp(edi, Immediate(-(byte_offset + byte_length))); | |
| 228 BranchOrBacktrack(greater, on_failure); | |
| 229 } | |
| 230 | |
| 231 if (on_failure == NULL) { | |
| 232 // Instead of inlining a backtrack, (re)use the global backtrack target. | |
| 233 on_failure = &backtrack_label_; | |
| 234 } | |
| 235 | |
| 236 // Do one character test first to minimize loading for the case that | |
| 237 // we don't match at all (loading more than one character introduces that | |
| 238 // chance of reading unaligned and reading across cache boundaries). | |
| 239 // If the first character matches, expect a larger chance of matching the | |
| 240 // string, and start loading more characters at a time. | |
| 241 if (mode_ == ASCII) { | |
| 242 __ cmpb(Operand(esi, edi, times_1, byte_offset), | |
| 243 static_cast<int8_t>(str[0])); | |
| 244 } else { | |
| 245 // Don't use 16-bit immediate. The size changing prefix throws off | |
| 246 // pre-decoding. | |
| 247 __ movzx_w(eax, | |
| 248 Operand(esi, edi, times_1, byte_offset)); | |
| 249 __ cmp(eax, static_cast<int32_t>(str[0])); | |
| 250 } | |
| 251 BranchOrBacktrack(not_equal, on_failure); | |
| 252 | |
| 253 __ lea(ebx, Operand(esi, edi, times_1, 0)); | |
| 254 for (int i = 1, n = str.length(); i < n;) { | |
| 255 if (mode_ == ASCII) { | |
| 256 if (i <= n - 4) { | |
| 257 int combined_chars = | |
| 258 (static_cast<uint32_t>(str[i + 0]) << 0) | | |
| 259 (static_cast<uint32_t>(str[i + 1]) << 8) | | |
| 260 (static_cast<uint32_t>(str[i + 2]) << 16) | | |
| 261 (static_cast<uint32_t>(str[i + 3]) << 24); | |
| 262 __ cmp(Operand(ebx, byte_offset + i), Immediate(combined_chars)); | |
| 263 i += 4; | |
| 264 } else { | |
| 265 __ cmpb(Operand(ebx, byte_offset + i), | |
| 266 static_cast<int8_t>(str[i])); | |
| 267 i += 1; | |
| 268 } | |
| 269 } else { | |
| 270 ASSERT(mode_ == UC16); | |
| 271 if (i <= n - 2) { | |
| 272 __ cmp(Operand(ebx, byte_offset + i * sizeof(uc16)), | |
| 273 Immediate(*reinterpret_cast<const int*>(&str[i]))); | |
| 274 i += 2; | |
| 275 } else { | |
| 276 // Avoid a 16-bit immediate operation. It uses the length-changing | |
| 277 // 0x66 prefix which causes pre-decoder misprediction and pipeline | |
| 278 // stalls. See | |
| 279 // "Intel(R) 64 and IA-32 Architectures Optimization Reference Manual" | |
| 280 // (248966.pdf) section 3.4.2.3 "Length-Changing Prefixes (LCP)" | |
| 281 __ movzx_w(eax, | |
| 282 Operand(ebx, byte_offset + i * sizeof(uc16))); | |
| 283 __ cmp(eax, static_cast<int32_t>(str[i])); | |
| 284 i += 1; | |
| 285 } | |
| 286 } | |
| 287 BranchOrBacktrack(not_equal, on_failure); | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 | |
| 292 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { | 212 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { |
| 293 Label fallthrough; | 213 Label fallthrough; |
| 294 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); | 214 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); |
| 295 __ j(not_equal, &fallthrough); | 215 __ j(not_equal, &fallthrough); |
| 296 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. | 216 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. |
| 297 BranchOrBacktrack(no_condition, on_equal); | 217 BranchOrBacktrack(no_condition, on_equal); |
| 298 __ bind(&fallthrough); | 218 __ bind(&fallthrough); |
| 299 } | 219 } |
| 300 | 220 |
| 301 | 221 |
| (...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 } | 1321 } |
| 1402 | 1322 |
| 1403 | 1323 |
| 1404 #undef __ | 1324 #undef __ |
| 1405 | 1325 |
| 1406 #endif // V8_INTERPRETED_REGEXP | 1326 #endif // V8_INTERPRETED_REGEXP |
| 1407 | 1327 |
| 1408 }} // namespace v8::internal | 1328 }} // namespace v8::internal |
| 1409 | 1329 |
| 1410 #endif // V8_TARGET_ARCH_IA32 | 1330 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |