From 24ef80dc93deba21256e9c270683f47036c9b32d Mon Sep 17 00:00:00 2001 From: mstarzinger Date: Fri, 21 Aug 2015 05:34:17 -0700 Subject: [PATCH] [heap] Move RegExpResultCache out of the heap. R=yangguo@chromium.org,hpayer@chromium.org Review URL: https://codereview.chromium.org/1306053003 Cr-Commit-Position: refs/heads/master@{#30300} --- src/heap/heap.cc | 92 ------------------------------------------------- src/heap/heap.h | 24 ------------- src/regexp/jsregexp.cc | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/regexp/jsregexp.h | 26 +++++++++++++- 4 files changed, 118 insertions(+), 117 deletions(-) diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 234bc9f..e36e2f8 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -3426,98 +3426,6 @@ bool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) { } -Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, - Object* key_pattern, ResultsCacheType type) { - FixedArray* cache; - if (!key_string->IsInternalizedString()) return Smi::FromInt(0); - if (type == STRING_SPLIT_SUBSTRINGS) { - DCHECK(key_pattern->IsString()); - if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); - cache = heap->string_split_cache(); - } else { - DCHECK(type == REGEXP_MULTIPLE_INDICES); - DCHECK(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) == key_string && - cache->get(index + kPatternOffset) == key_pattern) { - return cache->get(index + kArrayOffset); - } - 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 RegExpResultsCache::Enter(Isolate* isolate, Handle key_string, - Handle key_pattern, - Handle value_array, - ResultsCacheType type) { - Factory* factory = isolate->factory(); - Handle cache; - if (!key_string->IsInternalizedString()) return; - if (type == STRING_SPLIT_SUBSTRINGS) { - DCHECK(key_pattern->IsString()); - if (!key_pattern->IsInternalizedString()) return; - cache = factory->string_split_cache(); - } else { - DCHECK(type == REGEXP_MULTIPLE_INDICES); - DCHECK(key_pattern->IsFixedArray()); - cache = factory->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, *key_string); - cache->set(index + kPatternOffset, *key_pattern); - cache->set(index + kArrayOffset, *value_array); - } else { - uint32_t index2 = - ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); - if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { - 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, *key_string); - cache->set(index + kPatternOffset, *key_pattern); - cache->set(index + kArrayOffset, *value_array); - } - } - // If the array is a reasonably short list of substrings, convert it into a - // list of internalized strings. - if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { - for (int i = 0; i < value_array->length(); i++) { - Handle str(String::cast(value_array->get(i)), isolate); - Handle internalized_str = factory->InternalizeString(str); - value_array->set(i, *internalized_str); - } - } - // Convert backing store to a copy-on-write array. - value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); -} - - -void RegExpResultsCache::Clear(FixedArray* cache) { - for (int i = 0; i < kRegExpResultsCacheSize; i++) { - cache->set(i, Smi::FromInt(0)); - } -} - - int Heap::FullSizeNumberStringCacheLength() { // Compute the size of the number string cache based on the max newspace size. // The number string cache has a minimum size based on twice the initial cache diff --git a/src/heap/heap.h b/src/heap/heap.h index 415e7d0..33cb049 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -2643,30 +2643,6 @@ class DescriptorLookupCache { }; -class RegExpResultsCache { - public: - enum ResultsCacheType { REGEXP_MULTIPLE_INDICES, STRING_SPLIT_SUBSTRINGS }; - - // Attempt to retrieve a cached result. On failure, 0 is returned as a Smi. - // On success, the returned result is guaranteed to be a COW-array. - static Object* Lookup(Heap* heap, String* key_string, Object* key_pattern, - ResultsCacheType type); - // Attempt to add value_array to the cache specified by type. On success, - // value_array is turned into a COW-array. - static void Enter(Isolate* isolate, Handle key_string, - Handle key_pattern, Handle value_array, - ResultsCacheType type); - static void Clear(FixedArray* cache); - static const int kRegExpResultsCacheSize = 0x100; - - private: - static const int kArrayEntriesPerCacheEntry = 4; - static const int kStringOffset = 0; - static const int kPatternOffset = 1; - static const int kArrayOffset = 2; -}; - - // Abstract base class for checking whether a weak object should be retained. class WeakObjectRetainer { public: diff --git a/src/regexp/jsregexp.cc b/src/regexp/jsregexp.cc index aacaa1b..61d8792 100644 --- a/src/regexp/jsregexp.cc +++ b/src/regexp/jsregexp.cc @@ -6406,5 +6406,98 @@ bool RegExpEngine::TooMuchRegExpCode(Handle pattern) { } return too_much; } + + +Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, + Object* key_pattern, ResultsCacheType type) { + FixedArray* cache; + if (!key_string->IsInternalizedString()) return Smi::FromInt(0); + if (type == STRING_SPLIT_SUBSTRINGS) { + DCHECK(key_pattern->IsString()); + if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); + cache = heap->string_split_cache(); + } else { + DCHECK(type == REGEXP_MULTIPLE_INDICES); + DCHECK(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) == key_string && + cache->get(index + kPatternOffset) == key_pattern) { + return cache->get(index + kArrayOffset); + } + 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 RegExpResultsCache::Enter(Isolate* isolate, Handle key_string, + Handle key_pattern, + Handle value_array, + ResultsCacheType type) { + Factory* factory = isolate->factory(); + Handle cache; + if (!key_string->IsInternalizedString()) return; + if (type == STRING_SPLIT_SUBSTRINGS) { + DCHECK(key_pattern->IsString()); + if (!key_pattern->IsInternalizedString()) return; + cache = factory->string_split_cache(); + } else { + DCHECK(type == REGEXP_MULTIPLE_INDICES); + DCHECK(key_pattern->IsFixedArray()); + cache = factory->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, *key_string); + cache->set(index + kPatternOffset, *key_pattern); + cache->set(index + kArrayOffset, *value_array); + } else { + uint32_t index2 = + ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); + if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { + 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, *key_string); + cache->set(index + kPatternOffset, *key_pattern); + cache->set(index + kArrayOffset, *value_array); + } + } + // If the array is a reasonably short list of substrings, convert it into a + // list of internalized strings. + if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { + for (int i = 0; i < value_array->length(); i++) { + Handle str(String::cast(value_array->get(i)), isolate); + Handle internalized_str = factory->InternalizeString(str); + value_array->set(i, *internalized_str); + } + } + // Convert backing store to a copy-on-write array. + value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); +} + + +void RegExpResultsCache::Clear(FixedArray* cache) { + for (int i = 0; i < kRegExpResultsCacheSize; i++) { + cache->set(i, Smi::FromInt(0)); + } +} + } // namespace internal } // namespace v8 diff --git a/src/regexp/jsregexp.h b/src/regexp/jsregexp.h index 39e7021..760d378 100644 --- a/src/regexp/jsregexp.h +++ b/src/regexp/jsregexp.h @@ -1659,6 +1659,30 @@ class RegExpEngine: public AllStatic { }; -} } // namespace v8::internal +class RegExpResultsCache : public AllStatic { + public: + enum ResultsCacheType { REGEXP_MULTIPLE_INDICES, STRING_SPLIT_SUBSTRINGS }; + + // Attempt to retrieve a cached result. On failure, 0 is returned as a Smi. + // On success, the returned result is guaranteed to be a COW-array. + static Object* Lookup(Heap* heap, String* key_string, Object* key_pattern, + ResultsCacheType type); + // Attempt to add value_array to the cache specified by type. On success, + // value_array is turned into a COW-array. + static void Enter(Isolate* isolate, Handle key_string, + Handle key_pattern, Handle value_array, + ResultsCacheType type); + static void Clear(FixedArray* cache); + static const int kRegExpResultsCacheSize = 0x100; + + private: + static const int kArrayEntriesPerCacheEntry = 4; + static const int kStringOffset = 0; + static const int kPatternOffset = 1; + static const int kArrayOffset = 2; +}; + +} // namespace internal +} // namespace v8 #endif // V8_REGEXP_JSREGEXP_H_ -- 2.7.4