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 6388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6399 bool RegExpEngine::TooMuchRegExpCode(Handle<String> pattern) { | 6399 bool RegExpEngine::TooMuchRegExpCode(Handle<String> pattern) { |
6400 Heap* heap = pattern->GetHeap(); | 6400 Heap* heap = pattern->GetHeap(); |
6401 bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize; | 6401 bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize; |
6402 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && | 6402 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && |
6403 heap->isolate()->memory_allocator()->SizeExecutable() > | 6403 heap->isolate()->memory_allocator()->SizeExecutable() > |
6404 RegExpImpl::kRegExpExecutableMemoryLimit) { | 6404 RegExpImpl::kRegExpExecutableMemoryLimit) { |
6405 too_much = true; | 6405 too_much = true; |
6406 } | 6406 } |
6407 return too_much; | 6407 return too_much; |
6408 } | 6408 } |
| 6409 |
| 6410 |
| 6411 Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, |
| 6412 Object* key_pattern, ResultsCacheType type) { |
| 6413 FixedArray* cache; |
| 6414 if (!key_string->IsInternalizedString()) return Smi::FromInt(0); |
| 6415 if (type == STRING_SPLIT_SUBSTRINGS) { |
| 6416 DCHECK(key_pattern->IsString()); |
| 6417 if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); |
| 6418 cache = heap->string_split_cache(); |
| 6419 } else { |
| 6420 DCHECK(type == REGEXP_MULTIPLE_INDICES); |
| 6421 DCHECK(key_pattern->IsFixedArray()); |
| 6422 cache = heap->regexp_multiple_cache(); |
| 6423 } |
| 6424 |
| 6425 uint32_t hash = key_string->Hash(); |
| 6426 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
| 6427 ~(kArrayEntriesPerCacheEntry - 1)); |
| 6428 if (cache->get(index + kStringOffset) == key_string && |
| 6429 cache->get(index + kPatternOffset) == key_pattern) { |
| 6430 return cache->get(index + kArrayOffset); |
| 6431 } |
| 6432 index = |
| 6433 ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); |
| 6434 if (cache->get(index + kStringOffset) == key_string && |
| 6435 cache->get(index + kPatternOffset) == key_pattern) { |
| 6436 return cache->get(index + kArrayOffset); |
| 6437 } |
| 6438 return Smi::FromInt(0); |
| 6439 } |
| 6440 |
| 6441 |
| 6442 void RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, |
| 6443 Handle<Object> key_pattern, |
| 6444 Handle<FixedArray> value_array, |
| 6445 ResultsCacheType type) { |
| 6446 Factory* factory = isolate->factory(); |
| 6447 Handle<FixedArray> cache; |
| 6448 if (!key_string->IsInternalizedString()) return; |
| 6449 if (type == STRING_SPLIT_SUBSTRINGS) { |
| 6450 DCHECK(key_pattern->IsString()); |
| 6451 if (!key_pattern->IsInternalizedString()) return; |
| 6452 cache = factory->string_split_cache(); |
| 6453 } else { |
| 6454 DCHECK(type == REGEXP_MULTIPLE_INDICES); |
| 6455 DCHECK(key_pattern->IsFixedArray()); |
| 6456 cache = factory->regexp_multiple_cache(); |
| 6457 } |
| 6458 |
| 6459 uint32_t hash = key_string->Hash(); |
| 6460 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
| 6461 ~(kArrayEntriesPerCacheEntry - 1)); |
| 6462 if (cache->get(index + kStringOffset) == Smi::FromInt(0)) { |
| 6463 cache->set(index + kStringOffset, *key_string); |
| 6464 cache->set(index + kPatternOffset, *key_pattern); |
| 6465 cache->set(index + kArrayOffset, *value_array); |
| 6466 } else { |
| 6467 uint32_t index2 = |
| 6468 ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); |
| 6469 if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { |
| 6470 cache->set(index2 + kStringOffset, *key_string); |
| 6471 cache->set(index2 + kPatternOffset, *key_pattern); |
| 6472 cache->set(index2 + kArrayOffset, *value_array); |
| 6473 } else { |
| 6474 cache->set(index2 + kStringOffset, Smi::FromInt(0)); |
| 6475 cache->set(index2 + kPatternOffset, Smi::FromInt(0)); |
| 6476 cache->set(index2 + kArrayOffset, Smi::FromInt(0)); |
| 6477 cache->set(index + kStringOffset, *key_string); |
| 6478 cache->set(index + kPatternOffset, *key_pattern); |
| 6479 cache->set(index + kArrayOffset, *value_array); |
| 6480 } |
| 6481 } |
| 6482 // If the array is a reasonably short list of substrings, convert it into a |
| 6483 // list of internalized strings. |
| 6484 if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { |
| 6485 for (int i = 0; i < value_array->length(); i++) { |
| 6486 Handle<String> str(String::cast(value_array->get(i)), isolate); |
| 6487 Handle<String> internalized_str = factory->InternalizeString(str); |
| 6488 value_array->set(i, *internalized_str); |
| 6489 } |
| 6490 } |
| 6491 // Convert backing store to a copy-on-write array. |
| 6492 value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); |
| 6493 } |
| 6494 |
| 6495 |
| 6496 void RegExpResultsCache::Clear(FixedArray* cache) { |
| 6497 for (int i = 0; i < kRegExpResultsCacheSize; i++) { |
| 6498 cache->set(i, Smi::FromInt(0)); |
| 6499 } |
| 6500 } |
| 6501 |
6409 } // namespace internal | 6502 } // namespace internal |
6410 } // namespace v8 | 6503 } // namespace v8 |
OLD | NEW |