Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index 8fc025338625aaed00cee4c5101c799296a24d84..04f586e4f8e3c63571b6a81429e77a23cf6779f0 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -1002,7 +1002,8 @@ void Heap::MarkCompactPrologue() { |
isolate_->keyed_lookup_cache()->Clear(); |
isolate_->context_slot_cache()->Clear(); |
isolate_->descriptor_lookup_cache()->Clear(); |
- StringSplitCache::Clear(string_split_cache()); |
+ RegExpResultsCache::Clear(string_split_cache()); |
+ RegExpResultsCache::Clear(regexp_multiple_cache()); |
isolate_->compilation_cache()->MarkCompactPrologue(); |
@@ -2757,12 +2758,18 @@ bool Heap::CreateInitialObjects() { |
set_single_character_string_cache(FixedArray::cast(obj)); |
// Allocate cache for string split. |
- { MaybeObject* maybe_obj = |
- AllocateFixedArray(StringSplitCache::kStringSplitCacheSize, TENURED); |
+ { MaybeObject* maybe_obj = AllocateFixedArray( |
+ RegExpResultsCache::kRegExpResultsCacheSize, TENURED); |
if (!maybe_obj->ToObject(&obj)) return false; |
} |
set_string_split_cache(FixedArray::cast(obj)); |
+ { MaybeObject* maybe_obj = AllocateFixedArray( |
+ RegExpResultsCache::kRegExpResultsCacheSize, TENURED); |
+ if (!maybe_obj->ToObject(&obj)) return false; |
+ } |
+ set_regexp_multiple_cache(FixedArray::cast(obj)); |
+ |
// Allocate cache for external strings pointing to native source code. |
{ MaybeObject* maybe_obj = AllocateFixedArray(Natives::GetBuiltinsCount()); |
if (!maybe_obj->ToObject(&obj)) return false; |
@@ -2788,70 +2795,98 @@ bool Heap::CreateInitialObjects() { |
} |
-Object* StringSplitCache::Lookup( |
- FixedArray* cache, String* string, String* pattern) { |
- if (!string->IsSymbol() || !pattern->IsSymbol()) return Smi::FromInt(0); |
- uint32_t hash = string->Hash(); |
- uint32_t index = ((hash & (kStringSplitCacheSize - 1)) & |
+Object* RegExpResultsCache::Lookup(Heap* heap, |
+ String* key_string, |
+ Object* key_pattern, |
+ ResultsCacheType type) { |
+ FixedArray* cache; |
+ if (!key_string->IsSymbol()) return Smi::FromInt(0); |
+ if (type == STRING_SPLIT_SUBSTRINGS) { |
+ ASSERT(key_pattern->IsString()); |
+ if (!key_pattern->IsSymbol()) return Smi::FromInt(0); |
+ cache = heap->string_split_cache(); |
+ } else { |
+ ASSERT(type == REGEXP_MULTIPLE_INDICES); |
+ ASSERT(key_pattern->IsFixedArray()); |
+ cache = heap->regexp_multiple_cache(); |
+ } |
+ |
+ uint32_t hash = key_string->Hash(); |
+ uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
~(kArrayEntriesPerCacheEntry - 1)); |
- if (cache->get(index + kStringOffset) == string && |
- cache->get(index + kPatternOffset) == pattern) { |
+ if (cache->get(index + kStringOffset) == key_string && |
+ cache->get(index + kPatternOffset) == key_pattern) { |
return cache->get(index + kArrayOffset); |
} |
- index = ((index + kArrayEntriesPerCacheEntry) & (kStringSplitCacheSize - 1)); |
- if (cache->get(index + kStringOffset) == string && |
- cache->get(index + kPatternOffset) == pattern) { |
+ index = |
+ ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); |
+ if (cache->get(index + kStringOffset) == key_string && |
+ cache->get(index + kPatternOffset) == key_pattern) { |
return cache->get(index + kArrayOffset); |
} |
return Smi::FromInt(0); |
} |
-void StringSplitCache::Enter(Heap* heap, |
- FixedArray* cache, |
- String* string, |
- String* pattern, |
- FixedArray* array) { |
- if (!string->IsSymbol() || !pattern->IsSymbol()) return; |
- uint32_t hash = string->Hash(); |
- uint32_t index = ((hash & (kStringSplitCacheSize - 1)) & |
+void RegExpResultsCache::Enter(Heap* heap, |
+ String* key_string, |
+ Object* key_pattern, |
+ FixedArray* value_array, |
+ ResultsCacheType type) { |
+ FixedArray* cache; |
+ if (!key_string->IsSymbol()) return; |
+ if (type == STRING_SPLIT_SUBSTRINGS) { |
+ ASSERT(key_pattern->IsString()); |
+ if (!key_pattern->IsSymbol()) return; |
+ cache = heap->string_split_cache(); |
+ } else { |
+ ASSERT(type == REGEXP_MULTIPLE_INDICES); |
+ ASSERT(key_pattern->IsFixedArray()); |
+ cache = heap->regexp_multiple_cache(); |
+ } |
+ |
+ uint32_t hash = key_string->Hash(); |
+ uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
~(kArrayEntriesPerCacheEntry - 1)); |
if (cache->get(index + kStringOffset) == Smi::FromInt(0)) { |
- cache->set(index + kStringOffset, string); |
- cache->set(index + kPatternOffset, pattern); |
- cache->set(index + kArrayOffset, array); |
+ cache->set(index + kStringOffset, key_string); |
+ cache->set(index + kPatternOffset, key_pattern); |
+ cache->set(index + kArrayOffset, value_array); |
} else { |
uint32_t index2 = |
- ((index + kArrayEntriesPerCacheEntry) & (kStringSplitCacheSize - 1)); |
+ ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); |
if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { |
- cache->set(index2 + kStringOffset, string); |
- cache->set(index2 + kPatternOffset, pattern); |
- cache->set(index2 + kArrayOffset, array); |
+ cache->set(index2 + kStringOffset, key_string); |
+ cache->set(index2 + kPatternOffset, key_pattern); |
+ cache->set(index2 + kArrayOffset, value_array); |
} else { |
cache->set(index2 + kStringOffset, Smi::FromInt(0)); |
cache->set(index2 + kPatternOffset, Smi::FromInt(0)); |
cache->set(index2 + kArrayOffset, Smi::FromInt(0)); |
- cache->set(index + kStringOffset, string); |
- cache->set(index + kPatternOffset, pattern); |
- cache->set(index + kArrayOffset, array); |
+ cache->set(index + kStringOffset, key_string); |
+ cache->set(index + kPatternOffset, key_pattern); |
+ cache->set(index + kArrayOffset, value_array); |
} |
} |
- if (array->length() < 100) { // Limit how many new symbols we want to make. |
- for (int i = 0; i < array->length(); i++) { |
- String* str = String::cast(array->get(i)); |
+ // If the array is a reasonably short list of substrings, convert it into a |
+ // list of symbols. |
+ if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { |
+ for (int i = 0; i < value_array->length(); i++) { |
+ String* str = String::cast(value_array->get(i)); |
Object* symbol; |
MaybeObject* maybe_symbol = heap->LookupSymbol(str); |
if (maybe_symbol->ToObject(&symbol)) { |
- array->set(i, symbol); |
+ value_array->set(i, symbol); |
} |
} |
} |
- array->set_map_no_write_barrier(heap->fixed_cow_array_map()); |
+ // Convert backing store to a copy-on-write array. |
+ value_array->set_map_no_write_barrier(heap->fixed_cow_array_map()); |
} |
-void StringSplitCache::Clear(FixedArray* cache) { |
- for (int i = 0; i < kStringSplitCacheSize; i++) { |
+void RegExpResultsCache::Clear(FixedArray* cache) { |
+ for (int i = 0; i < kRegExpResultsCacheSize; i++) { |
cache->set(i, Smi::FromInt(0)); |
} |
} |