Chromium Code Reviews| Index: src/elements.cc |
| diff --git a/src/elements.cc b/src/elements.cc |
| index 2cf64c52f744c6c08e8af614165641a22e7554b9..1c23087317f395459b76ba32cdba159d8d157bd5 100644 |
| --- a/src/elements.cc |
| +++ b/src/elements.cc |
| @@ -562,8 +562,13 @@ class ElementsAccessorBase : public ElementsAccessor { |
| ElementsAccessorSubclass::SetImpl(backing_store, entry, value); |
| } |
| - static void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| - Object* value) { |
| + static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| + Object* value) { |
| + BackingStore::cast(backing_store)->SetValue(entry, value); |
| + } |
| + |
| + static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| + Object* value, WriteBarrierMode mode) { |
| BackingStore::cast(backing_store)->SetValue(entry, value); |
| } |
| @@ -609,6 +614,20 @@ class ElementsAccessorBase : public ElementsAccessor { |
| return 0; |
| } |
| + virtual uint32_t Unshift(Handle<JSArray> receiver, |
| + Handle<FixedArrayBase> backing_store, |
| + Arguments* args, uint32_t unshift_size) final { |
| + return ElementsAccessorSubclass::UnshiftImpl(receiver, backing_store, args, |
| + unshift_size); |
| + } |
| + |
| + static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| + Handle<FixedArrayBase> elms_obj, Arguments* args, |
| + uint32_t unshift_size) { |
| + UNREACHABLE(); |
| + return 0; |
| + } |
| + |
| virtual Handle<JSArray> Slice(Handle<JSObject> receiver, |
| Handle<FixedArrayBase> backing_store, |
| uint32_t start, uint32_t end) final { |
| @@ -662,13 +681,21 @@ class ElementsAccessorBase : public ElementsAccessor { |
| Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
| ElementsKind from_kind, uint32_t capacity) { |
| return ConvertElementsWithCapacity( |
| - object, old_elements, from_kind, capacity, |
| + object, old_elements, from_kind, capacity, 0, 0, |
| ElementsAccessor::kCopyToEndAndInitializeToHole); |
| } |
| static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
| Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
| ElementsKind from_kind, uint32_t capacity, int copy_size) { |
| + return ConvertElementsWithCapacity(object, old_elements, from_kind, |
| + capacity, 0, 0, copy_size); |
| + } |
| + |
| + static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
| + Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
| + ElementsKind from_kind, uint32_t capacity, uint32_t src_index, |
| + uint32_t dst_index, int copy_size) { |
|
Camillo Bruni
2015/09/01 08:45:12
Added this ConvertElementsWithCapacity to avoid co
|
| Isolate* isolate = object->GetIsolate(); |
| Handle<FixedArrayBase> new_elements; |
| if (IsFastDoubleElementsKind(kind())) { |
| @@ -683,7 +710,8 @@ class ElementsAccessorBase : public ElementsAccessor { |
| } |
| ElementsAccessorSubclass::CopyElementsImpl( |
| - *old_elements, 0, *new_elements, from_kind, 0, packed_size, copy_size); |
| + *old_elements, src_index, *new_elements, from_kind, dst_index, |
| + packed_size, copy_size); |
| return new_elements; |
| } |
| @@ -1001,7 +1029,8 @@ class DictionaryElementsAccessor |
| return handle(GetRaw(*store, entry), isolate); |
| } |
| - static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) { |
| + static inline void SetImpl(FixedArrayBase* store, uint32_t entry, |
| + Object* value) { |
| SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); |
| dictionary->ValueAtPut(entry, value); |
| } |
| @@ -1290,6 +1319,49 @@ class FastElementsAccessor |
| return new_length; |
| } |
| + static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| + Handle<FixedArrayBase> backing_store, |
| + Arguments* args, uint32_t unshift_size) { |
| + uint32_t len = Smi::cast(receiver->length())->value(); |
| + if (unshift_size == 0) { |
| + return len; |
| + } |
| + uint32_t elms_len = backing_store->length(); |
| + // Currently fixed arrays cannot grow too big, so |
| + // we should never hit this case. |
| + DCHECK(unshift_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
| + uint32_t new_length = len + unshift_size; |
| + |
| + if (new_length > elms_len) { |
| + // New backing storage is needed. |
| + uint32_t capacity = new_length + (new_length >> 1) + 16; |
| + backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| + receiver, backing_store, KindTraits::Kind, capacity, 0, unshift_size, |
| + ElementsAccessor::kCopyToEndAndInitializeToHole); |
| + DisallowHeapAllocation no_gc; |
| + receiver->set_elements(*backing_store); |
| + } else { |
| + // unshift_size is > 0 and new_length <= elms_len, so backing_store cannot |
| + // be the empty_fixed_array. |
| + DisallowHeapAllocation no_gc; |
| + Isolate* isolate = receiver->GetIsolate(); |
| + FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store, |
| + unshift_size, 0, len, 0, 0); |
| + } |
| + |
| + // Add the provided values. |
| + DisallowHeapAllocation no_gc; |
| + FixedArrayBase* raw_backing_store = *backing_store; |
| + WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
|
Camillo Bruni
2015/09/01 08:45:12
Introduced the second SetImpl so we can pass along
|
| + for (uint32_t index = 0; index < unshift_size; index++) { |
| + FastElementsAccessorSubclass::SetImpl(raw_backing_store, index, |
| + (*args)[index + 1], mode); |
| + } |
| + // Set the length. |
| + receiver->set_length(Smi::FromInt(new_length)); |
| + return new_length; |
| + } |
| + |
| static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, |
| int dst_index, int src_index, int len, |
| int hole_start, int hole_end) { |
| @@ -1435,6 +1507,16 @@ class FastSmiOrObjectElementsAccessor |
| : FastElementsAccessor<FastElementsAccessorSubclass, |
| KindTraits>(name) {} |
| + static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| + Object* value) { |
| + FixedArray::cast(backing_store)->set(entry, value); |
|
Camillo Bruni
2015/09/01 08:45:13
If I don't use the more uniform SetValue method (w
|
| + } |
| + |
| + static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| + Object* value, WriteBarrierMode mode) { |
| + FixedArray::cast(backing_store)->set(entry, value, mode); |
| + } |
| + |
| static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { |
| uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( |
| backing_store, entry); |
| @@ -1554,6 +1636,16 @@ class FastDoubleElementsAccessor |
| : FastElementsAccessor<FastElementsAccessorSubclass, |
| KindTraits>(name) {} |
| + static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| + Object* value) { |
|
Camillo Bruni
2015/09/01 08:45:12
If I leave out this version (for FixedDoubleArray)
|
| + FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
| + } |
| + |
| + static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| + Object* value, WriteBarrierMode mode) { |
| + FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
| + } |
| + |
| static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, |
| int dst_index, int src_index, int len, |
| int hole_start, int hole_end) { |
| @@ -1744,7 +1836,8 @@ class SloppyArgumentsElementsAccessor |
| UNREACHABLE(); |
| } |
| - static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) { |
| + static inline void SetImpl(FixedArrayBase* store, uint32_t entry, |
| + Object* value) { |
| FixedArray* parameter_map = FixedArray::cast(store); |
| uint32_t length = parameter_map->length() - 2; |
| if (entry < length) { |
| @@ -2224,7 +2317,6 @@ void ElementsAccessor::TearDown() { |
| elements_accessors_ = NULL; |
| } |
| - |
| ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| } // namespace internal |
| } // namespace v8 |