Adding ElementsAccessor::Unshift
authorcbruni <cbruni@chromium.org>
Tue, 1 Sep 2015 21:19:44 +0000 (14:19 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 1 Sep 2015 21:19:53 +0000 (21:19 +0000)
Move BackingStore specific implementation from builtins.cc tp ElementsAccessor

BUG=

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

Cr-Commit-Position: refs/heads/master@{#30526}

src/builtins.cc
src/elements.cc
src/elements.h
src/objects.cc
src/objects.h

index 890885267a98c46a519e249b148a806b611944df..5ae9a5e94f5107c35a53861d63ae43b23ab38d46 100644 (file)
@@ -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);
 }
 
index 2cf64c52f744c6c08e8af614165641a22e7554b9..51f6b5081c4ade088e305f0562762a9d3ec3765b 100644 (file)
@@ -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) {
index 6022375e20d324080597738f72332b73f5b60c6d..540be05060b13bf28761a409d03712999381d8e9 100644 (file)
@@ -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;
index 0a5b3d8e6ea7a0e79cfc59396dc09fa3a0f333c7..8caa732ba6c39981dff49dcbe4f4c591ebd544dc 100644 (file)
@@ -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());
index 03db209f13050d943702f10fffbca0a49e7b229c..869253741702f8596dd45b59517bb816437b3414 100644 (file)
@@ -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)