Roll V8 back to 3.6

Roll back to V8 3.6 to fix x86 build, we don't have ucontext.h.

This reverts commits:
5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b
c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9
592a9fc1d8ea420377a2e7efd0600e20b058be2b

Bug: 5688872
Change-Id: Ic961bb5e65b778e98bbfb71cce71d99fa949e995
diff --git a/src/elements.cc b/src/elements.cc
index 1d043a1..0454644 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -31,85 +31,14 @@
 #include "elements.h"
 #include "utils.h"
 
-
-// Each concrete ElementsAccessor can handle exactly one ElementsKind,
-// several abstract ElementsAccessor classes are used to allow sharing
-// common code.
-//
-// Inheritance hierarchy:
-// - ElementsAccessorBase                        (abstract)
-//   - FastElementsAccessor                      (abstract)
-//     - FastObjectElementsAccessor
-//     - FastDoubleElementsAccessor
-//   - ExternalElementsAccessor                  (abstract)
-//     - ExternalByteElementsAccessor
-//     - ExternalUnsignedByteElementsAccessor
-//     - ExternalShortElementsAccessor
-//     - ExternalUnsignedShortElementsAccessor
-//     - ExternalIntElementsAccessor
-//     - ExternalUnsignedIntElementsAccessor
-//     - ExternalFloatElementsAccessor
-//     - ExternalDoubleElementsAccessor
-//     - PixelElementsAccessor
-//   - DictionaryElementsAccessor
-//   - NonStrictArgumentsElementsAccessor
-
-
 namespace v8 {
 namespace internal {
 
 
-// First argument in list is the accessor class, the second argument is the
-// accessor ElementsKind, and the third is the backing store class.  Use the
-// fast element handler for smi-only arrays.  The implementation is currently
-// identical.  Note that the order must match that of the ElementsKind enum for
-// the |accessor_array[]| below to work.
-#define ELEMENTS_LIST(V)                                                \
-  V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS, FixedArray)     \
-  V(FastObjectElementsAccessor, FAST_ELEMENTS, FixedArray)              \
-  V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
-  V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS,                    \
-    SeededNumberDictionary)                                             \
-  V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS,  \
-    FixedArray)                                                         \
-  V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS,               \
-    ExternalByteArray)                                                  \
-  V(ExternalUnsignedByteElementsAccessor,                               \
-    EXTERNAL_UNSIGNED_BYTE_ELEMENTS, ExternalUnsignedByteArray)         \
-  V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS,             \
-    ExternalShortArray)                                                 \
-  V(ExternalUnsignedShortElementsAccessor,                              \
-    EXTERNAL_UNSIGNED_SHORT_ELEMENTS, ExternalUnsignedShortArray)       \
-  V(ExternalIntElementsAccessor, EXTERNAL_INT_ELEMENTS,                 \
-    ExternalIntArray)                                                   \
-  V(ExternalUnsignedIntElementsAccessor,                                \
-    EXTERNAL_UNSIGNED_INT_ELEMENTS, ExternalUnsignedIntArray)           \
-  V(ExternalFloatElementsAccessor,                                      \
-    EXTERNAL_FLOAT_ELEMENTS, ExternalFloatArray)                        \
-  V(ExternalDoubleElementsAccessor,                                     \
-    EXTERNAL_DOUBLE_ELEMENTS, ExternalDoubleArray)                      \
-  V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS, ExternalPixelArray)
-
-
-template<ElementsKind Kind> class ElementsKindTraits {
- public:
-  typedef FixedArrayBase BackingStore;
-};
-
-#define ELEMENTS_TRAITS(Class, KindParam, Store)               \
-template<> class ElementsKindTraits<KindParam> {               \
-  public:                                                      \
-  static const ElementsKind Kind = KindParam;                  \
-  typedef Store BackingStore;                                  \
-};
-ELEMENTS_LIST(ELEMENTS_TRAITS)
-#undef ELEMENTS_TRAITS
-
-
 ElementsAccessor** ElementsAccessor::elements_accessors_;
 
 
-static bool HasKey(FixedArray* array, Object* key) {
+bool HasKey(FixedArray* array, Object* key) {
   int len0 = array->length();
   for (int i = 0; i < len0; i++) {
     Object* element = array->get(i);
@@ -123,252 +52,6 @@
 }
 
 
-static Failure* ThrowArrayLengthRangeError(Heap* heap) {
-  HandleScope scope(heap->isolate());
-  return heap->isolate()->Throw(
-      *heap->isolate()->factory()->NewRangeError("invalid_array_length",
-          HandleVector<Object>(NULL, 0)));
-}
-
-
-void CopyObjectToObjectElements(FixedArray* from,
-                                ElementsKind from_kind,
-                                uint32_t from_start,
-                                FixedArray* to,
-                                ElementsKind to_kind,
-                                uint32_t to_start,
-                                int raw_copy_size) {
-  ASSERT(to->map() != HEAP->fixed_cow_array_map());
-  ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
-  ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
-  int copy_size = raw_copy_size;
-  if (raw_copy_size < 0) {
-    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
-           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
-    copy_size = Min(from->length() - from_start,
-                    to->length() - to_start);
-#ifdef DEBUG
-    // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
-    // marked with the hole.
-    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
-      for (int i = to_start + copy_size; i < to->length(); ++i) {
-        ASSERT(to->get(i)->IsTheHole());
-      }
-    }
-#endif
-  }
-  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
-         (copy_size + static_cast<int>(from_start)) <= from->length());
-  if (copy_size == 0) return;
-  Address to_address = to->address() + FixedArray::kHeaderSize;
-  Address from_address = from->address() + FixedArray::kHeaderSize;
-  CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
-            reinterpret_cast<Object**>(from_address) + from_start,
-            copy_size);
-  if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) {
-    Heap* heap = from->GetHeap();
-    if (!heap->InNewSpace(to)) {
-      heap->RecordWrites(to->address(),
-                         to->OffsetOfElementAt(to_start),
-                         copy_size);
-    }
-    heap->incremental_marking()->RecordWrites(to);
-  }
-}
-
-
-static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
-                                           uint32_t from_start,
-                                           FixedArray* to,
-                                           ElementsKind to_kind,
-                                           uint32_t to_start,
-                                           int raw_copy_size) {
-  int copy_size = raw_copy_size;
-  Heap* heap = from->GetHeap();
-  if (raw_copy_size < 0) {
-    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
-           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
-    copy_size = from->max_number_key() + 1 - from_start;
-#ifdef DEBUG
-    // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
-    // marked with the hole.
-    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
-      for (int i = to_start + copy_size; i < to->length(); ++i) {
-        ASSERT(to->get(i)->IsTheHole());
-      }
-    }
-#endif
-  }
-  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length());
-  ASSERT(to != from);
-  ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
-  if (copy_size == 0) return;
-  for (int i = 0; i < copy_size; i++) {
-    int entry = from->FindEntry(i + from_start);
-    if (entry != SeededNumberDictionary::kNotFound) {
-      Object* value = from->ValueAt(entry);
-      ASSERT(!value->IsTheHole());
-      to->set(i + to_start, value, SKIP_WRITE_BARRIER);
-    } else {
-      to->set_the_hole(i + to_start);
-    }
-  }
-  if (to_kind == FAST_ELEMENTS) {
-    if (!heap->InNewSpace(to)) {
-      heap->RecordWrites(to->address(),
-                         to->OffsetOfElementAt(to_start),
-                         copy_size);
-    }
-    heap->incremental_marking()->RecordWrites(to);
-  }
-}
-
-
-MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
-    FixedDoubleArray* from,
-    uint32_t from_start,
-    FixedArray* to,
-    ElementsKind to_kind,
-    uint32_t to_start,
-    int raw_copy_size) {
-  ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
-  int copy_size = raw_copy_size;
-  if (raw_copy_size < 0) {
-    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
-           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
-    copy_size = Min(from->length() - from_start,
-                    to->length() - to_start);
-#ifdef DEBUG
-    // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
-    // marked with the hole.
-    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
-      for (int i = to_start + copy_size; i < to->length(); ++i) {
-        ASSERT(to->get(i)->IsTheHole());
-      }
-    }
-#endif
-  }
-  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
-         (copy_size + static_cast<int>(from_start)) <= from->length());
-  if (copy_size == 0) return from;
-  for (int i = 0; i < copy_size; ++i) {
-    if (to_kind == FAST_SMI_ONLY_ELEMENTS) {
-      UNIMPLEMENTED();
-      return Failure::Exception();
-    } else {
-      MaybeObject* maybe_value = from->get(i + from_start);
-      Object* value;
-      ASSERT(to_kind == FAST_ELEMENTS);
-      // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects
-      // iteratively, the allocate must succeed within a single GC cycle,
-      // otherwise the retry after the GC will also fail. In order to ensure
-      // that no GC is triggered, allocate HeapNumbers from old space if they
-      // can't be taken from new space.
-      if (!maybe_value->ToObject(&value)) {
-        ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory());
-        Heap* heap = from->GetHeap();
-        MaybeObject* maybe_value_object =
-            heap->AllocateHeapNumber(from->get_scalar(i + from_start),
-                                     TENURED);
-        if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
-      }
-      to->set(i + to_start, value, UPDATE_WRITE_BARRIER);
-    }
-  }
-  return to;
-}
-
-
-static void CopyDoubleToDoubleElements(FixedDoubleArray* from,
-                                       uint32_t from_start,
-                                       FixedDoubleArray* to,
-                                       uint32_t to_start,
-                                       int raw_copy_size) {
-  int copy_size = raw_copy_size;
-  if (raw_copy_size < 0) {
-    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
-           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
-    copy_size = Min(from->length() - from_start,
-                    to->length() - to_start);
-    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
-      for (int i = to_start + copy_size; i < to->length(); ++i) {
-        to->set_the_hole(i);
-      }
-    }
-  }
-  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
-         (copy_size + static_cast<int>(from_start)) <= from->length());
-  if (copy_size == 0) return;
-  Address to_address = to->address() + FixedDoubleArray::kHeaderSize;
-  Address from_address = from->address() + FixedDoubleArray::kHeaderSize;
-  to_address += kDoubleSize * to_start;
-  from_address += kDoubleSize * from_start;
-  int words_per_double = (kDoubleSize / kPointerSize);
-  CopyWords(reinterpret_cast<Object**>(to_address),
-            reinterpret_cast<Object**>(from_address),
-            words_per_double * copy_size);
-}
-
-
-static void CopyObjectToDoubleElements(FixedArray* from,
-                                       uint32_t from_start,
-                                       FixedDoubleArray* to,
-                                       uint32_t to_start,
-                                       int raw_copy_size) {
-  int copy_size = raw_copy_size;
-  if (raw_copy_size < 0) {
-    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
-           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
-    copy_size = from->length() - from_start;
-    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
-      for (int i = to_start + copy_size; i < to->length(); ++i) {
-        to->set_the_hole(i);
-      }
-    }
-  }
-  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
-         (copy_size + static_cast<int>(from_start)) <= from->length());
-  if (copy_size == 0) return;
-  for (int i = 0; i < copy_size; i++) {
-    Object* hole_or_object = from->get(i + from_start);
-    if (hole_or_object->IsTheHole()) {
-      to->set_the_hole(i + to_start);
-    } else {
-      to->set(i + to_start, hole_or_object->Number());
-    }
-  }
-}
-
-
-static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from,
-                                           uint32_t from_start,
-                                           FixedDoubleArray* to,
-                                           uint32_t to_start,
-                                           int raw_copy_size) {
-  int copy_size = raw_copy_size;
-  if (copy_size < 0) {
-    ASSERT(copy_size == ElementsAccessor::kCopyToEnd ||
-           copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
-    copy_size = from->max_number_key() + 1 - from_start;
-    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
-      for (int i = to_start + copy_size; i < to->length(); ++i) {
-        to->set_the_hole(i);
-      }
-    }
-  }
-  ASSERT(copy_size + static_cast<int>(to_start) <= to->length());
-  if (copy_size == 0) return;
-  for (int i = 0; i < copy_size; i++) {
-    int entry = from->FindEntry(i + from_start);
-    if (entry != SeededNumberDictionary::kNotFound) {
-      to->set(i + to_start, from->ValueAt(entry)->Number());
-    } else {
-      to->set_the_hole(i + to_start);
-    }
-  }
-}
-
-
 // Base class for element handler implementations. Contains the
 // the common logic for objects with different ElementsKinds.
 // Subclasses must specialize method for which the element
