5 #ifndef V8_STRING_SEARCH_H_
6 #define V8_STRING_SEARCH_H_
53 template <
typename PatternChar,
typename SubjectChar>
60 if (
sizeof(PatternChar) >
sizeof(SubjectChar)) {
68 if (pattern_length == 1) {
83 if (
sizeof(PatternChar) == 1) {
87 DCHECK(
sizeof(PatternChar) == 2);
139 SubjectChar char_code) {
140 if (
sizeof(SubjectChar) == 1) {
141 return bad_char_occurrence[
static_cast<int>(char_code)];
143 if (
sizeof(PatternChar) == 1) {
147 return bad_char_occurrence[
static_cast<unsigned int>(char_code)];
151 return bad_char_occurrence[equiv_class];
162 return isolate_->bad_char_shift_table();
194 template <
typename PatternChar,
typename SubjectChar>
200 PatternChar pattern_first_char = search->
pattern_[0];
202 if (
sizeof(SubjectChar) == 1 &&
sizeof(PatternChar) == 1) {
203 const SubjectChar* pos =
reinterpret_cast<const SubjectChar*
>(
204 memchr(subject.
start() +
i,
207 if (pos ==
NULL)
return -1;
208 return static_cast<int>(pos - subject.
start());
210 if (
sizeof(PatternChar) >
sizeof(SubjectChar)) {
211 if (exceedsOneByte(pattern_first_char)) {
215 SubjectChar search_char =
static_cast<SubjectChar
>(pattern_first_char);
218 if (subject[
i++] == search_char)
return i - 1;
229 template <
typename PatternChar,
typename SubjectChar>
231 const SubjectChar* subject,
236 if (pattern[pos] != subject[pos]) {
240 }
while (pos < length);
246 template <
typename PatternChar,
typename SubjectChar>
253 int pattern_length = pattern.
length();
254 PatternChar pattern_first_char = pattern[0];
256 int n = subject.
length() - pattern_length;
258 if (
sizeof(SubjectChar) == 1 &&
sizeof(PatternChar) == 1) {
259 const SubjectChar* pos =
reinterpret_cast<const SubjectChar*
>(
260 memchr(subject.
start() +
i,
263 if (pos ==
NULL)
return -1;
264 i =
static_cast<int>(pos - subject.
start()) + 1;
266 if (subject[
i++] != pattern_first_char)
continue;
272 pattern_length - 1)) {
283 template <
typename PatternChar,
typename SubjectChar>
289 int subject_length = subject.
length();
290 int pattern_length = pattern.
length();
292 int start = search->
start_;
297 PatternChar last_char = pattern[pattern_length - 1];
298 int index = start_index;
300 while (index <= subject_length - pattern_length) {
301 int j = pattern_length - 1;
303 while (last_char != (c = subject[index + j])) {
305 j - CharOccurrence(bad_char_occurence, c);
307 if (index > subject_length - pattern_length) {
311 while (j >= 0 && pattern[j] == (c = subject[index + j])) j--;
314 }
else if (j < start) {
317 index += pattern_length - 1
318 - CharOccurrence(bad_char_occurence,
319 static_cast<SubjectChar
>(last_char));
321 int gs_shift = good_suffix_shift[j + 1];
323 CharOccurrence(bad_char_occurence, c);
324 int shift = j - bc_occ;
325 if (gs_shift >
shift) {
336 template <
typename PatternChar,
typename SubjectChar>
338 int pattern_length = pattern_.length();
339 const PatternChar* pattern = pattern_.start();
343 int length = pattern_length - start;
347 int* shift_table = good_suffix_shift_table();
348 int* suffix_table = this->suffix_table();
351 for (
int i = start;
i < pattern_length;
i++) {
352 shift_table[
i] = length;
354 shift_table[pattern_length] = 1;
355 suffix_table[pattern_length] = pattern_length + 1;
357 if (pattern_length <= start) {
362 PatternChar last_char = pattern[pattern_length - 1];
363 int suffix = pattern_length + 1;
365 int i = pattern_length;
367 PatternChar c = pattern[
i - 1];
368 while (suffix <= pattern_length && c != pattern[suffix - 1]) {
369 if (shift_table[suffix] == length) {
370 shift_table[suffix] = suffix -
i;
372 suffix = suffix_table[suffix];
374 suffix_table[--
i] = --suffix;
375 if (suffix == pattern_length) {
377 while ((
i > start) && (pattern[
i - 1] != last_char)) {
378 if (shift_table[pattern_length] == length) {
379 shift_table[pattern_length] = pattern_length -
i;
381 suffix_table[--
i] = pattern_length;
384 suffix_table[--
i] = --suffix;
390 if (suffix < pattern_length) {
391 for (
int i = start;
i <= pattern_length;
i++) {
392 if (shift_table[
i] == length) {
393 shift_table[
i] = suffix - start;
396 suffix = suffix_table[suffix];
406 template <
typename PatternChar,
typename SubjectChar>
412 int subject_length = subject.
length();
413 int pattern_length = pattern.
length();
415 int badness = -pattern_length;
418 PatternChar last_char = pattern[pattern_length - 1];
419 int last_char_shift = pattern_length - 1 -
420 CharOccurrence(char_occurrences,
static_cast<SubjectChar
>(last_char));
422 int index = start_index;
423 while (index <= subject_length - pattern_length) {
424 int j = pattern_length - 1;
426 while (last_char != (subject_char = subject[index + j])) {
427 int bc_occ = CharOccurrence(char_occurrences, subject_char);
428 int shift = j - bc_occ;
430 badness += 1 -
shift;
431 if (index > subject_length - pattern_length) {
436 while (j >= 0 && pattern[j] == (subject[index + j])) j--;
440 index += last_char_shift;
445 badness += (pattern_length - j) - last_char_shift;
449 return BoyerMooreSearch(search, subject, index);
457 template <
typename PatternChar,
typename SubjectChar>
459 int pattern_length = pattern_.length();
461 int* bad_char_occurrence = bad_char_table();
468 int table_size = AlphabetSize();
470 memset(bad_char_occurrence,
472 table_size *
sizeof(*bad_char_occurrence));
474 for (
int i = 0;
i < table_size;
i++) {
475 bad_char_occurrence[
i] = start - 1;
478 for (
int i = start;
i < pattern_length - 1;
i++) {
479 PatternChar c = pattern_[
i];
480 int bucket = (
sizeof(PatternChar) == 1) ? c : c % AlphabetSize();
481 bad_char_occurrence[bucket] =
i;
491 template <
typename PatternChar,
typename SubjectChar>
497 int pattern_length = pattern.
length();
501 int badness = -10 - (pattern_length << 2);
505 PatternChar pattern_first_char = pattern[0];
506 for (
int i = index, n = subject.
length() - pattern_length;
i <= n;
i++) {
509 if (
sizeof(SubjectChar) == 1 &&
sizeof(PatternChar) == 1) {
510 const SubjectChar* pos =
reinterpret_cast<const SubjectChar*
>(
511 memchr(subject.
start() +
i,
517 i =
static_cast<int>(pos - subject.
start());
519 if (subject[
i] != pattern_first_char)
continue;
523 if (pattern[j] != subject[
i + j]) {
527 }
while (j < pattern_length);
528 if (j == pattern_length) {
534 search->
strategy_ = &BoyerMooreHorspoolSearch;
535 return BoyerMooreHorspoolSearch(search, subject,
i);
546 template <
typename SubjectChar,
typename PatternChar>
552 return search.
Search(subject, start_index);
static const int kUC16AlphabetSize
static const int kBMMaxShift
static const int kLatin1AlphabetSize
static const int kUC16AlphabetSize
static const int kBMMinPatternLength
static const int kBMMaxShift
static bool IsOneByteString(Vector< const uint8_t > string)
static bool IsOneByteString(Vector< const uc16 > string)
static int BoyerMooreHorspoolSearch(StringSearch< PatternChar, SubjectChar > *search, Vector< const SubjectChar > subject, int start_index)
static int LinearSearch(StringSearch< PatternChar, SubjectChar > *search, Vector< const SubjectChar > subject, int start_index)
int * good_suffix_shift_table()
void PopulateBoyerMooreTable()
static int AlphabetSize()
static bool exceedsOneByte(uint16_t c)
static int BoyerMooreSearch(StringSearch< PatternChar, SubjectChar > *search, Vector< const SubjectChar > subject, int start_index)
static int FailSearch(StringSearch< PatternChar, SubjectChar > *, Vector< const SubjectChar >, int)
static bool exceedsOneByte(uint8_t c)
static int InitialSearch(StringSearch< PatternChar, SubjectChar > *search, Vector< const SubjectChar > subject, int start_index)
void PopulateBoyerMooreHorspoolTable()
static int SingleCharSearch(StringSearch< PatternChar, SubjectChar > *search, Vector< const SubjectChar > subject, int start_index)
StringSearch(Isolate *isolate, Vector< const PatternChar > pattern)
int Search(Vector< const SubjectChar > subject, int index)
static int CharOccurrence(int *bad_char_occurrence, SubjectChar char_code)
int(* SearchFunction)(StringSearch< PatternChar, SubjectChar > *, Vector< const SubjectChar >, int)
Vector< const PatternChar > pattern_
static const uint32_t kMaxOneByteCharCodeU
static bool IsOneByte(const uc16 *chars, int length)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
enable harmony numeric enable harmony object literal extensions Optimize object Array shift
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
int SearchString(Isolate *isolate, Vector< const SubjectChar > subject, Vector< const PatternChar > pattern, int start_index)
bool CharCompare(const PatternChar *pattern, const SubjectChar *subject, int length)
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
Debugger support for the V8 JavaScript engine.