Chromium Code Reviews| Index: src/elements.cc |
| diff --git a/src/elements.cc b/src/elements.cc |
| index 7484491a13b35c4a7ce01ac029d46992cba36d8a..751a292cfa074e34cf2bda1bfd2666ac1215d1e6 100644 |
| --- a/src/elements.cc |
| +++ b/src/elements.cc |
| @@ -638,6 +638,19 @@ class ElementsAccessorBase : public ElementsAccessor { |
| UNREACHABLE(); |
| } |
| + virtual void Add(Handle<JSObject> object, uint32_t index, |
| + Handle<Object> value, PropertyAttributes attributes, |
| + uint32_t new_capacity) final { |
| + ElementsAccessorSubclass::AddImpl(object, index, value, attributes, |
| + new_capacity); |
| + } |
| + |
| + static void AddImpl(Handle<JSObject> object, uint32_t index, |
| + Handle<Object> value, PropertyAttributes attributes, |
| + uint32_t new_capacity) { |
| + UNREACHABLE(); |
| + } |
| + |
| virtual MaybeHandle<AccessorPair> GetAccessorPair( |
| Handle<JSObject> holder, uint32_t key, |
| Handle<FixedArrayBase> backing_store) final { |
| @@ -919,17 +932,6 @@ class FastElementsAccessor |
| : ElementsAccessorBase<FastElementsAccessorSubclass, |
| KindTraits>(name) {} |
| - static void ReconfigureImpl(Handle<JSObject> object, |
| - Handle<FixedArrayBase> store, uint32_t index, |
| - Handle<Object> value, |
| - PropertyAttributes attributes) { |
| - Handle<SeededNumberDictionary> dictionary = |
| - JSObject::NormalizeElements(object); |
| - index = dictionary->FindEntry(index); |
| - object->GetElementsAccessor()->Reconfigure(object, dictionary, index, value, |
| - attributes); |
| - } |
| - |
| protected: |
| friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; |
| friend class SloppyArgumentsElementsAccessor; |
| @@ -992,6 +994,42 @@ class FastElementsAccessor |
| } |
| } |
| + static void ReconfigureImpl(Handle<JSObject> object, |
| + Handle<FixedArrayBase> store, uint32_t index, |
| + Handle<Object> value, |
| + PropertyAttributes attributes) { |
| + Handle<SeededNumberDictionary> dictionary = |
| + JSObject::NormalizeElements(object); |
| + index = dictionary->FindEntry(index); |
| + object->GetElementsAccessor()->Reconfigure(object, dictionary, index, value, |
| + attributes); |
| + } |
| + |
| + static void AddImpl(Handle<JSObject> object, uint32_t index, |
| + Handle<Object> value, PropertyAttributes attributes, |
| + uint32_t new_capacity) { |
| + DCHECK_EQ(NONE, attributes); |
| + ElementsKind from_kind = object->GetElementsKind(); |
| + ElementsKind to_kind = FastElementsAccessorSubclass::kind(); |
| + if (IsDictionaryElementsKind(from_kind) || |
| + IsFastDoubleElementsKind(from_kind) != |
| + IsFastDoubleElementsKind(to_kind) || |
| + FastElementsAccessorSubclass::GetCapacityImpl( |
| + *object, object->elements()) != new_capacity) { |
| + FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, |
| + new_capacity); |
| + } else { |
| + if (from_kind != to_kind) { |
| + JSObject::TransitionElementsKind(object, to_kind); |
| + } |
| + if (IsFastSmiOrObjectElementsKind(from_kind)) { |
| + DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); |
| + JSObject::EnsureWritableFastElements(object); |
| + } |
| + } |
| + FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value); |
| + } |
| + |
| virtual void Delete(Handle<JSObject> obj, uint32_t key, |
| LanguageMode language_mode) final { |
| DeleteCommon(obj, key, language_mode); |
| @@ -1455,6 +1493,22 @@ class DictionaryElementsAccessor |
| dictionary->DetailsAtPut(index, details); |
| } |
| + static void AddImpl(Handle<JSObject> object, uint32_t index, |
| + Handle<Object> value, PropertyAttributes attributes, |
| + uint32_t new_capacity) { |
| + PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); |
| + Handle<SeededNumberDictionary> dictionary = |
| + object->HasFastElements() |
| + ? JSObject::NormalizeElements(object) |
| + : handle(SeededNumberDictionary::cast(object->elements())); |
| + Handle<SeededNumberDictionary> new_dictionary = |
| + SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
| + details); |
| + if (attributes != NONE) new_dictionary->set_requires_slow_elements(); |
|
Igor Sheludko
2015/06/25 14:10:07
Shouldn't this be done before AddNumberEntry()?
Toon Verwaest
2015/06/25 14:14:34
Not necessarily. It just needs to be there on the
|
| + if (dictionary.is_identical_to(new_dictionary)) return; |
| + object->set_elements(*new_dictionary); |
| + } |
| + |
| static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
| Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) { |
| Handle<SeededNumberDictionary> backing_store = |
| @@ -1478,8 +1532,9 @@ class DictionaryElementsAccessor |
| static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { |
| DisallowHeapAllocation no_gc; |
| SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
| - Object* key = dict->KeyAt(index); |
| - return Smi::cast(key)->value(); |
| + uint32_t result = 0; |
| + CHECK(dict->KeyAt(index)->ToArrayIndex(&result)); |
| + return result; |
| } |
| static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store, |
| @@ -1611,6 +1666,20 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
| } |
| } |
| + static void AddImpl(Handle<JSObject> object, uint32_t key, |
| + Handle<Object> value, PropertyAttributes attributes, |
| + uint32_t new_capacity) { |
| + DCHECK_EQ(NONE, attributes); |
| + Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
| + Handle<FixedArrayBase> old_elements( |
| + FixedArrayBase::cast(parameter_map->get(1))); |
| + if (old_elements->IsSeededNumberDictionary() || |
| + static_cast<uint32_t>(old_elements->length()) < new_capacity) { |
| + GrowCapacityAndConvertImpl(object, new_capacity); |
| + } |
| + SetImpl(object->elements(), key, *value); |
| + } |
| + |
| static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
| Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) { |
| Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |