From 9d0cd81da9fdd736094c733f2ad8033103a264e2 Mon Sep 17 00:00:00 2001 From: verwaest Date: Thu, 2 Jul 2015 09:44:17 -0700 Subject: [PATCH] Move slow classes above fast to directly call ReconfigureImpl, remove friends, make things public BUG=v8:4137 LOG=n Review URL: https://codereview.chromium.org/1225493002 Cr-Commit-Position: refs/heads/master@{#29455} --- src/elements.cc | 687 ++++++++++++++++++++++++++------------------------------ 1 file changed, 316 insertions(+), 371 deletions(-) diff --git a/src/elements.cc b/src/elements.cc index 3c6e272..2082543 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -548,10 +548,7 @@ void CheckArrayAbuse(Handle obj, const char* op, uint32_t key, template class ElementsAccessorBase : public ElementsAccessor { - protected: - template - friend class SloppyArgumentsElementsAccessor; + public: explicit ElementsAccessorBase(const char* name) : ElementsAccessor(name) { } @@ -864,7 +861,6 @@ class ElementsAccessorBase : public ElementsAccessor { return result; } - protected: static uint32_t GetCapacityImpl(JSObject* holder, FixedArrayBase* backing_store) { return backing_store->length(); @@ -924,11 +920,200 @@ class ElementsAccessorBase : public ElementsAccessor { }; -class FastSloppyArgumentsElementsAccessor; -class FastHoleyObjectElementsAccessor; -template -class SloppyArgumentsElementsAccessor; +class DictionaryElementsAccessor + : public ElementsAccessorBase > { + public: + explicit DictionaryElementsAccessor(const char* name) + : ElementsAccessorBase >(name) {} + + static void SetLengthImpl(Handle array, uint32_t length, + Handle backing_store) { + Handle dict = + Handle::cast(backing_store); + Isolate* isolate = array->GetIsolate(); + int capacity = dict->Capacity(); + uint32_t old_length = 0; + CHECK(array->length()->ToArrayLength(&old_length)); + if (length < old_length) { + if (dict->requires_slow_elements()) { + // Find last non-deletable element in range of elements to be + // deleted and adjust range accordingly. + for (int i = 0; i < capacity; i++) { + DisallowHeapAllocation no_gc; + Object* key = dict->KeyAt(i); + if (key->IsNumber()) { + uint32_t number = static_cast(key->Number()); + if (length <= number && number < old_length) { + PropertyDetails details = dict->DetailsAt(i); + if (!details.IsConfigurable()) length = number + 1; + } + } + } + } + + if (length == 0) { + // Flush the backing store. + JSObject::ResetElements(array); + } else { + DisallowHeapAllocation no_gc; + // Remove elements that should be deleted. + int removed_entries = 0; + Handle the_hole_value = isolate->factory()->the_hole_value(); + for (int i = 0; i < capacity; i++) { + Object* key = dict->KeyAt(i); + if (key->IsNumber()) { + uint32_t number = static_cast(key->Number()); + if (length <= number && number < old_length) { + dict->SetEntry(i, the_hole_value, the_hole_value); + removed_entries++; + } + } + } + + // Update the number of elements. + dict->ElementsRemoved(removed_entries); + } + } + + Handle length_obj = isolate->factory()->NewNumberFromUint(length); + array->set_length(*length_obj); + } + + static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, + FixedArrayBase* to, ElementsKind from_kind, + uint32_t to_start, int packed_size, + int copy_size) { + UNREACHABLE(); + } + + + static void DeleteCommon(Handle obj, uint32_t key, + LanguageMode language_mode) { + Isolate* isolate = obj->GetIsolate(); + Handle backing_store(FixedArray::cast(obj->elements()), + isolate); + bool is_arguments = obj->HasSloppyArgumentsElements(); + if (is_arguments) { + backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); + } + Handle dictionary = + Handle::cast(backing_store); + int entry = dictionary->FindEntry(key); + if (entry != SeededNumberDictionary::kNotFound) { + Handle result = + SeededNumberDictionary::DeleteProperty(dictionary, entry); + USE(result); + DCHECK(result->IsTrue()); + Handle new_elements = + SeededNumberDictionary::Shrink(dictionary, key); + + if (is_arguments) { + FixedArray::cast(obj->elements())->set(1, *new_elements); + } else { + obj->set_elements(*new_elements); + } + } + } + + virtual void Delete(Handle obj, uint32_t key, + LanguageMode language_mode) final { + DeleteCommon(obj, key, language_mode); + } + + static Handle GetImpl(Handle obj, uint32_t key, + Handle store) { + Handle backing_store = + Handle::cast(store); + Isolate* isolate = backing_store->GetIsolate(); + int entry = backing_store->FindEntry(key); + if (entry != SeededNumberDictionary::kNotFound) { + return handle(backing_store->ValueAt(entry), isolate); + } + return isolate->factory()->the_hole_value(); + } + + static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { + SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); + int entry = dictionary->FindEntry(key); + DCHECK_NE(SeededNumberDictionary::kNotFound, entry); + dictionary->ValueAtPut(entry, value); + } + + static void ReconfigureImpl(Handle object, + Handle store, uint32_t index, + Handle value, + PropertyAttributes attributes) { + SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); + if (attributes != NONE) dictionary->set_requires_slow_elements(); + dictionary->ValueAtPut(index, *value); + PropertyDetails details = dictionary->DetailsAt(index); + details = PropertyDetails(attributes, DATA, details.dictionary_index(), + PropertyCellType::kNoCell); + dictionary->DetailsAtPut(index, details); + } + + static void AddImpl(Handle object, uint32_t index, + Handle value, PropertyAttributes attributes, + uint32_t new_capacity) { + PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); + Handle dictionary = + object->HasFastElements() + ? JSObject::NormalizeElements(object) + : handle(SeededNumberDictionary::cast(object->elements())); + Handle new_dictionary = + SeededNumberDictionary::AddNumberEntry(dictionary, index, value, + details); + if (attributes != NONE) new_dictionary->set_requires_slow_elements(); + if (dictionary.is_identical_to(new_dictionary)) return; + object->set_elements(*new_dictionary); + } + + static MaybeHandle GetAccessorPairImpl( + Handle obj, uint32_t key, Handle store) { + Handle backing_store = + Handle::cast(store); + int entry = backing_store->FindEntry(key); + if (entry != SeededNumberDictionary::kNotFound && + backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && + backing_store->ValueAt(entry)->IsAccessorPair()) { + return handle(AccessorPair::cast(backing_store->ValueAt(entry))); + } + return MaybeHandle(); + } + + static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) { + DisallowHeapAllocation no_gc; + SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); + Object* key = dict->KeyAt(index); + return !key->IsTheHole(); + } + + static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { + DisallowHeapAllocation no_gc; + SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); + uint32_t result = 0; + CHECK(dict->KeyAt(index)->ToArrayIndex(&result)); + return result; + } + + static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store, + uint32_t key) { + DisallowHeapAllocation no_gc; + SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); + int entry = dict->FindEntry(key); + return entry == SeededNumberDictionary::kNotFound + ? kMaxUInt32 + : static_cast(entry); + } + + static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, + uint32_t index) { + return SeededNumberDictionary::cast(backing_store)->DetailsAt(index); + } +}; + // Super class for all fast element arrays. template(name) {} - protected: - friend class ElementsAccessorBase; - friend class SloppyArgumentsElementsAccessor< - FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, - ElementsKindTraits >; - typedef typename KindTraits::BackingStore BackingStore; static void DeleteCommon(Handle obj, uint32_t key, @@ -1011,8 +1190,8 @@ class FastElementsAccessor Handle dictionary = JSObject::NormalizeElements(object); index = dictionary->FindEntry(index); - object->GetElementsAccessor()->Reconfigure(object, dictionary, index, value, - attributes); + DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, index, + value, attributes); } static void AddImpl(Handle object, uint32_t index, @@ -1186,7 +1365,6 @@ class FastDoubleElementsAccessor : FastElementsAccessor(name) {} - protected: static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, FixedArrayBase* to, ElementsKind from_kind, uint32_t to_start, int packed_size, @@ -1232,8 +1410,6 @@ class FastPackedDoubleElementsAccessor FastPackedDoubleElementsAccessor, ElementsKindTraits > { public: - friend class ElementsAccessorBase >; explicit FastPackedDoubleElementsAccessor(const char* name) : FastDoubleElementsAccessor< FastPackedDoubleElementsAccessor, @@ -1246,9 +1422,6 @@ class FastHoleyDoubleElementsAccessor FastHoleyDoubleElementsAccessor, ElementsKindTraits > { public: - friend class ElementsAccessorBase< - FastHoleyDoubleElementsAccessor, - ElementsKindTraits >; explicit FastHoleyDoubleElementsAccessor(const char* name) : FastDoubleElementsAccessor< FastHoleyDoubleElementsAccessor, @@ -1266,13 +1439,9 @@ class TypedElementsAccessor : ElementsAccessorBase >(name) {} - protected: typedef typename ElementsKindTraits::BackingStore BackingStore; typedef TypedElementsAccessor AccessorClass; - friend class ElementsAccessorBase >; - static Handle GetImpl(Handle obj, uint32_t key, Handle backing_store) { if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { @@ -1331,268 +1500,58 @@ TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) #undef FIXED_ELEMENTS_ACCESSOR -class SlowSloppyArgumentsElementsAccessor; +template +class SloppyArgumentsElementsAccessor + : public ElementsAccessorBase { + public: + explicit SloppyArgumentsElementsAccessor(const char* name) + : ElementsAccessorBase(name) {} + static Handle GetImpl(Handle obj, uint32_t key, + Handle parameters) { + Isolate* isolate = obj->GetIsolate(); + Handle parameter_map = Handle::cast(parameters); + Handle probe(GetParameterMapArg(*parameter_map, key), isolate); + if (!probe->IsTheHole()) { + DisallowHeapAllocation no_gc; + Context* context = Context::cast(parameter_map->get(0)); + int context_index = Handle::cast(probe)->value(); + DCHECK(!context->get(context_index)->IsTheHole()); + return handle(context->get(context_index), isolate); + } else { + // Object is not mapped, defer to the arguments. + Handle arguments(FixedArray::cast(parameter_map->get(1)), + isolate); + Handle result = ArgumentsAccessor::GetImpl(obj, key, arguments); + // Elements of the arguments object in slow mode might be slow aliases. + if (result->IsAliasedArgumentsEntry()) { + DisallowHeapAllocation no_gc; + AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); + Context* context = Context::cast(parameter_map->get(0)); + int context_index = entry->aliased_context_slot(); + DCHECK(!context->get(context_index)->IsTheHole()); + return handle(context->get(context_index), isolate); + } else { + return result; + } + } + } -class DictionaryElementsAccessor - : public ElementsAccessorBase > { - public: - explicit DictionaryElementsAccessor(const char* name) - : ElementsAccessorBase >(name) {} - - static void SetLengthImpl(Handle array, uint32_t length, - Handle backing_store) { - Handle dict = - Handle::cast(backing_store); - Isolate* isolate = array->GetIsolate(); - int capacity = dict->Capacity(); - uint32_t old_length = 0; - CHECK(array->length()->ToArrayLength(&old_length)); - if (length < old_length) { - if (dict->requires_slow_elements()) { - // Find last non-deletable element in range of elements to be - // deleted and adjust range accordingly. - for (int i = 0; i < capacity; i++) { - DisallowHeapAllocation no_gc; - Object* key = dict->KeyAt(i); - if (key->IsNumber()) { - uint32_t number = static_cast(key->Number()); - if (length <= number && number < old_length) { - PropertyDetails details = dict->DetailsAt(i); - if (!details.IsConfigurable()) length = number + 1; - } - } - } - } - - if (length == 0) { - // Flush the backing store. - JSObject::ResetElements(array); - } else { - DisallowHeapAllocation no_gc; - // Remove elements that should be deleted. - int removed_entries = 0; - Handle the_hole_value = isolate->factory()->the_hole_value(); - for (int i = 0; i < capacity; i++) { - Object* key = dict->KeyAt(i); - if (key->IsNumber()) { - uint32_t number = static_cast(key->Number()); - if (length <= number && number < old_length) { - dict->SetEntry(i, the_hole_value, the_hole_value); - removed_entries++; - } - } - } - - // Update the number of elements. - dict->ElementsRemoved(removed_entries); - } - } - - Handle length_obj = isolate->factory()->NewNumberFromUint(length); - array->set_length(*length_obj); - } - - static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, - FixedArrayBase* to, ElementsKind from_kind, - uint32_t to_start, int packed_size, - int copy_size) { - UNREACHABLE(); - } - - - protected: - friend class ElementsAccessorBase >; - friend class SlowSloppyArgumentsElementsAccessor; - friend class SloppyArgumentsElementsAccessor< - SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, - ElementsKindTraits >; - - static void DeleteCommon(Handle obj, uint32_t key, - LanguageMode language_mode) { - Isolate* isolate = obj->GetIsolate(); - Handle backing_store(FixedArray::cast(obj->elements()), - isolate); - bool is_arguments = obj->HasSloppyArgumentsElements(); - if (is_arguments) { - backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); - } - Handle dictionary = - Handle::cast(backing_store); - int entry = dictionary->FindEntry(key); - if (entry != SeededNumberDictionary::kNotFound) { - Handle result = - SeededNumberDictionary::DeleteProperty(dictionary, entry); - USE(result); - DCHECK(result->IsTrue()); - Handle new_elements = - SeededNumberDictionary::Shrink(dictionary, key); - - if (is_arguments) { - FixedArray::cast(obj->elements())->set(1, *new_elements); - } else { - obj->set_elements(*new_elements); - } - } - } - - virtual void Delete(Handle obj, uint32_t key, - LanguageMode language_mode) final { - DeleteCommon(obj, key, language_mode); - } - - static Handle GetImpl(Handle obj, uint32_t key, - Handle store) { - Handle backing_store = - Handle::cast(store); - Isolate* isolate = backing_store->GetIsolate(); - int entry = backing_store->FindEntry(key); - if (entry != SeededNumberDictionary::kNotFound) { - return handle(backing_store->ValueAt(entry), isolate); - } - return isolate->factory()->the_hole_value(); - } - - static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { - SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); - int entry = dictionary->FindEntry(key); - DCHECK_NE(SeededNumberDictionary::kNotFound, entry); - dictionary->ValueAtPut(entry, value); - } - - static void ReconfigureImpl(Handle object, - Handle store, uint32_t index, - Handle value, - PropertyAttributes attributes) { - SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); - if (attributes != NONE) dictionary->set_requires_slow_elements(); - dictionary->ValueAtPut(index, *value); - PropertyDetails details = dictionary->DetailsAt(index); - details = PropertyDetails(attributes, DATA, details.dictionary_index(), - PropertyCellType::kNoCell); - dictionary->DetailsAtPut(index, details); - } - - static void AddImpl(Handle object, uint32_t index, - Handle value, PropertyAttributes attributes, - uint32_t new_capacity) { - PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); - Handle dictionary = - object->HasFastElements() - ? JSObject::NormalizeElements(object) - : handle(SeededNumberDictionary::cast(object->elements())); - Handle new_dictionary = - SeededNumberDictionary::AddNumberEntry(dictionary, index, value, - details); - if (attributes != NONE) new_dictionary->set_requires_slow_elements(); - if (dictionary.is_identical_to(new_dictionary)) return; - object->set_elements(*new_dictionary); - } - - static MaybeHandle GetAccessorPairImpl( - Handle obj, uint32_t key, Handle store) { - Handle backing_store = - Handle::cast(store); - int entry = backing_store->FindEntry(key); - if (entry != SeededNumberDictionary::kNotFound && - backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && - backing_store->ValueAt(entry)->IsAccessorPair()) { - return handle(AccessorPair::cast(backing_store->ValueAt(entry))); - } - return MaybeHandle(); - } - - static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) { - DisallowHeapAllocation no_gc; - SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); - Object* key = dict->KeyAt(index); - return !key->IsTheHole(); - } - - static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { - DisallowHeapAllocation no_gc; - SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); - uint32_t result = 0; - CHECK(dict->KeyAt(index)->ToArrayIndex(&result)); - return result; - } - - static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store, - uint32_t key) { - DisallowHeapAllocation no_gc; - SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); - int entry = dict->FindEntry(key); - return entry == SeededNumberDictionary::kNotFound - ? kMaxUInt32 - : static_cast(entry); - } - - static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, - uint32_t index) { - return SeededNumberDictionary::cast(backing_store)->DetailsAt(index); - } -}; - - -template -class SloppyArgumentsElementsAccessor - : public ElementsAccessorBase { - public: - explicit SloppyArgumentsElementsAccessor(const char* name) - : ElementsAccessorBase(name) {} - - protected: - friend class ElementsAccessorBase; - - static Handle GetImpl(Handle obj, uint32_t key, - Handle parameters) { - Isolate* isolate = obj->GetIsolate(); - Handle parameter_map = Handle::cast(parameters); - Handle probe(GetParameterMapArg(*parameter_map, key), isolate); - if (!probe->IsTheHole()) { - DisallowHeapAllocation no_gc; - Context* context = Context::cast(parameter_map->get(0)); - int context_index = Handle::cast(probe)->value(); - DCHECK(!context->get(context_index)->IsTheHole()); - return handle(context->get(context_index), isolate); - } else { - // Object is not mapped, defer to the arguments. - Handle arguments(FixedArray::cast(parameter_map->get(1)), - isolate); - Handle result = ArgumentsAccessor::GetImpl(obj, key, arguments); - // Elements of the arguments object in slow mode might be slow aliases. - if (result->IsAliasedArgumentsEntry()) { - DisallowHeapAllocation no_gc; - AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); - Context* context = Context::cast(parameter_map->get(0)); - int context_index = entry->aliased_context_slot(); - DCHECK(!context->get(context_index)->IsTheHole()); - return handle(context->get(context_index), isolate); - } else { - return result; - } - } - } - - virtual void Delete(Handle obj, uint32_t key, - LanguageMode language_mode) final { - FixedArray* parameter_map = FixedArray::cast(obj->elements()); - if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) { - // TODO(kmillikin): We could check if this was the last aliased - // parameter, and revert to normal elements in that case. That - // would enable GC of the context. - parameter_map->set_the_hole(key + 2); - } else { - ArgumentsAccessor::DeleteCommon(obj, key, language_mode); - } - } + virtual void Delete(Handle obj, uint32_t key, + LanguageMode language_mode) final { + FixedArray* parameter_map = FixedArray::cast(obj->elements()); + if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) { + // TODO(kmillikin): We could check if this was the last aliased + // parameter, and revert to normal elements in that case. That + // would enable GC of the context. + parameter_map->set_the_hole(key + 2); + } else { + ArgumentsAccessor::DeleteCommon(obj, key, language_mode); + } + } static void GrowCapacityAndConvertImpl(Handle object, uint32_t capacity) { @@ -1696,24 +1655,84 @@ class SloppyArgumentsElementsAccessor }; +class SlowSloppyArgumentsElementsAccessor + : public SloppyArgumentsElementsAccessor< + SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, + ElementsKindTraits > { + public: + explicit SlowSloppyArgumentsElementsAccessor(const char* name) + : SloppyArgumentsElementsAccessor< + SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, + ElementsKindTraits >(name) {} + + static void AddImpl(Handle object, uint32_t key, + Handle value, PropertyAttributes attributes, + uint32_t new_capacity) { + Handle parameter_map(FixedArray::cast(object->elements())); + Handle old_elements( + FixedArrayBase::cast(parameter_map->get(1))); + Handle dictionary = + old_elements->IsSeededNumberDictionary() + ? Handle::cast(old_elements) + : JSObject::NormalizeElements(object); + PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); + Handle new_dictionary = + SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details); + if (attributes != NONE) new_dictionary->set_requires_slow_elements(); + if (*dictionary != *new_dictionary) { + FixedArray::cast(object->elements())->set(1, *new_dictionary); + } + } + + static void ReconfigureImpl(Handle object, + Handle store, uint32_t index, + Handle value, + PropertyAttributes attributes) { + Handle parameter_map = Handle::cast(store); + uint32_t length = parameter_map->length() - 2; + if (index < length) { + Object* probe = parameter_map->get(index + 2); + DCHECK(!probe->IsTheHole()); + Context* context = Context::cast(parameter_map->get(0)); + int context_index = Smi::cast(probe)->value(); + DCHECK(!context->get(context_index)->IsTheHole()); + context->set(context_index, *value); + + // Redefining attributes of an aliased element destroys fast aliasing. + parameter_map->set_the_hole(index + 2); + // For elements that are still writable we re-establish slow aliasing. + if ((attributes & READ_ONLY) == 0) { + Isolate* isolate = store->GetIsolate(); + value = isolate->factory()->NewAliasedArgumentsEntry(context_index); + } + + PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); + Handle arguments( + SeededNumberDictionary::cast(parameter_map->get(1))); + arguments = SeededNumberDictionary::AddNumberEntry(arguments, index, + value, details); + parameter_map->set(1, *arguments); + } else { + Handle arguments( + FixedArrayBase::cast(parameter_map->get(1))); + DictionaryElementsAccessor::ReconfigureImpl( + object, arguments, index - length, value, attributes); + } + } +}; + + class FastSloppyArgumentsElementsAccessor : public SloppyArgumentsElementsAccessor< FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, ElementsKindTraits > { public: - friend class SloppyArgumentsElementsAccessor< - FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, - ElementsKindTraits >; - friend class ElementsAccessorBase< - FastSloppyArgumentsElementsAccessor, - ElementsKindTraits >; explicit FastSloppyArgumentsElementsAccessor(const char* name) : SloppyArgumentsElementsAccessor< FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, ElementsKindTraits >(name) {} - protected: static void AddImpl(Handle object, uint32_t key, Handle value, PropertyAttributes attributes, uint32_t new_capacity) { @@ -1739,8 +1758,8 @@ class FastSloppyArgumentsElementsAccessor if (index >= length) { index = dictionary->FindEntry(index - length) + length; } - object->GetElementsAccessor()->Reconfigure(object, store, index, value, - attributes); + SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, index, + value, attributes); } static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, @@ -1778,80 +1797,6 @@ class FastSloppyArgumentsElementsAccessor }; -class SlowSloppyArgumentsElementsAccessor - : public SloppyArgumentsElementsAccessor< - SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, - ElementsKindTraits > { - public: - friend class ElementsAccessorBase< - SlowSloppyArgumentsElementsAccessor, - ElementsKindTraits >; - friend class SloppyArgumentsElementsAccessor< - SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, - ElementsKindTraits >; - explicit SlowSloppyArgumentsElementsAccessor(const char* name) - : SloppyArgumentsElementsAccessor< - SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, - ElementsKindTraits >(name) {} - - protected: - static void AddImpl(Handle object, uint32_t key, - Handle value, PropertyAttributes attributes, - uint32_t new_capacity) { - Handle parameter_map(FixedArray::cast(object->elements())); - Handle old_elements( - FixedArrayBase::cast(parameter_map->get(1))); - Handle dictionary = - old_elements->IsSeededNumberDictionary() - ? Handle::cast(old_elements) - : JSObject::NormalizeElements(object); - PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); - Handle new_dictionary = - SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details); - if (attributes != NONE) new_dictionary->set_requires_slow_elements(); - if (*dictionary != *new_dictionary) { - FixedArray::cast(object->elements())->set(1, *new_dictionary); - } - } - - static void ReconfigureImpl(Handle object, - Handle store, uint32_t index, - Handle value, - PropertyAttributes attributes) { - Handle parameter_map = Handle::cast(store); - uint32_t length = parameter_map->length() - 2; - if (index < length) { - Object* probe = parameter_map->get(index + 2); - DCHECK(!probe->IsTheHole()); - Context* context = Context::cast(parameter_map->get(0)); - int context_index = Smi::cast(probe)->value(); - DCHECK(!context->get(context_index)->IsTheHole()); - context->set(context_index, *value); - - // Redefining attributes of an aliased element destroys fast aliasing. - parameter_map->set_the_hole(index + 2); - // For elements that are still writable we re-establish slow aliasing. - if ((attributes & READ_ONLY) == 0) { - Isolate* isolate = store->GetIsolate(); - value = isolate->factory()->NewAliasedArgumentsEntry(context_index); - } - - PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); - Handle arguments( - SeededNumberDictionary::cast(parameter_map->get(1))); - arguments = SeededNumberDictionary::AddNumberEntry(arguments, index, - value, details); - parameter_map->set(1, *arguments); - } else { - Handle arguments( - FixedArrayBase::cast(parameter_map->get(1))); - DictionaryElementsAccessor::ReconfigureImpl( - object, arguments, index - length, value, attributes); - } - } -}; - - void ElementsAccessor::InitializeOncePerProcess() { static ElementsAccessor* accessor_array[] = { #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), -- 2.7.4