Commit 90b1077e authored by ishell@chromium.org's avatar ishell@chromium.org

Reland of r20146 "JSObject::NormalizeElements() handlified."

R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/208003002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20161 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a428b0d5
...@@ -4661,120 +4661,91 @@ void JSObject::TransformToFastProperties(Handle<JSObject> object, ...@@ -4661,120 +4661,91 @@ void JSObject::TransformToFastProperties(Handle<JSObject> object,
} }
static MUST_USE_RESULT MaybeObject* CopyFastElementsToDictionary( static Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
Isolate* isolate, Handle<FixedArrayBase> array,
FixedArrayBase* array,
int length, int length,
SeededNumberDictionary* dictionary) { Handle<SeededNumberDictionary> dictionary) {
Heap* heap = isolate->heap(); Isolate* isolate = array->GetIsolate();
Factory* factory = isolate->factory();
bool has_double_elements = array->IsFixedDoubleArray(); bool has_double_elements = array->IsFixedDoubleArray();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
Object* value = NULL; Handle<Object> value;
if (has_double_elements) { if (has_double_elements) {
FixedDoubleArray* double_array = FixedDoubleArray::cast(array); Handle<FixedDoubleArray> double_array =
Handle<FixedDoubleArray>::cast(array);
if (double_array->is_the_hole(i)) { if (double_array->is_the_hole(i)) {
value = isolate->heap()->the_hole_value(); value = factory->the_hole_value();
} else { } else {
// Objects must be allocated in the old object space, since the value = factory->NewHeapNumber(double_array->get_scalar(i));
// overall number of HeapNumbers needed for the conversion might
// exceed the capacity of new space, and we would fail repeatedly
// trying to convert the FixedDoubleArray.
MaybeObject* maybe_value_object =
heap->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
} }
} else { } else {
value = FixedArray::cast(array)->get(i); value = handle(Handle<FixedArray>::cast(array)->get(i), isolate);
} }
if (!value->IsTheHole()) { if (!value->IsTheHole()) {
PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
MaybeObject* maybe_result = dictionary =
dictionary->AddNumberEntry(i, value, details); SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details);
if (!maybe_result->To(&dictionary)) return maybe_result;
} }
} }
return dictionary; return dictionary;
} }
static Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
Handle<FixedArrayBase> array,
int length,
Handle<SeededNumberDictionary> dict) {
Isolate* isolate = array->GetIsolate();
CALL_HEAP_FUNCTION(isolate,
CopyFastElementsToDictionary(
isolate, *array, length, *dict),
SeededNumberDictionary);
}
Handle<SeededNumberDictionary> JSObject::NormalizeElements( Handle<SeededNumberDictionary> JSObject::NormalizeElements(
Handle<JSObject> object) { Handle<JSObject> object) {
CALL_HEAP_FUNCTION(object->GetIsolate(), ASSERT(!object->HasExternalArrayElements());
object->NormalizeElements(), Isolate* isolate = object->GetIsolate();
SeededNumberDictionary); Factory* factory = isolate->factory();
}
MaybeObject* JSObject::NormalizeElements() {
ASSERT(!HasExternalArrayElements());
// Find the backing store. // Find the backing store.
FixedArrayBase* array = FixedArrayBase::cast(elements()); Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements()));
Map* old_map = array->map();
bool is_arguments = bool is_arguments =
(old_map == old_map->GetHeap()->sloppy_arguments_elements_map()); (array->map() == isolate->heap()->sloppy_arguments_elements_map());
if (is_arguments) { if (is_arguments) {
array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); array = handle(FixedArrayBase::cast(
Handle<FixedArray>::cast(array)->get(1)));
} }
if (array->IsDictionary()) return array; if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array);
ASSERT(HasFastSmiOrObjectElements() || ASSERT(object->HasFastSmiOrObjectElements() ||
HasFastDoubleElements() || object->HasFastDoubleElements() ||
HasFastArgumentsElements()); object->HasFastArgumentsElements());
// Compute the effective length and allocate a new backing store. // Compute the effective length and allocate a new backing store.
int length = IsJSArray() int length = object->IsJSArray()
? Smi::cast(JSArray::cast(this)->length())->value() ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
: array->length(); : array->length();
int old_capacity = 0; int old_capacity = 0;
int used_elements = 0; int used_elements = 0;
GetElementsCapacityAndUsage(&old_capacity, &used_elements); object->GetElementsCapacityAndUsage(&old_capacity, &used_elements);
SeededNumberDictionary* dictionary; Handle<SeededNumberDictionary> dictionary =
MaybeObject* maybe_dictionary = factory->NewSeededNumberDictionary(used_elements);
SeededNumberDictionary::Allocate(GetHeap(), used_elements);
if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
maybe_dictionary = CopyFastElementsToDictionary( dictionary = CopyFastElementsToDictionary(array, length, dictionary);
GetIsolate(), array, length, dictionary);
if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
// Switch to using the dictionary as the backing storage for elements. // Switch to using the dictionary as the backing storage for elements.
if (is_arguments) { if (is_arguments) {
FixedArray::cast(elements())->set(1, dictionary); FixedArray::cast(object->elements())->set(1, *dictionary);
} else { } else {
// Set the new map first to satify the elements type assert in // Set the new map first to satify the elements type assert in
// set_elements(). // set_elements().
Map* new_map; Handle<Map> new_map =
MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS);
DICTIONARY_ELEMENTS);
if (!maybe->To(&new_map)) return maybe; JSObject::MigrateToMap(object, new_map);
// TODO(verwaest): Replace by MigrateToMap. object->set_elements(*dictionary);
set_map(new_map);
set_elements(dictionary);
} }
old_map->GetHeap()->isolate()->counters()->elements_to_dictionary()-> isolate->counters()->elements_to_dictionary()->Increment();
Increment();
#ifdef DEBUG #ifdef DEBUG
if (FLAG_trace_normalization) { if (FLAG_trace_normalization) {
PrintF("Object elements have been normalized:\n"); PrintF("Object elements have been normalized:\n");
Print(); object->Print();
} }
#endif #endif
ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); ASSERT(object->HasDictionaryElements() ||
object->HasDictionaryArgumentsElements());
return dictionary; return dictionary;
} }
......
...@@ -2608,8 +2608,6 @@ class JSObject: public JSReceiver { ...@@ -2608,8 +2608,6 @@ class JSObject: public JSReceiver {
static Handle<SeededNumberDictionary> NormalizeElements( static Handle<SeededNumberDictionary> NormalizeElements(
Handle<JSObject> object); Handle<JSObject> object);
MUST_USE_RESULT MaybeObject* NormalizeElements();
// Transform slow named properties to fast variants. // Transform slow named properties to fast variants.
static void TransformToFastProperties(Handle<JSObject> object, static void TransformToFastProperties(Handle<JSObject> object,
int unused_property_fields); int unused_property_fields);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment