}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
- if (!array->HasFastSmiOrObjectElements()) {
- return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
- }
- int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
- int new_length = len + to_add;
// Currently fixed arrays cannot grow too big, so
// we should never hit this case.
- DCHECK(to_add <= (Smi::kMaxValue - len));
+ DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value()));
- if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
+ if (to_add > 0 && JSArray::HasReadOnlyLength(array)) {
return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
}
- Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
-
- if (new_length > elms->length()) {
- // New backing storage is needed.
- int capacity = new_length + (new_length >> 1) + 16;
- Handle<FixedArray> new_elms =
- isolate->factory()->NewUninitializedFixedArray(capacity);
-
- ElementsKind kind = array->GetElementsKind();
- ElementsAccessor* accessor = array->GetElementsAccessor();
- accessor->CopyElements(
- elms, 0, kind, new_elms, to_add,
- ElementsAccessor::kCopyToEndAndInitializeToHole);
-
- elms = new_elms;
- array->set_elements(*elms);
- } else {
- DisallowHeapAllocation no_gc;
- Heap* heap = isolate->heap();
- heap->MoveElements(*elms, to_add, 0, len);
- }
-
- // Add the provided values.
- DisallowHeapAllocation no_gc;
- WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
- for (int i = 0; i < to_add; i++) {
- elms->set(i, args[i + 1], mode);
- }
-
- // Set the length.
- array->set_length(Smi::FromInt(new_length));
+ ElementsAccessor* accessor = array->GetElementsAccessor();
+ int new_length = accessor->Unshift(array, elms_obj, &args, to_add);
return Smi::FromInt(new_length);
}
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,
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 {
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())) {
}
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;
}
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);
}
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) {
: 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);
: 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) {
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);
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) {