Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 63b77b7994b4833a7e3eb41c66516b81d040b13f..5a057e1643a6659f8585d4f1da2bf2230b8ceca6 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2222,6 +2222,11 @@ Object* JSObject::TransformToFastProperties(int unused_property_fields) { |
Object* JSObject::NormalizeElements() { |
ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
if (HasDictionaryElements()) return this; |
+ ASSERT(map()->has_fast_elements()); |
+ |
+ Object* obj = map()->GetSlowElementsMap(); |
+ if (obj->IsFailure()) return obj; |
+ Map* new_map = Map::cast(obj); |
// Get number of entries. |
FixedArray* array = FixedArray::cast(elements()); |
@@ -2230,7 +2235,7 @@ Object* JSObject::NormalizeElements() { |
int length = IsJSArray() ? |
Smi::cast(JSArray::cast(this)->length())->value() : |
array->length(); |
- Object* obj = NumberDictionary::Allocate(length); |
+ obj = NumberDictionary::Allocate(length); |
if (obj->IsFailure()) return obj; |
NumberDictionary* dictionary = NumberDictionary::cast(obj); |
// Copy entries. |
@@ -2243,7 +2248,10 @@ Object* JSObject::NormalizeElements() { |
dictionary = NumberDictionary::cast(result); |
} |
} |
- // Switch to using the dictionary as the backing storage for elements. |
+ // Switch to using the dictionary as the backing storage for |
+ // elements. Set the new map first to satify the elements type |
+ // assert in set_elements(). |
+ set_map(new_map); |
set_elements(dictionary); |
Counters::elements_to_dictionary.Increment(); |
@@ -5473,14 +5481,18 @@ void Code::Disassemble(const char* name) { |
#endif // ENABLE_DISASSEMBLER |
-void JSObject::SetFastElements(FixedArray* elems) { |
+Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) { |
// We should never end in here with a pixel or external array. |
ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
-#ifdef DEBUG |
- // Check the provided array is filled with the_hole. |
- uint32_t len = static_cast<uint32_t>(elems->length()); |
- for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole()); |
-#endif |
+ |
+ Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); |
+ if (obj->IsFailure()) return obj; |
+ FixedArray* elems = FixedArray::cast(obj); |
+ |
+ obj = map()->GetFastElementsMap(); |
+ if (obj->IsFailure()) return obj; |
+ Map* new_map = Map::cast(obj); |
+ |
AssertNoAllocation no_gc; |
WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); |
switch (GetElementsKind()) { |
@@ -5508,7 +5520,15 @@ void JSObject::SetFastElements(FixedArray* elems) { |
UNREACHABLE(); |
break; |
} |
+ |
+ set_map(new_map); |
set_elements(elems); |
+ |
+ if (IsJSArray()) { |
+ JSArray::cast(this)->set_length(Smi::FromInt(length)); |
+ } |
+ |
+ return this; |
} |
@@ -5595,7 +5615,7 @@ Object* JSObject::SetElementsLength(Object* len) { |
Object* smi_length = len->ToSmi(); |
if (smi_length->IsSmi()) { |
- int value = Smi::cast(smi_length)->value(); |
+ const int value = Smi::cast(smi_length)->value(); |
if (value < 0) return ArrayLengthRangeError(); |
switch (GetElementsKind()) { |
case FAST_ELEMENTS: { |
@@ -5617,12 +5637,8 @@ Object* JSObject::SetElementsLength(Object* len) { |
int new_capacity = value > min ? value : min; |
if (new_capacity <= kMaxFastElementsLength || |
!ShouldConvertToSlowElements(new_capacity)) { |
- Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); |
+ Object* obj = SetFastElementsCapacityAndLength(new_capacity, value); |
if (obj->IsFailure()) return obj; |
- if (IsJSArray()) { |
- JSArray::cast(this)->set_length(Smi::cast(smi_length)); |
- } |
- SetFastElements(FixedArray::cast(obj)); |
return this; |
} |
break; |
@@ -5633,7 +5649,8 @@ Object* JSObject::SetElementsLength(Object* len) { |
// 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. |
- initialize_elements(); |
+ Object* obj = ResetElements(); |
+ if (obj->IsFailure()) return obj; |
} else { |
// Remove deleted elements. |
uint32_t old_length = |
@@ -6092,12 +6109,8 @@ Object* JSObject::SetFastElement(uint32_t index, Object* value) { |
if (new_capacity <= kMaxFastElementsLength || |
!ShouldConvertToSlowElements(new_capacity)) { |
ASSERT(static_cast<uint32_t>(new_capacity) > index); |
- Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); |
+ Object* obj = SetFastElementsCapacityAndLength(new_capacity, index + 1); |
if (obj->IsFailure()) return obj; |
- SetFastElements(FixedArray::cast(obj)); |
- if (IsJSArray()) { |
- JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); |
- } |
FixedArray::cast(elements())->set(index, value); |
return value; |
} |
@@ -6216,13 +6229,11 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) { |
uint32_t new_length = 0; |
if (IsJSArray()) { |
CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); |
- JSArray::cast(this)->set_length(Smi::FromInt(new_length)); |
} else { |
new_length = NumberDictionary::cast(elements())->max_number_key() + 1; |
} |
- Object* obj = Heap::AllocateFixedArrayWithHoles(new_length); |
+ Object* obj = SetFastElementsCapacityAndLength(new_length, new_length); |
if (obj->IsFailure()) return obj; |
- SetFastElements(FixedArray::cast(obj)); |
#ifdef DEBUG |
if (FLAG_trace_normalization) { |
PrintF("Object elements are fast case again:\n"); |
@@ -7526,14 +7537,18 @@ Object* JSObject::PrepareElementsForSort(uint32_t limit) { |
} |
// Convert to fast elements. |
+ Object* obj = map()->GetFastElementsMap(); |
+ if (obj->IsFailure()) return obj; |
+ Map* new_map = Map::cast(obj); |
+ |
PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; |
Object* new_array = |
Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); |
- if (new_array->IsFailure()) { |
- return new_array; |
- } |
+ if (new_array->IsFailure()) return new_array; |
FixedArray* fast_elements = FixedArray::cast(new_array); |
dict->CopyValuesTo(fast_elements); |
+ |
+ set_map(new_map); |
set_elements(fast_elements); |
} |
ASSERT(HasFastElements()); |