Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index ae5c7de04ac55712be64baf6e69be7b546934b29..cf2853c6cdc438f95420874d05b3fa557e472a45 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -146,33 +146,36 @@ static Failure* ThrowArrayLengthRangeError(Heap* heap) { |
} |
-static void CopyObjectToObjectElements(FixedArray* from, |
+static void CopyObjectToObjectElements(FixedArrayBase* from_base, |
ElementsKind from_kind, |
uint32_t from_start, |
- FixedArray* to, |
+ FixedArrayBase* to_base, |
ElementsKind to_kind, |
uint32_t to_start, |
int raw_copy_size) { |
- ASSERT(to->map() != HEAP->fixed_cow_array_map()); |
+ ASSERT(to_base->map() != HEAP->fixed_cow_array_map()); |
AssertNoAllocation no_allocation; |
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); |
+ copy_size = Min(from_base->length() - from_start, |
+ to_base->length() - to_start); |
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
int start = to_start + copy_size; |
- int length = to->length() - start; |
+ int length = to_base->length() - start; |
if (length > 0) { |
- Heap* heap = from->GetHeap(); |
- MemsetPointer(to->data_start() + start, heap->the_hole_value(), length); |
+ Heap* heap = from_base->GetHeap(); |
+ MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
+ heap->the_hole_value(), length); |
} |
} |
} |
- ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
- (copy_size + static_cast<int>(from_start)) <= from->length()); |
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
+ (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
if (copy_size == 0) return; |
+ FixedArray* from = FixedArray::cast(from_base); |
+ FixedArray* to = FixedArray::cast(to_base); |
ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); |
ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
Address to_address = to->address() + FixedArray::kHeaderSize; |
@@ -193,12 +196,13 @@ static void CopyObjectToObjectElements(FixedArray* from, |
} |
-static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, |
+static void CopyDictionaryToObjectElements(FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedArray* to, |
+ FixedArrayBase* to_base, |
ElementsKind to_kind, |
uint32_t to_start, |
int raw_copy_size) { |
+ SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); |
AssertNoAllocation no_allocation; |
int copy_size = raw_copy_size; |
Heap* heap = from->GetHeap(); |
@@ -208,16 +212,18 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, |
copy_size = from->max_number_key() + 1 - from_start; |
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
int start = to_start + copy_size; |
- int length = to->length() - start; |
+ int length = to_base->length() - start; |
if (length > 0) { |
Heap* heap = from->GetHeap(); |
- MemsetPointer(to->data_start() + start, heap->the_hole_value(), length); |
+ MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
+ heap->the_hole_value(), length); |
} |
} |
} |
- ASSERT(to != from); |
+ ASSERT(to_base != from_base); |
ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
if (copy_size == 0) return; |
+ FixedArray* to = FixedArray::cast(to_base); |
uint32_t to_length = to->length(); |
if (to_start + copy_size > to_length) { |
copy_size = to_length - to_start; |
@@ -244,9 +250,9 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, |
MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
- FixedDoubleArray* from, |
+ FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedArray* to, |
+ FixedArrayBase* to_base, |
ElementsKind to_kind, |
uint32_t to_start, |
int raw_copy_size) { |
@@ -255,23 +261,26 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
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); |
+ copy_size = Min(from_base->length() - from_start, |
+ to_base->length() - to_start); |
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
// Also initialize the area that will be copied over since HeapNumber |
// allocation below can cause an incremental marking step, requiring all |
// existing heap objects to be propertly initialized. |
int start = to_start; |
- int length = to->length() - start; |
+ int length = to_base->length() - start; |
if (length > 0) { |
- Heap* heap = from->GetHeap(); |
- MemsetPointer(to->data_start() + start, heap->the_hole_value(), length); |
+ Heap* heap = from_base->GetHeap(); |
+ MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
+ heap->the_hole_value(), length); |
} |
} |
} |
- 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; |
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
+ (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
+ if (copy_size == 0) return from_base; |
+ FixedDoubleArray* from = FixedDoubleArray::cast(from_base); |
+ FixedArray* to = FixedArray::cast(to_base); |
for (int i = 0; i < copy_size; ++i) { |
if (IsFastSmiElementsKind(to_kind)) { |
UNIMPLEMENTED(); |
@@ -300,26 +309,28 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
} |
-static void CopyDoubleToDoubleElements(FixedDoubleArray* from, |
+static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedDoubleArray* to, |
+ FixedArrayBase* to_base, |
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); |
+ copy_size = Min(from_base->length() - from_start, |
+ to_base->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); |
+ for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
+ FixedDoubleArray::cast(to_base)->set_the_hole(i); |
} |
} |
} |
- ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
- (copy_size + static_cast<int>(from_start)) <= from->length()); |
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
+ (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
if (copy_size == 0) return; |
+ FixedDoubleArray* from = FixedDoubleArray::cast(from_base); |
+ FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
to_address += kDoubleSize * to_start; |
@@ -331,25 +342,27 @@ static void CopyDoubleToDoubleElements(FixedDoubleArray* from, |
} |
-static void CopySmiToDoubleElements(FixedArray* from, |
+static void CopySmiToDoubleElements(FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedDoubleArray* to, |
+ FixedArrayBase* to_base, |
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; |
+ copy_size = from_base->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); |
+ for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
+ FixedDoubleArray::cast(to_base)->set_the_hole(i); |
} |
} |
} |
- ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
- (copy_size + static_cast<int>(from_start)) <= from->length()); |
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
+ (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
if (copy_size == 0) return; |
+ FixedArray* from = FixedArray::cast(from_base); |
+ FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
Object* the_hole = from->GetHeap()->the_hole_value(); |
for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); |
from_start < from_end; from_start++, to_start++) { |
@@ -363,9 +376,9 @@ static void CopySmiToDoubleElements(FixedArray* from, |
} |
-static void CopyPackedSmiToDoubleElements(FixedArray* from, |
+static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedDoubleArray* to, |
+ FixedArrayBase* to_base, |
uint32_t to_start, |
int packed_size, |
int raw_copy_size) { |
@@ -374,11 +387,11 @@ static void CopyPackedSmiToDoubleElements(FixedArray* from, |
if (raw_copy_size < 0) { |
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
- copy_size = from->length() - from_start; |
+ copy_size = from_base->length() - from_start; |
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
- to_end = to->length(); |
+ to_end = to_base->length(); |
for (uint32_t i = to_start + copy_size; i < to_end; ++i) { |
- to->set_the_hole(i); |
+ FixedDoubleArray::cast(to_base)->set_the_hole(i); |
} |
} else { |
to_end = to_start + static_cast<uint32_t>(copy_size); |
@@ -386,11 +399,13 @@ static void CopyPackedSmiToDoubleElements(FixedArray* from, |
} else { |
to_end = to_start + static_cast<uint32_t>(copy_size); |
} |
- ASSERT(static_cast<int>(to_end) <= to->length()); |
+ ASSERT(static_cast<int>(to_end) <= to_base->length()); |
ASSERT(packed_size >= 0 && packed_size <= copy_size); |
- ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
- (copy_size + static_cast<int>(from_start)) <= from->length()); |
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
+ (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
if (copy_size == 0) return; |
+ FixedArray* from = FixedArray::cast(from_base); |
+ FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
from_start < from_end; from_start++, to_start++) { |
Object* smi = from->get(from_start); |
@@ -400,25 +415,27 @@ static void CopyPackedSmiToDoubleElements(FixedArray* from, |
} |
-static void CopyObjectToDoubleElements(FixedArray* from, |
+static void CopyObjectToDoubleElements(FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedDoubleArray* to, |
+ FixedArrayBase* to_base, |
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; |
+ copy_size = from_base->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); |
+ for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
+ FixedDoubleArray::cast(to_base)->set_the_hole(i); |
} |
} |
} |
- ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
- (copy_size + static_cast<int>(from_start)) <= from->length()); |
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
+ (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
if (copy_size == 0) return; |
+ FixedArray* from = FixedArray::cast(from_base); |
+ FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
Object* the_hole = from->GetHeap()->the_hole_value(); |
for (uint32_t from_end = from_start + copy_size; |
from_start < from_end; from_start++, to_start++) { |
@@ -432,23 +449,25 @@ static void CopyObjectToDoubleElements(FixedArray* from, |
} |
-static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, |
+static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base, |
uint32_t from_start, |
- FixedDoubleArray* to, |
+ FixedArrayBase* to_base, |
uint32_t to_start, |
int raw_copy_size) { |
+ SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); |
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); |
+ for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
+ FixedDoubleArray::cast(to_base)->set_the_hole(i); |
} |
} |
} |
if (copy_size == 0) return; |
+ FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
uint32_t to_length = to->length(); |
if (to_start + copy_size > to_length) { |
copy_size = to_length - to_start; |
@@ -541,7 +560,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
backing_store = holder->elements(); |
} |
return ElementsAccessorSubclass::HasElementImpl( |
- receiver, holder, key, BackingStore::cast(backing_store)); |
+ receiver, holder, key, backing_store); |
} |
MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver, |
@@ -552,15 +571,15 @@ class ElementsAccessorBase : public ElementsAccessor { |
backing_store = holder->elements(); |
} |
return ElementsAccessorSubclass::GetImpl( |
- receiver, holder, key, BackingStore::cast(backing_store)); |
+ receiver, holder, key, backing_store); |
} |
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
JSObject* obj, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) |
- ? backing_store->get(key) |
+ ? BackingStore::cast(backing_store)->get(key) |
: backing_store->GetHeap()->the_hole_value(); |
} |
@@ -596,18 +615,19 @@ class ElementsAccessorBase : public ElementsAccessor { |
backing_store = holder->elements(); |
} |
return ElementsAccessorSubclass::GetTypeImpl( |
- receiver, holder, key, BackingStore::cast(backing_store)); |
+ receiver, holder, key, backing_store); |
} |
MUST_USE_RESULT static PropertyType GetTypeImpl( |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
return NONEXISTENT; |
} |
- return backing_store->is_the_hole(key) ? NONEXISTENT : FIELD; |
+ return BackingStore::cast(backing_store)->is_the_hole(key) |
+ ? NONEXISTENT : FIELD; |
} |
MUST_USE_RESULT virtual AccessorPair* GetAccessorPair( |
@@ -619,27 +639,27 @@ class ElementsAccessorBase : public ElementsAccessor { |
backing_store = holder->elements(); |
} |
return ElementsAccessorSubclass::GetAccessorPairImpl( |
- receiver, holder, key, BackingStore::cast(backing_store)); |
+ receiver, holder, key, backing_store); |
} |
MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
return NULL; |
} |
MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array, |
Object* length) { |
return ElementsAccessorSubclass::SetLengthImpl( |
- array, length, BackingStore::cast(array->elements())); |
+ array, length, array->elements()); |
} |
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
JSObject* obj, |
Object* length, |
- BackingStore* backing_store); |
+ FixedArrayBase* backing_store); |
MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength( |
JSArray* array, |
@@ -666,7 +686,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
uint32_t from_start, |
FixedArrayBase* to, |
- ElementsKind to_kind, |
+ ElementsKind from_kind, |
uint32_t to_start, |
int packed_size, |
int copy_size) { |
@@ -677,7 +697,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder, |
uint32_t from_start, |
FixedArrayBase* to, |
- ElementsKind to_kind, |
+ ElementsKind from_kind, |
uint32_t to_start, |
int copy_size, |
FixedArrayBase* from) { |
@@ -687,8 +707,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
} |
if (from_holder) { |
- ElementsKind elements_kind = from_holder->GetElementsKind(); |
- bool is_packed = IsFastPackedElementsKind(elements_kind) && |
+ bool is_packed = IsFastPackedElementsKind(from_kind) && |
from_holder->IsJSArray(); |
if (is_packed) { |
packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value(); |
@@ -698,7 +717,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
} |
} |
return ElementsAccessorSubclass::CopyElementsImpl( |
- from, from_start, to, to_kind, to_start, packed_size, copy_size); |
+ from, from_start, to, from_kind, to_start, packed_size, copy_size); |
} |
MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( |
@@ -717,25 +736,22 @@ class ElementsAccessorBase : public ElementsAccessor { |
if (from == NULL) { |
from = holder->elements(); |
} |
- BackingStore* backing_store = BackingStore::cast(from); |
- uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
// Optimize if 'other' is empty. |
// We cannot optimize if 'this' is empty, as other may have holes. |
+ uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); |
if (len1 == 0) return to; |
// Compute how many elements are not in other. |
uint32_t extra = 0; |
for (uint32_t y = 0; y < len1; y++) { |
- uint32_t key = |
- ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
+ uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
if (ElementsAccessorSubclass::HasElementImpl( |
- receiver, holder, key, backing_store)) { |
+ receiver, holder, key, from)) { |
MaybeObject* maybe_value = |
- ElementsAccessorSubclass::GetImpl(receiver, holder, |
- key, backing_store); |
+ ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
Object* value; |
- if (!maybe_value->ToObject(&value)) return maybe_value; |
+ if (!maybe_value->To(&value)) return maybe_value; |
ASSERT(!value->IsTheHole()); |
if (!HasKey(to, value)) { |
extra++; |
@@ -747,9 +763,8 @@ class ElementsAccessorBase : public ElementsAccessor { |
// Allocate the result |
FixedArray* result; |
- MaybeObject* maybe_obj = |
- backing_store->GetHeap()->AllocateFixedArray(len0 + extra); |
- if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj; |
+ MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra); |
+ if (!maybe_obj->To(&result)) return maybe_obj; |
// Fill in the content |
{ |
@@ -765,14 +780,13 @@ class ElementsAccessorBase : public ElementsAccessor { |
uint32_t index = 0; |
for (uint32_t y = 0; y < len1; y++) { |
uint32_t key = |
- ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
+ ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
if (ElementsAccessorSubclass::HasElementImpl( |
- receiver, holder, key, backing_store)) { |
+ receiver, holder, key, from)) { |
MaybeObject* maybe_value = |
- ElementsAccessorSubclass::GetImpl(receiver, holder, |
- key, backing_store); |
+ ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
Object* value; |
- if (!maybe_value->ToObject(&value)) return maybe_value; |
+ if (!maybe_value->To(&value)) return maybe_value; |
if (!value->IsTheHole() && !HasKey(to, value)) { |
result->set(len0 + index, value); |
index++; |
@@ -792,15 +806,14 @@ class ElementsAccessorBase : public ElementsAccessor { |
return ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
} |
- static uint32_t GetKeyForIndexImpl(BackingStore* backing_store, |
+ static uint32_t GetKeyForIndexImpl(FixedArrayBase* 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); |
+ return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
} |
private: |
@@ -826,7 +839,7 @@ class FastElementsAccessor |
// 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, |
+ static MaybeObject* SetLengthWithoutNormalize(FixedArrayBase* backing_store, |
JSArray* array, |
Object* length_object, |
uint32_t length) { |
@@ -864,7 +877,7 @@ class FastElementsAccessor |
// Otherwise, fill the unused tail with holes. |
int old_length = FastD2IChecked(array->length()->Number()); |
for (int i = length; i < old_length; i++) { |
- backing_store->set_the_hole(i); |
+ BackingStore::cast(backing_store)->set_the_hole(i); |
} |
} |
return length_object; |
@@ -901,9 +914,8 @@ class FastElementsAccessor |
bool is_non_strict_arguments_elements_map = |
backing_store->map() == heap->non_strict_arguments_elements_map(); |
if (is_non_strict_arguments_elements_map) { |
- backing_store = |
- KindTraits::BackingStore::cast( |
- FixedArray::cast(backing_store)->get(1)); |
+ backing_store = KindTraits::BackingStore::cast( |
+ FixedArray::cast(backing_store)->get(1)); |
} |
uint32_t length = static_cast<uint32_t>( |
obj->IsJSArray() |
@@ -959,11 +971,11 @@ class FastElementsAccessor |
Object* receiver, |
JSObject* holder, |
uint32_t key, |
- typename KindTraits::BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
if (key >= static_cast<uint32_t>(backing_store->length())) { |
return false; |
} |
- return !backing_store->is_the_hole(key); |
+ return !BackingStore::cast(backing_store)->is_the_hole(key); |
} |
static void ValidateContents(JSObject* holder, int length) { |
@@ -990,6 +1002,41 @@ class FastElementsAccessor |
}; |
+static ElementsKind ElementsKindForArray(FixedArrayBase* array) { |
+ switch (array->map()->instance_type()) { |
+ case FIXED_ARRAY_TYPE: |
+ if (array->IsDictionary()) { |
+ return DICTIONARY_ELEMENTS; |
+ } else { |
+ return FAST_HOLEY_ELEMENTS; |
+ } |
+ case FIXED_DOUBLE_ARRAY_TYPE: |
+ return FAST_HOLEY_DOUBLE_ELEMENTS; |
+ case EXTERNAL_BYTE_ARRAY_TYPE: |
+ return EXTERNAL_BYTE_ELEMENTS; |
+ case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: |
+ return EXTERNAL_UNSIGNED_BYTE_ELEMENTS; |
+ case EXTERNAL_SHORT_ARRAY_TYPE: |
+ return EXTERNAL_SHORT_ELEMENTS; |
+ case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: |
+ return EXTERNAL_UNSIGNED_SHORT_ELEMENTS; |
+ case EXTERNAL_INT_ARRAY_TYPE: |
+ return EXTERNAL_INT_ELEMENTS; |
+ case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: |
+ return EXTERNAL_UNSIGNED_INT_ELEMENTS; |
+ case EXTERNAL_FLOAT_ARRAY_TYPE: |
+ return EXTERNAL_FLOAT_ELEMENTS; |
+ case EXTERNAL_DOUBLE_ARRAY_TYPE: |
+ return EXTERNAL_DOUBLE_ELEMENTS; |
+ case EXTERNAL_PIXEL_ARRAY_TYPE: |
+ return EXTERNAL_PIXEL_ELEMENTS; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ return FAST_HOLEY_ELEMENTS; |
+} |
+ |
+ |
template<typename FastElementsAccessorSubclass, |
typename KindTraits> |
class FastSmiOrObjectElementsAccessor |
@@ -1005,36 +1052,49 @@ class FastSmiOrObjectElementsAccessor |
static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
uint32_t from_start, |
FixedArrayBase* to, |
- ElementsKind to_kind, |
+ ElementsKind from_kind, |
uint32_t to_start, |
int packed_size, |
int copy_size) { |
- if (IsFastSmiOrObjectElementsKind(to_kind)) { |
- CopyObjectToObjectElements( |
- FixedArray::cast(from), KindTraits::Kind, from_start, |
- FixedArray::cast(to), to_kind, to_start, copy_size); |
- } else if (IsFastDoubleElementsKind(to_kind)) { |
- if (IsFastSmiElementsKind(KindTraits::Kind)) { |
- if (IsFastPackedElementsKind(KindTraits::Kind) && |
- packed_size != kPackedSizeNotKnown) { |
- CopyPackedSmiToDoubleElements( |
- FixedArray::cast(from), from_start, |
- FixedDoubleArray::castOrEmptyFixedArray(to), to_start, |
- packed_size, copy_size); |
- } else { |
- CopySmiToDoubleElements( |
- FixedArray::cast(from), from_start, |
- FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size); |
- } |
- } else { |
- CopyObjectToDoubleElements( |
- FixedArray::cast(from), from_start, |
- FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size); |
+ ElementsKind to_kind = KindTraits::Kind; |
+ switch (from_kind) { |
+ case FAST_SMI_ELEMENTS: |
+ case FAST_HOLEY_SMI_ELEMENTS: |
+ case FAST_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ CopyObjectToObjectElements( |
+ from, from_kind, from_start, to, to_kind, to_start, copy_size); |
+ return to->GetHeap()->undefined_value(); |
+ case FAST_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_DOUBLE_ELEMENTS: |
+ return CopyDoubleToObjectElements( |
+ from, from_start, to, to_kind, to_start, copy_size); |
+ case DICTIONARY_ELEMENTS: |
+ CopyDictionaryToObjectElements( |
+ from, from_start, to, to_kind, to_start, copy_size); |
+ return to->GetHeap()->undefined_value(); |
+ case NON_STRICT_ARGUMENTS_ELEMENTS: { |
+ // TODO(verwaest): This is a temporary hack to support extending |
+ // NON_STRICT_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. |
+ // This case should be UNREACHABLE(). |
+ FixedArray* parameter_map = FixedArray::cast(from); |
+ FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
+ ElementsKind from_kind = ElementsKindForArray(arguments); |
+ return CopyElementsImpl(arguments, from_start, to, from_kind, |
+ to_start, packed_size, copy_size); |
} |
- } else { |
- UNREACHABLE(); |
+ case EXTERNAL_BYTE_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
+ case EXTERNAL_SHORT_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
+ case EXTERNAL_INT_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
+ case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_DOUBLE_ELEMENTS: |
+ case EXTERNAL_PIXEL_ELEMENTS: |
+ UNREACHABLE(); |
} |
- return to->GetHeap()->undefined_value(); |
+ return NULL; |
} |
@@ -1123,25 +1183,40 @@ class FastDoubleElementsAccessor |
static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
uint32_t from_start, |
FixedArrayBase* to, |
- ElementsKind to_kind, |
+ ElementsKind from_kind, |
uint32_t to_start, |
int packed_size, |
int copy_size) { |
- switch (to_kind) { |
+ switch (from_kind) { |
case FAST_SMI_ELEMENTS: |
- case FAST_ELEMENTS: |
+ CopyPackedSmiToDoubleElements( |
+ from, from_start, to, to_start, packed_size, copy_size); |
+ break; |
case FAST_HOLEY_SMI_ELEMENTS: |
- case FAST_HOLEY_ELEMENTS: |
- return CopyDoubleToObjectElements( |
- FixedDoubleArray::castOrEmptyFixedArray(from), from_start, |
- FixedArray::cast(to), to_kind, to_start, copy_size); |
+ CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); |
+ break; |
case FAST_DOUBLE_ELEMENTS: |
case FAST_HOLEY_DOUBLE_ELEMENTS: |
- CopyDoubleToDoubleElements( |
- FixedDoubleArray::castOrEmptyFixedArray(from), from_start, |
- FixedDoubleArray::castOrEmptyFixedArray(to), to_start, copy_size); |
- return from; |
- default: |
+ CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size); |
+ break; |
+ case FAST_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); |
+ break; |
+ case DICTIONARY_ELEMENTS: |
+ CopyDictionaryToDoubleElements( |
+ from, from_start, to, to_start, copy_size); |
+ break; |
+ case NON_STRICT_ARGUMENTS_ELEMENTS: |
+ case EXTERNAL_BYTE_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
+ case EXTERNAL_SHORT_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
+ case EXTERNAL_INT_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
+ case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_DOUBLE_ELEMENTS: |
+ case EXTERNAL_PIXEL_ELEMENTS: |
UNREACHABLE(); |
} |
return to->GetHeap()->undefined_value(); |
@@ -1198,10 +1273,10 @@ class ExternalElementsAccessor |
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
JSObject* obj, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
return |
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
- ? backing_store->get(key) |
+ ? BackingStore::cast(backing_store)->get(key) |
: backing_store->GetHeap()->undefined_value(); |
} |
@@ -1219,7 +1294,7 @@ class ExternalElementsAccessor |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
return |
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
? FIELD : NONEXISTENT; |
@@ -1228,7 +1303,7 @@ class ExternalElementsAccessor |
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
JSObject* obj, |
Object* length, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
// External arrays do not support changing their length. |
UNREACHABLE(); |
return obj; |
@@ -1244,7 +1319,7 @@ class ExternalElementsAccessor |
static bool HasElementImpl(Object* receiver, |
JSObject* holder, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
uint32_t capacity = |
ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); |
return key < capacity; |
@@ -1353,10 +1428,11 @@ class DictionaryElementsAccessor |
// Adjusts the length of the dictionary backing store and returns the new |
// length according to ES5 section 15.4.5.2 behavior. |
MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize( |
- SeededNumberDictionary* dict, |
+ FixedArrayBase* store, |
JSArray* array, |
Object* length_object, |
uint32_t length) { |
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
Heap* heap = array->GetHeap(); |
int capacity = dict->Capacity(); |
uint32_t new_length = length; |
@@ -1456,30 +1532,12 @@ class DictionaryElementsAccessor |
MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
uint32_t from_start, |
FixedArrayBase* to, |
- ElementsKind to_kind, |
+ ElementsKind from_kind, |
uint32_t to_start, |
int packed_size, |
int copy_size) { |
- switch (to_kind) { |
- case FAST_SMI_ELEMENTS: |
- case FAST_ELEMENTS: |
- case FAST_HOLEY_SMI_ELEMENTS: |
- case FAST_HOLEY_ELEMENTS: |
- CopyDictionaryToObjectElements( |
- SeededNumberDictionary::cast(from), from_start, |
- FixedArray::cast(to), to_kind, to_start, copy_size); |
- return from; |
- case FAST_DOUBLE_ELEMENTS: |
- case FAST_HOLEY_DOUBLE_ELEMENTS: |
- CopyDictionaryToDoubleElements( |
- SeededNumberDictionary::cast(from), from_start, |
- FixedDoubleArray::castOrEmptyFixedArray(to), to_start, |
- copy_size); |
- return from; |
- default: |
- UNREACHABLE(); |
- } |
- return to->GetHeap()->undefined_value(); |
+ UNREACHABLE(); |
+ return NULL; |
} |
@@ -1497,7 +1555,8 @@ class DictionaryElementsAccessor |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- SeededNumberDictionary* backing_store) { |
+ FixedArrayBase* store) { |
+ SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
int entry = backing_store->FindEntry(key); |
if (entry != SeededNumberDictionary::kNotFound) { |
Object* element = backing_store->ValueAt(entry); |
@@ -1532,7 +1591,8 @@ class DictionaryElementsAccessor |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- SeededNumberDictionary* backing_store) { |
+ FixedArrayBase* store) { |
+ SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
int entry = backing_store->FindEntry(key); |
if (entry != SeededNumberDictionary::kNotFound) { |
return backing_store->DetailsAt(entry).type(); |
@@ -1544,7 +1604,8 @@ class DictionaryElementsAccessor |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- BackingStore* backing_store) { |
+ FixedArrayBase* store) { |
+ SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
int entry = backing_store->FindEntry(key); |
if (entry != SeededNumberDictionary::kNotFound && |
backing_store->DetailsAt(entry).type() == CALLBACKS && |
@@ -1557,13 +1618,14 @@ class DictionaryElementsAccessor |
static bool HasElementImpl(Object* receiver, |
JSObject* holder, |
uint32_t key, |
- SeededNumberDictionary* backing_store) { |
- return backing_store->FindEntry(key) != |
+ FixedArrayBase* backing_store) { |
+ return SeededNumberDictionary::cast(backing_store)->FindEntry(key) != |
SeededNumberDictionary::kNotFound; |
} |
- static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, |
+ static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, |
uint32_t index) { |
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
Object* key = dict->KeyAt(index); |
return Smi::cast(key)->value(); |
} |
@@ -1586,7 +1648,8 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
JSObject* obj, |
uint32_t key, |
- FixedArray* parameter_map) { |
+ FixedArrayBase* parameters) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
if (!probe->IsTheHole()) { |
Context* context = Context::cast(parameter_map->get(0)); |
@@ -1634,7 +1697,8 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- FixedArray* parameter_map) { |
+ FixedArrayBase* parameters) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
if (!probe->IsTheHole()) { |
return FIELD; |
@@ -1650,7 +1714,8 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
Object* receiver, |
JSObject* obj, |
uint32_t key, |
- FixedArray* parameter_map) { |
+ FixedArrayBase* parameters) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
if (!probe->IsTheHole()) { |
return NULL; |
@@ -1665,7 +1730,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
JSObject* obj, |
Object* length, |
- FixedArray* parameter_map) { |
+ FixedArrayBase* parameter_map) { |
// TODO(mstarzinger): This was never implemented but will be used once we |
// correctly implement [[DefineOwnProperty]] on arrays. |
UNIMPLEMENTED(); |
@@ -1699,15 +1764,12 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
uint32_t from_start, |
FixedArrayBase* to, |
- ElementsKind to_kind, |
+ ElementsKind from_kind, |
uint32_t to_start, |
int packed_size, |
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); |
+ UNREACHABLE(); |
+ return NULL; |
} |
static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
@@ -1717,7 +1779,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
ForArray(arguments)->GetCapacity(arguments)); |
} |
- static uint32_t GetKeyForIndexImpl(FixedArray* dict, |
+ static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, |
uint32_t index) { |
return index; |
} |
@@ -1725,12 +1787,14 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
static bool HasElementImpl(Object* receiver, |
JSObject* holder, |
uint32_t key, |
- FixedArray* parameter_map) { |
+ FixedArrayBase* parameters) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
Object* probe = GetParameterMapArg(holder, parameter_map, key); |
if (!probe->IsTheHole()) { |
return true; |
} else { |
- FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
+ FixedArrayBase* arguments = |
+ FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1)); |
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
} |
@@ -1743,7 +1807,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
uint32_t length = holder->IsJSArray() |
? Smi::cast(JSArray::cast(holder)->length())->value() |
: parameter_map->length(); |
- return key < (length - 2 ) |
+ return key < (length - 2) |
? parameter_map->get(key + 2) |
: parameter_map->GetHeap()->the_hole_value(); |
} |
@@ -1751,35 +1815,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { |
- switch (array->map()->instance_type()) { |
- case FIXED_ARRAY_TYPE: |
- if (array->IsDictionary()) { |
- return elements_accessors_[DICTIONARY_ELEMENTS]; |
- } else { |
- return elements_accessors_[FAST_HOLEY_ELEMENTS]; |
- } |
- case EXTERNAL_BYTE_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_BYTE_ELEMENTS]; |
- case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; |
- case EXTERNAL_SHORT_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_SHORT_ELEMENTS]; |
- case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; |
- case EXTERNAL_INT_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_INT_ELEMENTS]; |
- case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS]; |
- case EXTERNAL_FLOAT_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS]; |
- case EXTERNAL_DOUBLE_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS]; |
- case EXTERNAL_PIXEL_ARRAY_TYPE: |
- return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS]; |
- default: |
- UNREACHABLE(); |
- return NULL; |
- } |
+ return elements_accessors_[ElementsKindForArray(array)]; |
} |
@@ -1810,7 +1846,7 @@ MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, |
ElementsKindTraits>:: |
SetLengthImpl(JSObject* obj, |
Object* length, |
- typename ElementsKindTraits::BackingStore* backing_store) { |
+ FixedArrayBase* backing_store) { |
JSArray* array = JSArray::cast(obj); |
// Fast case: The new length fits into a Smi. |