Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 2cf64c52f744c6c08e8af614165641a22e7554b9..51f6b5081c4ade088e305f0562762a9d3ec3765b 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -562,9 +562,15 @@ class ElementsAccessorBase : public ElementsAccessor { |
ElementsAccessorSubclass::SetImpl(backing_store, entry, value); |
} |
- static 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) { |
+ UNREACHABLE(); |
+ } |
+ |
+ |
+ static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
+ Object* value, WriteBarrierMode mode) { |
+ UNREACHABLE(); |
} |
virtual void Reconfigure(Handle<JSObject> object, |
@@ -609,6 +615,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 +682,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) { |
Isolate* isolate = object->GetIsolate(); |
Handle<FixedArrayBase> new_elements; |
if (IsFastDoubleElementsKind(kind())) { |
@@ -683,7 +711,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 +1030,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 +1320,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); |
+ 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 +1508,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); |
+ } |
+ |
+ 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 +1637,16 @@ class FastDoubleElementsAccessor |
: FastElementsAccessor<FastElementsAccessorSubclass, |
KindTraits>(name) {} |
+ static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
+ Object* value) { |
+ 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) { |
@@ -1644,6 +1737,16 @@ class TypedElementsAccessor |
typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; |
typedef TypedElementsAccessor<Kind> AccessorClass; |
+ 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); |
+ } |
+ |
static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, |
uint32_t entry) { |
uint32_t index = GetIndexForEntryImpl(*backing_store, entry); |
@@ -1744,7 +1847,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) { |