Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 256f5558952cea7b5d3f806e205633681796ca40..d311ee7176f55b6adf5e2f4df416cfc919940351 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -13083,26 +13083,15 @@ bool Map::IsValidElementsTransition(ElementsKind from_kind, |
void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array, |
uint32_t index, |
Handle<Object> value) { |
- CALL_HEAP_FUNCTION_VOID(array->GetIsolate(), |
- array->JSArrayUpdateLengthFromIndex(index, *value)); |
-} |
- |
- |
-MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
- Object* value) { |
uint32_t old_len = 0; |
- CHECK(length()->ToArrayIndex(&old_len)); |
+ CHECK(array->length()->ToArrayIndex(&old_len)); |
// Check to see if we need to update the length. For now, we make |
// sure that the length stays within 32-bits (unsigned). |
if (index >= old_len && index != 0xffffffff) { |
- Object* len; |
- { MaybeObject* maybe_len = |
- GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); |
- if (!maybe_len->ToObject(&len)) return maybe_len; |
- } |
- set_length(len); |
+ Handle<Object> len = array->GetIsolate()->factory()->NewNumber( |
+ static_cast<double>(index) + 1); |
+ array->set_length(*len); |
} |
- return value; |
} |
@@ -14520,107 +14509,88 @@ Handle<NameDictionary> NameDictionary::AddNameEntry(Handle<NameDictionary> dict, |
Handle<Object> JSObject::PrepareSlowElementsForSort( |
Handle<JSObject> object, uint32_t limit) { |
- CALL_HEAP_FUNCTION(object->GetIsolate(), |
- object->PrepareSlowElementsForSort(limit), |
- Object); |
-} |
- |
- |
-// Collates undefined and unexisting elements below limit from position |
-// zero of the elements. The object stays in Dictionary mode. |
-MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
- ASSERT(HasDictionaryElements()); |
+ ASSERT(object->HasDictionaryElements()); |
+ Isolate* isolate = object->GetIsolate(); |
// Must stay in dictionary mode, either because of requires_slow_elements, |
// or because we are not going to sort (and therefore compact) all of the |
// elements. |
- SeededNumberDictionary* dict = element_dictionary(); |
- HeapNumber* result_double = NULL; |
- if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
- // Allocate space for result before we start mutating the object. |
- Object* new_double; |
- { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); |
- if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
- } |
- result_double = HeapNumber::cast(new_double); |
- } |
- |
- Object* obj; |
- { MaybeObject* maybe_obj = |
- SeededNumberDictionary::Allocate(GetHeap(), dict->NumberOfElements()); |
- if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
- } |
- SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj); |
- |
- DisallowHeapAllocation no_alloc; |
+ Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); |
+ Handle<SeededNumberDictionary> new_dict = |
+ isolate->factory()->NewSeededNumberDictionary(dict->NumberOfElements()); |
uint32_t pos = 0; |
uint32_t undefs = 0; |
int capacity = dict->Capacity(); |
+ Handle<Smi> bailout(Smi::FromInt(-1), isolate); |
+ // Entry to the new dictionary does not cause it to grow, as we have |
+ // allocated one that is large enough for all entries. |
+ DisallowHeapAllocation no_gc; |
for (int i = 0; i < capacity; i++) { |
Object* k = dict->KeyAt(i); |
- if (dict->IsKey(k)) { |
- ASSERT(k->IsNumber()); |
- ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
- ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
- ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
- Object* value = dict->ValueAt(i); |
- PropertyDetails details = dict->DetailsAt(i); |
- if (details.type() == CALLBACKS || details.IsReadOnly()) { |
- // Bail out and do the sorting of undefineds and array holes in JS. |
- // Also bail out if the element is not supposed to be moved. |
- return Smi::FromInt(-1); |
- } |
- uint32_t key = NumberToUint32(k); |
- // In the following we assert that adding the entry to the new dictionary |
- // does not cause GC. This is the case because we made sure to allocate |
- // the dictionary big enough above, so it need not grow. |
- if (key < limit) { |
- if (value->IsUndefined()) { |
- undefs++; |
- } else { |
- if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
- // Adding an entry with the key beyond smi-range requires |
- // allocation. Bailout. |
- return Smi::FromInt(-1); |
- } |
- new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked(); |
- pos++; |
- } |
+ if (!dict->IsKey(k)) continue; |
+ |
+ ASSERT(k->IsNumber()); |
+ ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
+ ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
+ ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
+ |
+ HandleScope scope(isolate); |
+ Handle<Object> value(dict->ValueAt(i), isolate); |
+ PropertyDetails details = dict->DetailsAt(i); |
+ if (details.type() == CALLBACKS || details.IsReadOnly()) { |
+ // Bail out and do the sorting of undefineds and array holes in JS. |
+ // Also bail out if the element is not supposed to be moved. |
+ return bailout; |
+ } |
+ |
+ uint32_t key = NumberToUint32(k); |
+ if (key < limit) { |
+ if (value->IsUndefined()) { |
+ undefs++; |
+ } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
+ // Adding an entry with the key beyond smi-range requires |
+ // allocation. Bailout. |
+ return bailout; |
} else { |
- if (key > static_cast<uint32_t>(Smi::kMaxValue)) { |
- // Adding an entry with the key beyond smi-range requires |
- // allocation. Bailout. |
- return Smi::FromInt(-1); |
- } |
- new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); |
+ Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
+ new_dict, pos, value, details); |
+ ASSERT(result.is_identical_to(new_dict)); |
+ USE(result); |
+ pos++; |
} |
+ } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) { |
+ // Adding an entry with the key beyond smi-range requires |
+ // allocation. Bailout. |
+ return bailout; |
+ } else { |
+ Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
+ new_dict, key, value, details); |
+ ASSERT(result.is_identical_to(new_dict)); |
+ USE(result); |
} |
} |
uint32_t result = pos; |
PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0); |
- Heap* heap = GetHeap(); |
while (undefs > 0) { |
if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
// Adding an entry with the key beyond smi-range requires |
// allocation. Bailout. |
- return Smi::FromInt(-1); |
+ return bailout; |
} |
- new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> |
- ToObjectUnchecked(); |
+ HandleScope scope(isolate); |
+ Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
+ new_dict, pos, isolate->factory()->undefined_value(), no_details); |
+ ASSERT(result.is_identical_to(new_dict)); |
+ USE(result); |
pos++; |
undefs--; |
} |
- set_elements(new_dict); |
- |
- if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
- return Smi::FromInt(static_cast<int>(result)); |
- } |
+ object->set_elements(*new_dict); |
- ASSERT_NE(NULL, result_double); |
- result_double->set_value(static_cast<double>(result)); |
- return result_double; |
+ AllowHeapAllocation allocate_return_value; |
+ return isolate->factory()->NewNumberFromUint(result); |
mvstanton
2014/04/15 09:56:19
Nice consolidation to use NewNumberFromUint().
|
} |