@@ -386,119 +69,36 @@
 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).  We use
 // CRTP to guarantee aggressive compile time optimizations (i.e.  inlining and
 // specialization of SomeElementsAccessor methods).
-template <typename ElementsAccessorSubclass,
-          typename ElementsTraitsParam>
+template <typename ElementsAccessorSubclass, typename BackingStoreClass>
 class ElementsAccessorBase : public ElementsAccessor {
  protected:
-  explicit ElementsAccessorBase(const char* name)
-      : ElementsAccessor(name) { }
-
-  typedef ElementsTraitsParam ElementsTraits;
-  typedef typename ElementsTraitsParam::BackingStore BackingStore;
-
-  virtual ElementsKind kind() const { return ElementsTraits::Kind; }
-
-  static bool HasElementImpl(Object* receiver,
-                             JSObject* holder,
-                             uint32_t key,
-                             BackingStore* backing_store) {
-    MaybeObject* element =
-        ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store);
-    return !element->IsTheHole();
-  }
-
-  virtual bool HasElement(Object* receiver,
-                          JSObject* holder,
-                          uint32_t key,
-                          FixedArrayBase* backing_store) {
-    if (backing_store == NULL) {
-      backing_store = holder->elements();
-    }
-    return ElementsAccessorSubclass::HasElementImpl(
-        receiver, holder, key, BackingStore::cast(backing_store));
-  }
-
-  virtual MaybeObject* Get(Object* receiver,
-                           JSObject* holder,
+  ElementsAccessorBase() { }
+  virtual MaybeObject* Get(FixedArrayBase* backing_store,
                            uint32_t key,
-                           FixedArrayBase* backing_store) {
-    if (backing_store == NULL) {
-      backing_store = holder->elements();
+                           JSObject* obj,
+                           Object* receiver) {
+    return ElementsAccessorSubclass::Get(
+        BackingStoreClass::cast(backing_store), key, obj, receiver);
+  }
+
+  static MaybeObject* Get(BackingStoreClass* backing_store,
+                          uint32_t key,
+                          JSObject* obj,
+                          Object* receiver) {
+    if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) {
+      return backing_store->get(key);
     }
-    return ElementsAccessorSubclass::GetImpl(
-        receiver, holder, key, BackingStore::cast(backing_store));
-  }
-
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              BackingStore* backing_store) {
-    return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
-           ? backing_store->get(key)
-           : backing_store->GetHeap()->the_hole_value();
-  }
-
-  virtual MaybeObject* SetLength(JSArray* array,
-                                 Object* length) {
-    return ElementsAccessorSubclass::SetLengthImpl(
-        array, length, BackingStore::cast(array->elements()));
-  }
-
-  static MaybeObject* SetLengthImpl(JSObject* obj,
-                                    Object* length,
-                                    BackingStore* backing_store);
-
-  virtual MaybeObject* SetCapacityAndLength(JSArray* array,
-                                            int capacity,
-                                            int length) {
-    return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
-        array,
-        capacity,
-        length);
-  }
-
-  static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
-                                                       int capacity,
-                                                       int length) {
-    UNIMPLEMENTED();
-    return obj;
+    return backing_store->GetHeap()->the_hole_value();
   }
 
   virtual MaybeObject* Delete(JSObject* obj,
                               uint32_t key,
                               JSReceiver::DeleteMode mode) = 0;
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
-    UNREACHABLE();
-    return NULL;
-  }
-
-  virtual MaybeObject* CopyElements(JSObject* from_holder,
-                                    uint32_t from_start,
-                                    FixedArrayBase* to,
-                                    ElementsKind to_kind,
-                                    uint32_t to_start,
-                                    int copy_size,
-                                    FixedArrayBase* from) {
-    if (from == NULL) {
-      from = from_holder->elements();
-    }
-    if (from->length() == 0) {
-      return from;
-    }
-    return ElementsAccessorSubclass::CopyElementsImpl(
-        from, from_start, to, to_kind, to_start, copy_size);
-  }
-
-  virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
-                                               JSObject* holder,
+  virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from,
                                                FixedArray* to,
-                                               FixedArrayBase* from) {
+                                               JSObject* holder,
+                                               Object* receiver) {
     int len0 = to->length();
 #ifdef DEBUG
     if (FLAG_enable_slow_asserts) {
@@ -507,26 +107,24 @@
       }
     }
 #endif
-    if (from == NULL) {
-      from = holder->elements();
-    }
-    BackingStore* backing_store = BackingStore::cast(from);
-    uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
+    BackingStoreClass* backing_store = BackingStoreClass::cast(from);
+    uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store);
 
     // Optimize if 'other' is empty.
     // We cannot optimize if 'this' is empty, as other may have holes.
     if (len1 == 0) return to;
 
     // Compute how many elements are not in other.
