| Index: src/elements.cc
|
| diff --git a/src/elements.cc b/src/elements.cc
|
| index fd440a54be129a7a1c02ed75312c97d88827f9e2..b214184d2131b3d0bf1533f879a900a026017261 100644
|
| --- a/src/elements.cc
|
| +++ b/src/elements.cc
|
| @@ -700,15 +700,27 @@ class ElementsAccessorBase : public ElementsAccessor {
|
| return 0;
|
| }
|
|
|
| - Handle<JSArray> Slice(Handle<JSObject> receiver, uint32_t start,
|
| - uint32_t end) final {
|
| + Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start,
|
| + uint32_t end) final {
|
| return Subclass::SliceImpl(receiver, start, end);
|
| }
|
|
|
| - static Handle<JSArray> SliceImpl(Handle<JSObject> receiver,
|
| - uint32_t start, uint32_t end) {
|
| + Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start,
|
| + uint32_t end, Handle<JSObject> result) final {
|
| + return Subclass::SliceWithResultImpl(receiver, start, end, result);
|
| + }
|
| +
|
| + static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start,
|
| + uint32_t end) {
|
| UNREACHABLE();
|
| - return Handle<JSArray>();
|
| + return Handle<JSObject>();
|
| + }
|
| +
|
| + static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver,
|
| + uint32_t start, uint32_t end,
|
| + Handle<JSObject> result) {
|
| + UNREACHABLE();
|
| + return Handle<JSObject>();
|
| }
|
|
|
| Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start,
|
| @@ -2049,8 +2061,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
| AT_START);
|
| }
|
|
|
| - static Handle<JSArray> SliceImpl(Handle<JSObject> receiver,
|
| - uint32_t start, uint32_t end) {
|
| + static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start,
|
| + uint32_t end) {
|
| Isolate* isolate = receiver->GetIsolate();
|
| Handle<FixedArrayBase> backing_store(receiver->elements(), isolate);
|
| int result_len = end < start ? 0u : end - start;
|
| @@ -3052,6 +3064,48 @@ class TypedElementsAccessor
|
| ctype* data = static_cast<ctype*>(elements->DataPtr());
|
| std::reverse(data, data + len);
|
| }
|
| +
|
| + static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver,
|
| + uint32_t start, uint32_t end,
|
| + Handle<JSObject> result) {
|
| + Isolate* isolate = receiver->GetIsolate();
|
| + DCHECK(!WasNeutered(*receiver));
|
| + DCHECK(result->IsJSTypedArray());
|
| + DCHECK(!WasNeutered(*result));
|
| + DCHECK_LE(start, end);
|
| +
|
| + Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
|
| + Handle<JSTypedArray> result_array = Handle<JSTypedArray>::cast(result);
|
| + DCHECK_LE(end, array->length_value());
|
| +
|
| + // Fast path for the same type result array
|
| + if (result_array->type() == array->type()) {
|
| + int64_t element_size = array->element_size();
|
| + int64_t count = end - start;
|
| +
|
| + DisallowHeapAllocation no_gc;
|
| + BackingStore* src_elements = BackingStore::cast(receiver->elements());
|
| + BackingStore* result_elements =
|
| + BackingStore::cast(result_array->elements());
|
| +
|
| + DCHECK_LE(count, result_elements->length());
|
| +
|
| + uint8_t* src = static_cast<uint8_t*>(src_elements->DataPtr());
|
| + uint8_t* result = static_cast<uint8_t*>(result_elements->DataPtr());
|
| + std::memcpy(result, src + start * element_size, count * element_size);
|
| + return result_array;
|
| + }
|
| +
|
| + // If the types of the two typed arrays are different, properly convert
|
| + // elements
|
| + Handle<BackingStore> from(BackingStore::cast(array->elements()), isolate);
|
| + ElementsAccessor* result_accessor = result_array->GetElementsAccessor();
|
| + for (uint32_t i = start; i < end; i++) {
|
| + Handle<Object> elem = AccessorClass::GetImpl(isolate, *from, i);
|
| + result_accessor->Set(result_array, i, *elem);
|
| + }
|
| + return result_array;
|
| + }
|
| };
|
|
|
| #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
|
| @@ -3489,8 +3543,8 @@ class FastSloppyArgumentsElementsAccessor
|
| return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate);
|
| }
|
|
|
| - static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, uint32_t start,
|
| - uint32_t end) {
|
| + static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start,
|
| + uint32_t end) {
|
| Isolate* isolate = receiver->GetIsolate();
|
| uint32_t result_len = end < start ? 0u : end - start;
|
| Handle<JSArray> result_array = isolate->factory()->NewJSArray(
|
|
|