| 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());
|
|
|