-    uint32_t extra = 0;
+    int extra = 0;
     for (uint32_t y = 0; y < len1; y++) {
-      uint32_t key =
-          ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
-      if (ElementsAccessorSubclass::HasElementImpl(
-              receiver, holder, key, backing_store)) {
+      if (ElementsAccessorSubclass::HasElementAtIndex(backing_store,
+                                                      y,
+                                                      holder,
+                                                      receiver)) {
+        uint32_t key =
+            ElementsAccessorSubclass::GetKeyForIndex(backing_store, y);
         MaybeObject* maybe_value =
-            ElementsAccessorSubclass::GetImpl(receiver, holder,
-                                              key, backing_store);
+            ElementsAccessorSubclass::Get(backing_store, key, holder, receiver);
         Object* value;
         if (!maybe_value->ToObject(&value)) return maybe_value;
         ASSERT(!value->IsTheHole());
@@ -555,15 +153,16 @@
       }
     }
     // Fill in the extra values.
-    uint32_t index = 0;
+    int index = 0;
     for (uint32_t y = 0; y < len1; y++) {
-      uint32_t key =
-          ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
-      if (ElementsAccessorSubclass::HasElementImpl(
-              receiver, holder, key, backing_store)) {
+      if (ElementsAccessorSubclass::HasElementAtIndex(backing_store,
+                                                      y,
+                                                      holder,
+                                                      receiver)) {
+        uint32_t key =
+            ElementsAccessorSubclass::GetKeyForIndex(backing_store, y);
         MaybeObject* maybe_value =
-            ElementsAccessorSubclass::GetImpl(receiver, holder,
-                                              key, backing_store);
+            ElementsAccessorSubclass::Get(backing_store, key, holder, receiver);
         Object* value;
         if (!maybe_value->ToObject(&value)) return maybe_value;
         if (!value->IsTheHole() && !HasKey(to, value)) {
@@ -577,24 +176,45 @@
   }
 
  protected:
-  static uint32_t GetCapacityImpl(BackingStore* backing_store) {
+  static uint32_t GetCapacity(BackingStoreClass* backing_store) {
     return backing_store->length();
   }
 
   virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
-    return ElementsAccessorSubclass::GetCapacityImpl(
-        BackingStore::cast(backing_store));
+    return ElementsAccessorSubclass::GetCapacity(
+        BackingStoreClass::cast(backing_store));
   }
 
-  static uint32_t GetKeyForIndexImpl(BackingStore* backing_store,
-                                     uint32_t index) {
+  static bool HasElementAtIndex(BackingStoreClass* backing_store,
+                                uint32_t index,
+                                JSObject* holder,
+                                Object* receiver) {
+    uint32_t key =
+        ElementsAccessorSubclass::GetKeyForIndex(backing_store, index);
+    MaybeObject* element = ElementsAccessorSubclass::Get(backing_store,
+                                                         key,
+                                                         holder,
+                                                         receiver);
+    return !element->IsTheHole();
+  }
+
+  virtual bool HasElementAtIndex(FixedArrayBase* backing_store,
+                                 uint32_t index,
+                                 JSObject* holder,
+                                 Object* receiver) {
+    return ElementsAccessorSubclass::HasElementAtIndex(
+        BackingStoreClass::cast(backing_store), index, holder, receiver);
+  }
+
+  static uint32_t GetKeyForIndex(BackingStoreClass* backing_store,
+                                 uint32_t index) {
     return index;
   }
 
   virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
-                                  uint32_t index) {
-    return ElementsAccessorSubclass::GetKeyForIndexImpl(
-        BackingStore::cast(backing_store), index);
+                                              uint32_t index) {
+    return ElementsAccessorSubclass::GetKeyForIndex(
+        BackingStoreClass::cast(backing_store), index);
   }
 
  private:
@@ -602,87 +222,12 @@
 };
 
 
-// Super class for all fast element arrays.
-template<typename FastElementsAccessorSubclass,
-         typename KindTraits,
-         int ElementSize>
 class FastElementsAccessor
-    : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
+    : public ElementsAccessorBase<FastElementsAccessor, FixedArray> {
  public:
-  explicit FastElementsAccessor(const char* name)
-      : ElementsAccessorBase<FastElementsAccessorSubclass,
-                             KindTraits>(name) {}
- protected:
-  friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
-
-  typedef typename KindTraits::BackingStore BackingStore;
-
-  // Adjusts the length of the fast backing store or returns the new length or
-  // undefined in case conversion to a slow backing store should be performed.
-  static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store,
-                                                JSArray* array,
-                                                Object* length_object,
-                                                uint32_t length) {
-    uint32_t old_capacity = backing_store->length();
-
-    // Check whether the backing store should be shrunk.
-    if (length <= old_capacity) {
-      if (array->HasFastTypeElements()) {
-        MaybeObject* maybe_obj = array->EnsureWritableFastElements();
-        if (!maybe_obj->To(&backing_store)) return maybe_obj;
-      }
-      if (2 * length <= old_capacity) {
-        // If more than half the elements won't be used, trim the array.
-        if (length == 0) {
-          array->initialize_elements();
-        } else {
-          backing_store->set_length(length);
-          Address filler_start = backing_store->address() +
-              BackingStore::OffsetOfElementAt(length);
-          int filler_size = (old_capacity - length) * ElementSize;
-          array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
-        }
-      } else {
-        // Otherwise, fill the unused tail with holes.
-        int old_length = FastD2I(array->length()->Number());
-        for (int i = length; i < old_length; i++) {
-          backing_store->set_the_hole(i);
-        }
-      }
-      return length_object;
-    }
-
-    // Check whether the backing store should be expanded.
-    uint32_t min = JSObject::NewElementsCapacity(old_capacity);
-    uint32_t new_capacity = length > min ? length : min;
-    if (!array->ShouldConvertToSlowElements(new_capacity)) {
-      MaybeObject* result = FastElementsAccessorSubclass::
-          SetFastElementsCapacityAndLength(array, new_capacity, length);
-      if (result->IsFailure()) return result;
-      return length_object;
-    }
-
-    // Request conversion to slow elements.
-    return array->GetHeap()->undefined_value();
-  }
-};
-
-
-class FastObjectElementsAccessor
-    : public FastElementsAccessor<FastObjectElementsAccessor,
-                                  ElementsKindTraits<FAST_ELEMENTS>,
-                                  kPointerSize> {
- public:
-  explicit FastObjectElementsAccessor(const char* name)
-      : FastElementsAccessor<FastObjectElementsAccessor,
-                             ElementsKindTraits<FAST_ELEMENTS>,
-                             kPointerSize>(name) {}
-
   static MaybeObject* DeleteCommon(JSObject* obj,
                                    uint32_t key) {
-    ASSERT(obj->HasFastElements() ||
-           obj->HasFastSmiOnlyElements() ||
-           obj->HasFastArgumentsElements());
+    ASSERT(obj->HasFastElements() || obj->HasFastArgumentsElements());
     Heap* heap = obj->GetHeap();
     FixedArray* backing_store = FixedArray::cast(obj->elements());
     if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
@@ -724,49 +269,7 @@
     return heap->true_value();
   }
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
-    switch (to_kind) {
-      case FAST_SMI_ONLY_ELEMENTS:
-      case FAST_ELEMENTS: {
-        CopyObjectToObjectElements(
-            FixedArray::cast(from), ElementsTraits::Kind, from_start,
-            FixedArray::cast(to), to_kind, to_start, copy_size);
-        return from;
-      }
-      case FAST_DOUBLE_ELEMENTS:
-        CopyObjectToDoubleElements(
-            FixedArray::cast(from), from_start,
-            FixedDoubleArray::cast(to), to_start, copy_size);
-        return from;
-      default:
-        UNREACHABLE();
-    }
-    return to->GetHeap()->undefined_value();
-  }
-
-
-  static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
-                                                       uint32_t capacity,
-                                                       uint32_t length) {
-    JSObject::SetFastElementsCapacityMode set_capacity_mode =
-        obj->HasFastSmiOnlyElements()
-            ? JSObject::kAllowSmiOnlyElements
-            : JSObject::kDontAllowSmiOnlyElements;
-    return obj->SetFastElementsCapacityAndLength(capacity,
-                                                 length,
-                                                 set_capacity_mode);
-  }
-
  protected:
-  friend class FastElementsAccessor<FastObjectElementsAccessor,
-                                    ElementsKindTraits<FAST_ELEMENTS>,
-                                    kPointerSize>;
-
   virtual MaybeObject* Delete(JSObject* obj,
                               uint32_t key,
                               JSReceiver::DeleteMode mode) {
@@ -776,50 +279,11 @@
 
 
 class FastDoubleElementsAccessor
-    : public FastElementsAccessor<FastDoubleElementsAccessor,
-                                  ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
-                                  kDoubleSize> {
- public:
-  explicit FastDoubleElementsAccessor(const char* name)
-      : FastElementsAccessor<FastDoubleElementsAccessor,
-                             ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
-                             kDoubleSize>(name) {}
-
-  static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
-                                                       uint32_t capacity,
-                                                       uint32_t length) {
-    return obj->SetFastDoubleElementsCapacityAndLength(capacity, length);
-  }
-
+    : public ElementsAccessorBase<FastDoubleElementsAccessor,
+                                  FixedDoubleArray> {
  protected:
   friend class ElementsAccessorBase<FastDoubleElementsAccessor,
-                                    ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
-  friend class FastElementsAccessor<FastDoubleElementsAccessor,
-                                    ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
-                                    kDoubleSize>;
-
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
-    switch (to_kind) {
-      case FAST_SMI_ONLY_ELEMENTS:
-      case FAST_ELEMENTS:
-        return CopyDoubleToObjectElements(
-            FixedDoubleArray::cast(from), from_start, FixedArray::cast(to),
-            to_kind, to_start, copy_size);
-      case FAST_DOUBLE_ELEMENTS:
-        CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start,
-                                   FixedDoubleArray::cast(to),
-                                   to_start, copy_size);
-        return from;
-      default:
-        UNREACHABLE();
-    }
-    return to->GetHeap()->undefined_value();
-  }
+                                    FixedDoubleArray>;
 
   virtual MaybeObject* Delete(JSObject* obj,
                               uint32_t key,
@@ -833,49 +297,34 @@
     return obj->GetHeap()->true_value();
   }
 
-  static bool HasElementImpl(Object* receiver,
-                             JSObject* holder,
-                             uint32_t key,
-                             FixedDoubleArray* backing_store) {
-    return key < static_cast<uint32_t>(backing_store->length()) &&
-        !backing_store->is_the_hole(key);
+  static bool HasElementAtIndex(FixedDoubleArray* backing_store,
+                                uint32_t index,
+                                JSObject* holder,
+                                Object* receiver) {
+    return !backing_store->is_the_hole(index);
   }
 };
 
 
 // Super class for all external element arrays.
 template<typename ExternalElementsAccessorSubclass,
-         ElementsKind Kind>
+         typename ExternalArray>
 class ExternalElementsAccessor
     : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
-                                  ElementsKindTraits<Kind> > {
- public:
-  explicit ExternalElementsAccessor(const char* name)
-      : ElementsAccessorBase<ExternalElementsAccessorSubclass,
-                             ElementsKindTraits<Kind> >(name) {}
-
+                                  ExternalArray> {
  protected:
-  typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
-
   friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
-                                    ElementsKindTraits<Kind> >;
+                                    ExternalArray>;
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              BackingStore* backing_store) {
-    return
-        key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
-        ? backing_store->get(key)
-        : backing_store->GetHeap()->undefined_value();
-  }
-
-  static MaybeObject* SetLengthImpl(JSObject* obj,
-                                    Object* length,
-                                    BackingStore* backing_store) {
-    // External arrays do not support changing their length.
-    UNREACHABLE();
-    return obj;
+  static MaybeObject* Get(ExternalArray* backing_store,
+                          uint32_t key,
+                          JSObject* obj,
+                          Object* receiver) {
+    if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) {
+      return backing_store->get(key);
+    } else {
+      return backing_store->GetHeap()->undefined_value();
+    }
   }
 
   virtual MaybeObject* Delete(JSObject* obj,
@@ -884,173 +333,67 @@
     // External arrays always ignore deletes.
     return obj->GetHeap()->true_value();
   }
-
-  static bool HasElementImpl(Object* receiver,
-                             JSObject* holder,
-                             uint32_t key,
-                             BackingStore* backing_store) {
-    uint32_t capacity =
-        ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
-    return key < capacity;
-  }
 };
 
 
 class ExternalByteElementsAccessor
     : public ExternalElementsAccessor<ExternalByteElementsAccessor,
-                                      EXTERNAL_BYTE_ELEMENTS> {
- public:
-  explicit ExternalByteElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalByteElementsAccessor,
-                                 EXTERNAL_BYTE_ELEMENTS>(name) {}
+                                      ExternalByteArray> {
 };
 
 
 class ExternalUnsignedByteElementsAccessor
     : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor,
-                                      EXTERNAL_UNSIGNED_BYTE_ELEMENTS> {
- public:
-  explicit ExternalUnsignedByteElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor,
-                                 EXTERNAL_UNSIGNED_BYTE_ELEMENTS>(name) {}
+                                      ExternalUnsignedByteArray> {
 };
 
 
 class ExternalShortElementsAccessor
     : public ExternalElementsAccessor<ExternalShortElementsAccessor,
-                                      EXTERNAL_SHORT_ELEMENTS> {
- public:
-  explicit ExternalShortElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalShortElementsAccessor,
-                                 EXTERNAL_SHORT_ELEMENTS>(name) {}
+                                      ExternalShortArray> {
 };
 
 
 class ExternalUnsignedShortElementsAccessor
     : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor,
-                                      EXTERNAL_UNSIGNED_SHORT_ELEMENTS> {
- public:
-  explicit ExternalUnsignedShortElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor,
-                                 EXTERNAL_UNSIGNED_SHORT_ELEMENTS>(name) {}
+                                      ExternalUnsignedShortArray> {
 };
 
 
 class ExternalIntElementsAccessor
     : public ExternalElementsAccessor<ExternalIntElementsAccessor,
-                                      EXTERNAL_INT_ELEMENTS> {
- public:
-  explicit ExternalIntElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalIntElementsAccessor,
-                                 EXTERNAL_INT_ELEMENTS>(name) {}
+                                      ExternalIntArray> {
 };
 
 
 class ExternalUnsignedIntElementsAccessor
     : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor,
-                                      EXTERNAL_UNSIGNED_INT_ELEMENTS> {
- public:
-  explicit ExternalUnsignedIntElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor,
-                                 EXTERNAL_UNSIGNED_INT_ELEMENTS>(name) {}
+                                      ExternalUnsignedIntArray> {
 };
 
 
 class ExternalFloatElementsAccessor
     : public ExternalElementsAccessor<ExternalFloatElementsAccessor,
-                                      EXTERNAL_FLOAT_ELEMENTS> {
- public:
-  explicit ExternalFloatElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalFloatElementsAccessor,
-                                 EXTERNAL_FLOAT_ELEMENTS>(name) {}
+                                      ExternalFloatArray> {
 };
 
 
 class ExternalDoubleElementsAccessor
     : public ExternalElementsAccessor<ExternalDoubleElementsAccessor,
-                                      EXTERNAL_DOUBLE_ELEMENTS> {
- public:
-  explicit ExternalDoubleElementsAccessor(const char* name)
-      : ExternalElementsAccessor<ExternalDoubleElementsAccessor,
-                                 EXTERNAL_DOUBLE_ELEMENTS>(name) {}
+                                      ExternalDoubleArray> {
 };
 
 
 class PixelElementsAccessor
     : public ExternalElementsAccessor<PixelElementsAccessor,
-                                      EXTERNAL_PIXEL_ELEMENTS> {
- public:
-  explicit PixelElementsAccessor(const char* name)
-      : ExternalElementsAccessor<PixelElementsAccessor,
-                                 EXTERNAL_PIXEL_ELEMENTS>(name) {}
+                                      ExternalPixelArray> {
 };
 
 
 class DictionaryElementsAccessor
     : public ElementsAccessorBase<DictionaryElementsAccessor,
-                                  ElementsKindTraits<DICTIONARY_ELEMENTS> > {
+                                  SeededNumberDictionary> {
  public:
-  explicit DictionaryElementsAccessor(const char* name)
-      : ElementsAccessorBase<DictionaryElementsAccessor,
-                             ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
-
-  // Adjusts the length of the dictionary backing store and returns the new
-  // length according to ES5 section 15.4.5.2 behavior.
-  static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict,
-                                                JSArray* array,
-                                                Object* length_object,
-                                                uint32_t length) {
-    if (length == 0) {
-      // If the length of a slow array is reset to zero, we clear
-      // the array and flush backing storage. This has the added
-      // benefit that the array returns to fast mode.
-      Object* obj;
-      MaybeObject* maybe_obj = array->ResetElements();
-      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-    } else {
-      uint32_t new_length = length;
-      uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
-      if (new_length < old_length) {
-        // Find last non-deletable element in range of elements to be
-        // deleted and adjust range accordingly.
-        Heap* heap = array->GetHeap();
-        int capacity = dict->Capacity();
-        for (int i = 0; i < capacity; i++) {
-          Object* key = dict->KeyAt(i);
-          if (key->IsNumber()) {
-            uint32_t number = static_cast<uint32_t>(key->Number());
-            if (new_length <= number && number < old_length) {
-              PropertyDetails details = dict->DetailsAt(i);
-              if (details.IsDontDelete()) new_length = number + 1;
-            }
-          }
-        }
-        if (new_length != length) {
-          MaybeObject* maybe_object = heap->NumberFromUint32(new_length);
-          if (!maybe_object->To(&length_object)) return maybe_object;
-        }
-
-        // Remove elements that should be deleted.
-        int removed_entries = 0;
-        Object* the_hole_value = heap->the_hole_value();
-        for (int i = 0; i < capacity; i++) {
-          Object* key = dict->KeyAt(i);
-          if (key->IsNumber()) {
-            uint32_t number = static_cast<uint32_t>(key->Number());
-            if (new_length <= number && number < old_length) {
-              dict->SetEntry(i, the_hole_value, the_hole_value);
-              removed_entries++;
-            }
-          }
-        }
-
-        // Update the number of elements.
-        dict->ElementsRemoved(removed_entries);
-      }
-    }
-    return length_object;
-  }
-
   static MaybeObject* DeleteCommon(JSObject* obj,
                                    uint32_t key,
                                    JSReceiver::DeleteMode mode) {
@@ -1096,34 +439,9 @@
     return heap->true_value();
   }
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
-    switch (to_kind) {
-      case FAST_SMI_ONLY_ELEMENTS:
-      case FAST_ELEMENTS:
-        CopyDictionaryToObjectElements(
-            SeededNumberDictionary::cast(from), from_start,
-            FixedArray::cast(to), to_kind, to_start, copy_size);
-        return from;
-      case FAST_DOUBLE_ELEMENTS:
-        CopyDictionaryToDoubleElements(
-            SeededNumberDictionary::cast(from), from_start,
-            FixedDoubleArray::cast(to), to_start, copy_size);
-        return from;
-      default:
-        UNREACHABLE();
-    }
-    return to->GetHeap()->undefined_value();
-  }
-
-
  protected:
   friend class ElementsAccessorBase<DictionaryElementsAccessor,
-                                    ElementsKindTraits<DICTIONARY_ELEMENTS> >;
+                                    SeededNumberDictionary>;
 
   virtual MaybeObject* Delete(JSObject* obj,
                               uint32_t key,
@@ -1131,10 +449,10 @@
     return DeleteCommon(obj, key, mode);
   }
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              SeededNumberDictionary* backing_store) {
+  static MaybeObject* Get(SeededNumberDictionary* backing_store,
+                          uint32_t key,
+                          JSObject* obj,
+                          Object* receiver) {
     int entry = backing_store->FindEntry(key);
     if (entry != SeededNumberDictionary::kNotFound) {
       Object* element = backing_store->ValueAt(entry);
@@ -1151,40 +469,26 @@
     return obj->GetHeap()->the_hole_value();
   }
 
-  static bool HasElementImpl(Object* receiver,
-                             JSObject* holder,
-                             uint32_t key,
-                             SeededNumberDictionary* backing_store) {
-    return backing_store->FindEntry(key) !=
-        SeededNumberDictionary::kNotFound;
-  }
-
-  static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
-                                     uint32_t index) {
+  static uint32_t GetKeyForIndex(SeededNumberDictionary* dict,
+                                 uint32_t index) {
     Object* key = dict->KeyAt(index);
     return Smi::cast(key)->value();
   }
 };
 
 
-class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
-    NonStrictArgumentsElementsAccessor,
-    ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > {
- public:
-  explicit NonStrictArgumentsElementsAccessor(const char* name)
-      : ElementsAccessorBase<
-          NonStrictArgumentsElementsAccessor,
-          ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {}
+class NonStrictArgumentsElementsAccessor
+    : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
+                                  FixedArray> {
  protected:
-  friend class ElementsAccessorBase<
-      NonStrictArgumentsElementsAccessor,
-      ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
+  friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
+                                    FixedArray>;
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              FixedArray* parameter_map) {
-    Object* probe = GetParameterMapArg(obj, parameter_map, key);
+  static MaybeObject* Get(FixedArray* parameter_map,
+                          uint32_t key,
+                          JSObject* obj,
+                          Object* receiver) {
+    Object* probe = GetParameterMapArg(parameter_map, key);
     if (!probe->IsTheHole()) {
       Context* context = Context::cast(parameter_map->get(0));
       int context_index = Smi::cast(probe)->value();
@@ -1193,37 +497,19 @@
     } else {
       // Object is not mapped, defer to the arguments.
       FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
-      MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
-          receiver, obj, key, arguments);
-      Object* result;
-      if (!maybe_result->ToObject(&result)) return maybe_result;
-      // Elements of the arguments object in slow mode might be slow aliases.
-      if (result->IsAliasedArgumentsEntry()) {
-        AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(result);
-        Context* context = Context::cast(parameter_map->get(0));
-        int context_index = entry->aliased_context_slot();
-        ASSERT(!context->get(context_index)->IsTheHole());
-        return context->get(context_index);
-      } else {
-        return result;
-      }
+      return ElementsAccessor::ForArray(arguments)->Get(arguments,
+                                                        key,
+                                                        obj,
+                                                        receiver);
     }
   }
 
-  static MaybeObject* SetLengthImpl(JSObject* obj,
-                                    Object* length,
-                                    FixedArray* parameter_map) {
-    // TODO(mstarzinger): This was never implemented but will be used once we
-    // correctly implement [[DefineOwnProperty]] on arrays.
-    UNIMPLEMENTED();
-    return obj;
-  }
-
   virtual MaybeObject* Delete(JSObject* obj,
-                              uint32_t key,
+                              uint32_t key
+                              ,
                               JSReceiver::DeleteMode mode) {
     FixedArray* parameter_map = FixedArray::cast(obj->elements());
-    Object* probe = GetParameterMapArg(obj, parameter_map, key);
+    Object* probe = GetParameterMapArg(parameter_map, key);
     if (!probe->IsTheHole()) {
       // TODO(kmillikin): We could check if this was the last aliased
       // parameter, and revert to normal elements in that case.  That
@@ -1234,57 +520,41 @@
       if (arguments->IsDictionary()) {
         return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
       } else {
-        return FastObjectElementsAccessor::DeleteCommon(obj, key);
+        return FastElementsAccessor::DeleteCommon(obj, key);
       }
     }
     return obj->GetHeap()->true_value();
   }
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
-    FixedArray* parameter_map = FixedArray::cast(from);
-    FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
-    ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
-    return accessor->CopyElements(NULL, from_start, to, to_kind,
-                                  to_start, copy_size, arguments);
-  }
-
-  static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
+  static uint32_t GetCapacity(FixedArray* parameter_map) {
     FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
     return Max(static_cast<uint32_t>(parameter_map->length() - 2),
                ForArray(arguments)->GetCapacity(arguments));
   }
 
-  static uint32_t GetKeyForIndexImpl(FixedArray* dict,
-                                     uint32_t index) {
+  static uint32_t GetKeyForIndex(FixedArray* dict,
+                                 uint32_t index) {
     return index;
   }
 
-  static bool HasElementImpl(Object* receiver,
-                             JSObject* holder,
-                             uint32_t key,
-                             FixedArray* parameter_map) {
-    Object* probe = GetParameterMapArg(holder, parameter_map, key);
+  static bool HasElementAtIndex(FixedArray* parameter_map,
+                                uint32_t index,
+                                JSObject* holder,
+                                Object* receiver) {
+    Object* probe = GetParameterMapArg(parameter_map, index);
     if (!probe->IsTheHole()) {
       return true;
     } else {
       FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
       ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
-      return !accessor->Get(receiver, holder, key, arguments)->IsTheHole();
+      return !accessor->Get(arguments, index, holder, receiver)->IsTheHole();
     }
   }
 
  private:
-  static Object* GetParameterMapArg(JSObject* holder,
-                                    FixedArray* parameter_map,
+  static Object* GetParameterMapArg(FixedArray* parameter_map,
                                     uint32_t key) {
-    uint32_t length = holder->IsJSArray()
-        ? Smi::cast(JSArray::cast(holder)->length())->value()
-        : parameter_map->length();
+    uint32_t length = parameter_map->length();
     return key < (length - 2 )
         ? parameter_map->get(key + 2)
         : parameter_map->GetHeap()->the_hole_value();
@@ -1327,87 +597,39 @@
 
 void ElementsAccessor::InitializeOncePerProcess() {
   static struct ConcreteElementsAccessors {
-#define ACCESSOR_STRUCT(Class, Kind, Store) Class* Kind##_handler;
-    ELEMENTS_LIST(ACCESSOR_STRUCT)
-#undef ACCESSOR_STRUCT
-  } element_accessors = {
-#define ACCESSOR_INIT(Class, Kind, Store) new Class(#Kind),
-    ELEMENTS_LIST(ACCESSOR_INIT)
-#undef ACCESSOR_INIT
-  };
+    FastElementsAccessor fast_elements_handler;
+    FastDoubleElementsAccessor fast_double_elements_handler;
+    DictionaryElementsAccessor dictionary_elements_handler;
+    NonStrictArgumentsElementsAccessor non_strict_arguments_elements_handler;
+    ExternalByteElementsAccessor byte_elements_handler;
+    ExternalUnsignedByteElementsAccessor unsigned_byte_elements_handler;
+    ExternalShortElementsAccessor short_elements_handler;
+    ExternalUnsignedShortElementsAccessor unsigned_short_elements_handler;
+    ExternalIntElementsAccessor int_elements_handler;
+    ExternalUnsignedIntElementsAccessor unsigned_int_elements_handler;
+    ExternalFloatElementsAccessor float_elements_handler;
+    ExternalDoubleElementsAccessor double_elements_handler;
+    PixelElementsAccessor pixel_elements_handler;
+  } element_accessors;
 
   static ElementsAccessor* accessor_array[] = {
-#define ACCESSOR_ARRAY(Class, Kind, Store) element_accessors.Kind##_handler,
-    ELEMENTS_LIST(ACCESSOR_ARRAY)
-#undef ACCESSOR_ARRAY
+    &element_accessors.fast_elements_handler,
+    &element_accessors.fast_double_elements_handler,
+    &element_accessors.dictionary_elements_handler,
+    &element_accessors.non_strict_arguments_elements_handler,
+    &element_accessors.byte_elements_handler,
+    &element_accessors.unsigned_byte_elements_handler,
+    &element_accessors.short_elements_handler,
+    &element_accessors.unsigned_short_elements_handler,
+    &element_accessors.int_elements_handler,
+    &element_accessors.unsigned_int_elements_handler,
+    &element_accessors.float_elements_handler,
+    &element_accessors.double_elements_handler,
+    &element_accessors.pixel_elements_handler
   };
 
-  STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) ==
-                kElementsKindCount);
-
   elements_accessors_ = accessor_array;
 }
 
 
-template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
-MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
-                                  ElementsKindTraits>::
-    SetLengthImpl(JSObject* obj,
-                  Object* length,
-                  typename ElementsKindTraits::BackingStore* backing_store) {
-  JSArray* array = JSArray::cast(obj);
-
-  // Fast case: The new length fits into a Smi.
-  MaybeObject* maybe_smi_length = length->ToSmi();
-  Object* smi_length = Smi::FromInt(0);
-  if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
-    const int value = Smi::cast(smi_length)->value();
-    if (value >= 0) {
-      Object* new_length;
-      MaybeObject* result = ElementsAccessorSubclass::
-          SetLengthWithoutNormalize(backing_store, array, smi_length, value);
-      if (!result->ToObject(&new_length)) return result;
-      ASSERT(new_length->IsSmi() || new_length->IsUndefined());
-      if (new_length->IsSmi()) {
-        array->set_length(Smi::cast(new_length));
-        return array;
-      }
-    } else {
-      return ThrowArrayLengthRangeError(array->GetHeap());
-    }
-  }
-
-  // Slow case: The new length does not fit into a Smi or conversion
-  // to slow elements is needed for other reasons.
-  if (length->IsNumber()) {
-    uint32_t value;
-    if (length->ToArrayIndex(&value)) {
-      SeededNumberDictionary* dictionary;
-      MaybeObject* maybe_object = array->NormalizeElements();
-      if (!maybe_object->To(&dictionary)) return maybe_object;
-      Object* new_length;
-      MaybeObject* result = DictionaryElementsAccessor::
-          SetLengthWithoutNormalize(dictionary, array, length, value);
-      if (!result->ToObject(&new_length)) return result;
-      ASSERT(new_length->IsNumber());
-      array->set_length(new_length);
-      return array;
-    } else {
-      return ThrowArrayLengthRangeError(array->GetHeap());
-    }
-  }
-
-  // Fall-back case: The new length is not a number so make the array
-  // size one and set only element to length.
-  FixedArray* new_backing_store;
-  MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1);
-  if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
-  new_backing_store->set(0, length);
-  { MaybeObject* result = array->SetContent(new_backing_store);
-    if (result->IsFailure()) return result;
-  }
-  return array;
-}
-
-
 } }  // namespace v8::internal