Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index e133f8f738eb0bcf0b90c822e13c3a80d45e0b79..d36f7a4e4961798dc309a858a2f650f2cdfcded7 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -585,6 +585,20 @@ class ElementsAccessorBase : public ElementsAccessor { |
return 0; |
} |
+ virtual uint32_t Unshift(Handle<JSArray> receiver, |
+ Handle<FixedArrayBase> backing_store, Arguments args, |
+ uint32_t add_count) { |
+ return ElementsAccessorSubclass::UnshiftImpl(receiver, backing_store, args, |
+ add_count); |
+ } |
+ |
+ static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
+ Handle<FixedArrayBase> backing_store, |
+ Arguments args, uint32_t add_count) { |
+ UNREACHABLE(); |
+ return 0; |
+ } |
+ |
virtual Handle<JSArray> Splice(Handle<JSArray> receiver, |
Handle<FixedArrayBase> backing_store, |
uint32_t start, uint32_t delete_count, |
@@ -1181,6 +1195,50 @@ class FastElementsAccessor |
#endif |
} |
+ |
+ static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
+ Handle<FixedArrayBase> backing_store, |
+ Arguments args, uint32_t add_count) { |
+ int len = Smi::cast(receiver->length())->value(); |
+ if (add_count == 0) { |
+ return len; |
+ } |
+ // Currently fixed arrays cannot grow too big, so |
+ // we should never hit this case. |
+ DCHECK(add_count <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
+ int new_length = len + add_count; |
+ Handle<FixedArrayBase> new_elements; |
+ |
+ if (new_length > backing_store->length()) { |
+ // New backing storage is needed. |
+ int capacity = new_length + (new_length >> 1) + 16; |
+ new_elements = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
+ receiver, backing_store, KindTraits::Kind, capacity, 0); |
+ FastElementsAccessorSubclass::CopyElementsImpl( |
+ *backing_store, 0, *new_elements, KindTraits::Kind, add_count, |
+ kPackedSizeNotKnown, ElementsAccessor::kCopyToEndAndInitializeToHole); |
+ } else { |
+ DisallowHeapAllocation no_gc; |
+ Heap* heap = receiver->GetIsolate()->heap(); |
+ FastElementsAccessorSubclass::MoveElements(heap, backing_store, add_count, |
+ 0, len, 0, 0); |
+ new_elements = backing_store; |
+ } |
+ |
+ // Add the provided values. |
+ DisallowHeapAllocation no_gc; |
+ for (uint32_t i = 0; i < add_count; i++) { |
+ FastElementsAccessorSubclass::SetImpl(*new_elements, i, args[i + 1]); |
+ } |
+ if (!new_elements.is_identical_to(backing_store)) { |
+ receiver->set_elements(*new_elements); |
+ } |
+ // Set the length. |
+ receiver->set_length(Smi::FromInt(new_length)); |
+ return new_length; |
+ } |
+ |
+ |
static uint32_t PushImpl(Handle<JSArray> receiver, |
Handle<FixedArrayBase> backing_store, |
Object** objects, uint32_t push_size, |
@@ -1189,14 +1247,13 @@ class FastElementsAccessor |
if (push_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(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
uint32_t new_length = len + push_size; |
Handle<FixedArrayBase> new_elms; |
- if (new_length > elms_len) { |
+ if (new_length > static_cast<uint32_t>(backing_store->length())) { |
// New backing storage is needed. |
uint32_t capacity = new_length + (new_length >> 1) + 16; |
new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
@@ -1271,19 +1328,10 @@ class FastElementsAccessor |
} |
// Copy new Elements from args |
- if (IsFastDoubleElementsKind(KindTraits::Kind)) { |
- for (uint32_t index = start; index < start + add_count; index++) { |
- Object* arg = args[3 + index - start]; |
- FastElementsAccessorSubclass::SetImpl(*backing_store, index, arg); |
- } |
- } else { |
- // FastSmiOrObjectElementsKind |
- Handle<FixedArray> elms = Handle<FixedArray>::cast(backing_store); |
- DisallowHeapAllocation no_gc; |
- WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
- for (uint32_t index = start; index < start + add_count; index++) { |
- elms->set(index, args[3 + index - start], mode); |
- } |
+ DisallowHeapAllocation no_gc; |
+ for (uint32_t index = start; index < start + add_count; index++) { |
+ Object* object = args[3 + index - start]; |
+ FastElementsAccessorSubclass::SetImpl(*backing_store, index, object); |
} |
if (elms_changed) { |