| Index: src/elements.cc
|
| diff --git a/src/elements.cc b/src/elements.cc
|
| index 7ef13b30dedc38511410ef9a5bfb91cdd0297f4b..76269eb87b3f47d8256965bfd208029f312f3b07 100644
|
| --- a/src/elements.cc
|
| +++ b/src/elements.cc
|
| @@ -245,6 +245,7 @@ static void CopyDoubleToObjectElements(FixedArrayBase* from_base,
|
| }
|
| }
|
| }
|
| +
|
| DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
|
| (copy_size + static_cast<int>(from_start)) <= from_base->length());
|
| if (copy_size == 0) return;
|
| @@ -571,6 +572,20 @@ class ElementsAccessorBase : public ElementsAccessor {
|
| UNREACHABLE();
|
| }
|
|
|
| + virtual uint32_t Push(Handle<JSArray> receiver,
|
| + Handle<FixedArrayBase> backing_store, Object** objects,
|
| + uint32_t push_size, int direction) {
|
| + return ElementsAccessorSubclass::PushImpl(receiver, backing_store, objects,
|
| + push_size, direction);
|
| + }
|
| +
|
| + static uint32_t PushImpl(Handle<JSArray> receiver,
|
| + Handle<FixedArrayBase> elms_obj, Object** objects,
|
| + uint32_t push_size, int direction) {
|
| + UNREACHABLE();
|
| + return 0;
|
| + }
|
| +
|
| virtual void SetLength(Handle<JSArray> array, uint32_t length) final {
|
| ElementsAccessorSubclass::SetLengthImpl(array, length,
|
| handle(array->elements()));
|
| @@ -1140,6 +1155,53 @@ class FastElementsAccessor
|
| }
|
| #endif
|
| }
|
| +
|
| + static uint32_t PushImpl(Handle<JSArray> receiver,
|
| + Handle<FixedArrayBase> backing_store,
|
| + Object** objects, uint32_t push_size,
|
| + int direction) {
|
| + uint32_t len = Smi::cast(receiver->length())->value();
|
| + 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) {
|
| + // New backing storage is needed.
|
| + uint32_t capacity = new_length + (new_length >> 1) + 16;
|
| + new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity(
|
| + receiver, backing_store, KindTraits::Kind, capacity);
|
| + } else {
|
| + // push_size is > 0 and new_length <= elms_len, so backing_store cannot be
|
| + // the
|
| + // empty_fixed_array.
|
| + new_elms = backing_store;
|
| + }
|
| +
|
| + // Add the provided values.
|
| + DisallowHeapAllocation no_gc;
|
| + DCHECK(direction == ElementsAccessor::kDirectionForward ||
|
| + direction == ElementsAccessor::kDirectionReverse);
|
| + STATIC_ASSERT(ElementsAccessor::kDirectionForward == 1);
|
| + STATIC_ASSERT(ElementsAccessor::kDirectionReverse == -1);
|
| + for (uint32_t index = 0; index < push_size; index++) {
|
| + int offset = direction * index;
|
| + Object* object = objects[offset];
|
| + FastElementsAccessorSubclass::SetImpl(*new_elms, index + len, object);
|
| + }
|
| + if (!new_elms.is_identical_to(backing_store)) {
|
| + receiver->set_elements(*new_elms);
|
| + }
|
| + DCHECK(*new_elms == receiver->elements());
|
| + // Set the length.
|
| + receiver->set_length(Smi::FromInt(new_length));
|
| + return new_length;
|
| + }
|
| };
|
|
|
|
|
|
|