| 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) { | 
|  |