Commit ec2518ee authored by cbruni's avatar cbruni Committed by Commit bot

Adding ElementsAccessor::Unshift

Move BackingStore specific implementation from builtins.cc tp ElementsAccessor

BUG=

Review URL: https://codereview.chromium.org/1322803002

Cr-Commit-Position: refs/heads/master@{#30526}
parent a2841eb0
......@@ -472,51 +472,17 @@ BUILTIN(ArrayUnshift) {
}
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);
}
......
......@@ -562,9 +562,15 @@ class ElementsAccessorBase : public ElementsAccessor {
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,
......@@ -609,6 +615,20 @@ class ElementsAccessorBase : public ElementsAccessor {
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 {
......@@ -662,13 +682,21 @@ class ElementsAccessorBase : public ElementsAccessor {
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())) {
......@@ -683,7 +711,8 @@ class ElementsAccessorBase : public ElementsAccessor {
}
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;
}
......@@ -1001,7 +1030,8 @@ class DictionaryElementsAccessor
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);
}
......@@ -1290,6 +1320,49 @@ class FastElementsAccessor
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) {
......@@ -1435,6 +1508,16 @@ class FastSmiOrObjectElementsAccessor
: 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);
......@@ -1554,6 +1637,16 @@ class FastDoubleElementsAccessor
: 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) {
......@@ -1644,6 +1737,16 @@ class TypedElementsAccessor
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);
......@@ -1744,7 +1847,8 @@ class SloppyArgumentsElementsAccessor
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) {
......
......@@ -136,6 +136,10 @@ class ElementsAccessor {
Handle<FixedArrayBase> backing_store, Object** objects,
uint32_t start, int direction) = 0;
virtual uint32_t Unshift(Handle<JSArray> receiver,
Handle<FixedArrayBase> backing_store,
Arguments* args, uint32_t unshift_size) = 0;
virtual Handle<JSArray> Slice(Handle<JSObject> receiver,
Handle<FixedArrayBase> backing_store,
uint32_t start, uint32_t end) = 0;
......
......@@ -14272,12 +14272,6 @@ size_t JSTypedArray::element_size() {
}
void FixedArray::SetValue(uint32_t index, Object* value) { set(index, value); }
void FixedDoubleArray::SetValue(uint32_t index, Object* value) {
set(index, value->Number());
}
void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global,
Handle<Name> name) {
DCHECK(!global->HasFastProperties());
......
......@@ -2391,7 +2391,6 @@ class FixedArray: public FixedArrayBase {
public:
// Setter and getter for elements.
inline Object* get(int index) const;
void SetValue(uint32_t index, Object* value);
static inline Handle<Object> get(Handle<FixedArray> array, int index);
// Setter that uses write barrier.
inline void set(int index, Object* value);
......@@ -2503,8 +2502,6 @@ class FixedDoubleArray: public FixedArrayBase {
inline double get_scalar(int index);
inline uint64_t get_representation(int index);
static inline Handle<Object> get(Handle<FixedDoubleArray> array, int index);
// This accessor has to get a Number as |value|.
void SetValue(uint32_t index, Object* value);
inline void set(int index, double value);
inline void set_the_hole(int index);
......@@ -4303,7 +4300,7 @@ class FixedTypedArray: public FixedTypedArrayBase {
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
void SetValue(uint32_t index, Object* value);
inline void SetValue(uint32_t index, Object* value);
DECLARE_PRINTER(FixedTypedArray)
DECLARE_VERIFIER(FixedTypedArray)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment