OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/regexp/jsregexp.h" | 5 #include "src/regexp/jsregexp.h" |
6 | 6 |
7 #include "src/ast.h" | 7 #include "src/ast.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 6392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6403 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && | 6403 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && |
6404 heap->isolate()->memory_allocator()->SizeExecutable() > | 6404 heap->isolate()->memory_allocator()->SizeExecutable() > |
6405 RegExpImpl::kRegExpExecutableMemoryLimit) { | 6405 RegExpImpl::kRegExpExecutableMemoryLimit) { |
6406 too_much = true; | 6406 too_much = true; |
6407 } | 6407 } |
6408 return too_much; | 6408 return too_much; |
6409 } | 6409 } |
6410 | 6410 |
6411 | 6411 |
6412 Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, | 6412 Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, |
6413 Object* key_pattern, ResultsCacheType type) { | 6413 Object* key_pattern, |
| 6414 FixedArray** last_match_cache, |
| 6415 ResultsCacheType type) { |
6414 FixedArray* cache; | 6416 FixedArray* cache; |
6415 if (!key_string->IsInternalizedString()) return Smi::FromInt(0); | 6417 if (!key_string->IsInternalizedString()) return Smi::FromInt(0); |
6416 if (type == STRING_SPLIT_SUBSTRINGS) { | 6418 if (type == STRING_SPLIT_SUBSTRINGS) { |
6417 DCHECK(key_pattern->IsString()); | 6419 DCHECK(key_pattern->IsString()); |
6418 if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); | 6420 if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); |
6419 cache = heap->string_split_cache(); | 6421 cache = heap->string_split_cache(); |
6420 } else { | 6422 } else { |
6421 DCHECK(type == REGEXP_MULTIPLE_INDICES); | 6423 DCHECK(type == REGEXP_MULTIPLE_INDICES); |
6422 DCHECK(key_pattern->IsFixedArray()); | 6424 DCHECK(key_pattern->IsFixedArray()); |
6423 cache = heap->regexp_multiple_cache(); | 6425 cache = heap->regexp_multiple_cache(); |
6424 } | 6426 } |
6425 | 6427 |
6426 uint32_t hash = key_string->Hash(); | 6428 uint32_t hash = key_string->Hash(); |
6427 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & | 6429 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
6428 ~(kArrayEntriesPerCacheEntry - 1)); | 6430 ~(kArrayEntriesPerCacheEntry - 1)); |
6429 if (cache->get(index + kStringOffset) == key_string && | 6431 if (cache->get(index + kStringOffset) != key_string || |
6430 cache->get(index + kPatternOffset) == key_pattern) { | 6432 cache->get(index + kPatternOffset) != key_pattern) { |
6431 return cache->get(index + kArrayOffset); | 6433 index = |
| 6434 ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); |
| 6435 if (cache->get(index + kStringOffset) != key_string || |
| 6436 cache->get(index + kPatternOffset) != key_pattern) { |
| 6437 return Smi::FromInt(0); |
| 6438 } |
6432 } | 6439 } |
6433 index = | 6440 |
6434 ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); | 6441 *last_match_cache = FixedArray::cast(cache->get(index + kLastMatchOffset)); |
6435 if (cache->get(index + kStringOffset) == key_string && | 6442 return cache->get(index + kArrayOffset); |
6436 cache->get(index + kPatternOffset) == key_pattern) { | |
6437 return cache->get(index + kArrayOffset); | |
6438 } | |
6439 return Smi::FromInt(0); | |
6440 } | 6443 } |
6441 | 6444 |
6442 | 6445 |
6443 void RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, | 6446 void RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, |
6444 Handle<Object> key_pattern, | 6447 Handle<Object> key_pattern, |
6445 Handle<FixedArray> value_array, | 6448 Handle<FixedArray> value_array, |
| 6449 Handle<FixedArray> last_match_cache, |
6446 ResultsCacheType type) { | 6450 ResultsCacheType type) { |
6447 Factory* factory = isolate->factory(); | 6451 Factory* factory = isolate->factory(); |
6448 Handle<FixedArray> cache; | 6452 Handle<FixedArray> cache; |
6449 if (!key_string->IsInternalizedString()) return; | 6453 if (!key_string->IsInternalizedString()) return; |
6450 if (type == STRING_SPLIT_SUBSTRINGS) { | 6454 if (type == STRING_SPLIT_SUBSTRINGS) { |
6451 DCHECK(key_pattern->IsString()); | 6455 DCHECK(key_pattern->IsString()); |
6452 if (!key_pattern->IsInternalizedString()) return; | 6456 if (!key_pattern->IsInternalizedString()) return; |
6453 cache = factory->string_split_cache(); | 6457 cache = factory->string_split_cache(); |
6454 } else { | 6458 } else { |
6455 DCHECK(type == REGEXP_MULTIPLE_INDICES); | 6459 DCHECK(type == REGEXP_MULTIPLE_INDICES); |
6456 DCHECK(key_pattern->IsFixedArray()); | 6460 DCHECK(key_pattern->IsFixedArray()); |
6457 cache = factory->regexp_multiple_cache(); | 6461 cache = factory->regexp_multiple_cache(); |
6458 } | 6462 } |
6459 | 6463 |
6460 uint32_t hash = key_string->Hash(); | 6464 uint32_t hash = key_string->Hash(); |
6461 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & | 6465 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
6462 ~(kArrayEntriesPerCacheEntry - 1)); | 6466 ~(kArrayEntriesPerCacheEntry - 1)); |
6463 if (cache->get(index + kStringOffset) == Smi::FromInt(0)) { | 6467 if (cache->get(index + kStringOffset) == Smi::FromInt(0)) { |
6464 cache->set(index + kStringOffset, *key_string); | 6468 cache->set(index + kStringOffset, *key_string); |
6465 cache->set(index + kPatternOffset, *key_pattern); | 6469 cache->set(index + kPatternOffset, *key_pattern); |
6466 cache->set(index + kArrayOffset, *value_array); | 6470 cache->set(index + kArrayOffset, *value_array); |
| 6471 cache->set(index + kLastMatchOffset, *last_match_cache); |
6467 } else { | 6472 } else { |
6468 uint32_t index2 = | 6473 uint32_t index2 = |
6469 ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); | 6474 ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); |
6470 if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { | 6475 if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { |
6471 cache->set(index2 + kStringOffset, *key_string); | 6476 cache->set(index2 + kStringOffset, *key_string); |
6472 cache->set(index2 + kPatternOffset, *key_pattern); | 6477 cache->set(index2 + kPatternOffset, *key_pattern); |
6473 cache->set(index2 + kArrayOffset, *value_array); | 6478 cache->set(index2 + kArrayOffset, *value_array); |
| 6479 cache->set(index2 + kLastMatchOffset, *last_match_cache); |
6474 } else { | 6480 } else { |
6475 cache->set(index2 + kStringOffset, Smi::FromInt(0)); | 6481 cache->set(index2 + kStringOffset, Smi::FromInt(0)); |
6476 cache->set(index2 + kPatternOffset, Smi::FromInt(0)); | 6482 cache->set(index2 + kPatternOffset, Smi::FromInt(0)); |
6477 cache->set(index2 + kArrayOffset, Smi::FromInt(0)); | 6483 cache->set(index2 + kArrayOffset, Smi::FromInt(0)); |
| 6484 cache->set(index2 + kLastMatchOffset, Smi::FromInt(0)); |
6478 cache->set(index + kStringOffset, *key_string); | 6485 cache->set(index + kStringOffset, *key_string); |
6479 cache->set(index + kPatternOffset, *key_pattern); | 6486 cache->set(index + kPatternOffset, *key_pattern); |
6480 cache->set(index + kArrayOffset, *value_array); | 6487 cache->set(index + kArrayOffset, *value_array); |
| 6488 cache->set(index + kLastMatchOffset, *last_match_cache); |
6481 } | 6489 } |
6482 } | 6490 } |
6483 // If the array is a reasonably short list of substrings, convert it into a | 6491 // If the array is a reasonably short list of substrings, convert it into a |
6484 // list of internalized strings. | 6492 // list of internalized strings. |
6485 if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { | 6493 if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { |
6486 for (int i = 0; i < value_array->length(); i++) { | 6494 for (int i = 0; i < value_array->length(); i++) { |
6487 Handle<String> str(String::cast(value_array->get(i)), isolate); | 6495 Handle<String> str(String::cast(value_array->get(i)), isolate); |
6488 Handle<String> internalized_str = factory->InternalizeString(str); | 6496 Handle<String> internalized_str = factory->InternalizeString(str); |
6489 value_array->set(i, *internalized_str); | 6497 value_array->set(i, *internalized_str); |
6490 } | 6498 } |
6491 } | 6499 } |
6492 // Convert backing store to a copy-on-write array. | 6500 // Convert backing store to a copy-on-write array. |
6493 value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); | 6501 value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); |
6494 } | 6502 } |
6495 | 6503 |
6496 | 6504 |
6497 void RegExpResultsCache::Clear(FixedArray* cache) { | 6505 void RegExpResultsCache::Clear(FixedArray* cache) { |
6498 for (int i = 0; i < kRegExpResultsCacheSize; i++) { | 6506 for (int i = 0; i < kRegExpResultsCacheSize; i++) { |
6499 cache->set(i, Smi::FromInt(0)); | 6507 cache->set(i, Smi::FromInt(0)); |
6500 } | 6508 } |
6501 } | 6509 } |
6502 | 6510 |
6503 } // namespace internal | 6511 } // namespace internal |
6504 } // namespace v8 | 6512 } // namespace v8 |
OLD | NEW |