Index: src/builtins/builtins-array.cc |
diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc |
index 5f3bc4250b577428b0b841b66b3b074ac13d0f3b..9df9d980c543a02094d5bc1bab46da05220492d1 100644 |
--- a/src/builtins/builtins-array.cc |
+++ b/src/builtins/builtins-array.cc |
@@ -555,14 +555,18 @@ namespace { |
*/ |
class ArrayConcatVisitor { |
public: |
- ArrayConcatVisitor(Isolate* isolate, Handle<Object> storage, |
+ ArrayConcatVisitor(Isolate* isolate, Handle<HeapObject> storage, |
bool fast_elements) |
: isolate_(isolate), |
storage_(isolate->global_handles()->Create(*storage)), |
index_offset_(0u), |
- bit_field_(FastElementsField::encode(fast_elements) | |
- ExceedsLimitField::encode(false) | |
- IsFixedArrayField::encode(storage->IsFixedArray())) { |
+ bit_field_( |
+ FastElementsField::encode(fast_elements) | |
+ ExceedsLimitField::encode(false) | |
+ IsFixedArrayField::encode(storage->IsFixedArray()) | |
+ HasSimpleElementsField::encode(storage->IsFixedArray() || |
+ storage->map()->instance_type() > |
+ LAST_CUSTOM_ELEMENTS_RECEIVER)) { |
DCHECK(!(this->fast_elements() && !is_fixed_array())); |
} |
@@ -652,12 +656,16 @@ class ArrayConcatVisitor { |
// (otherwise) |
Handle<FixedArray> storage_fixed_array() { |
DCHECK(is_fixed_array()); |
+ DCHECK(has_simple_elements()); |
return Handle<FixedArray>::cast(storage_); |
} |
Handle<JSReceiver> storage_jsreceiver() { |
DCHECK(!is_fixed_array()); |
return Handle<JSReceiver>::cast(storage_); |
} |
+ bool has_simple_elements() const { |
+ return HasSimpleElementsField::decode(bit_field_); |
+ } |
private: |
// Convert storage to dictionary mode. |
@@ -691,12 +699,14 @@ class ArrayConcatVisitor { |
inline void set_storage(FixedArray* storage) { |
DCHECK(is_fixed_array()); |
+ DCHECK(has_simple_elements()); |
storage_ = isolate_->global_handles()->Create(storage); |
} |
class FastElementsField : public BitField<bool, 0, 1> {}; |
class ExceedsLimitField : public BitField<bool, 1, 1> {}; |
class IsFixedArrayField : public BitField<bool, 2, 1> {}; |
+ class HasSimpleElementsField : public BitField<bool, 3, 1> {}; |
bool fast_elements() const { return FastElementsField::decode(bit_field_); } |
void set_fast_elements(bool fast) { |
@@ -922,7 +932,6 @@ bool IterateElementsSlow(Isolate* isolate, Handle<JSReceiver> receiver, |
visitor->increase_index_offset(length); |
return true; |
} |
- |
/** |
* A helper function that visits "array" elements of a JSReceiver in numerical |
* order. |
@@ -952,7 +961,8 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver, |
return IterateElementsSlow(isolate, receiver, length, visitor); |
} |
- if (!HasOnlySimpleElements(isolate, *receiver)) { |
+ if (!HasOnlySimpleElements(isolate, *receiver) || |
+ !visitor->has_simple_elements()) { |
return IterateElementsSlow(isolate, receiver, length, visitor); |
} |
Handle<JSObject> array = Handle<JSObject>::cast(receiver); |
@@ -1222,7 +1232,7 @@ Object* Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species, |
// In case of failure, fall through. |
} |
- Handle<Object> storage; |
+ Handle<HeapObject> storage; |
if (fast_case) { |
// The backing storage array must have non-existing elements to preserve |
// holes across concat operations. |
@@ -1240,7 +1250,7 @@ Object* Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species, |
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
isolate, storage_object, |
Execution::New(isolate, species, species, 1, &length)); |
- storage = storage_object; |
+ storage = Handle<HeapObject>::cast(storage_object); |
} |
ArrayConcatVisitor visitor(isolate, storage, fast_case); |