Revision: 2582 Author: [email protected] Date: Thu Jul 30 00:33:05 2009 Log: Allocate global object as a normalized object.
The global object is now allocated and initialized as a normalized object. Review URL: http://codereview.chromium.org/159587 http://code.google.com/p/v8/source/detail?r=2582 Modified: /branches/bleeding_edge/src/heap.cc /branches/bleeding_edge/src/objects.cc ======================================= --- /branches/bleeding_edge/src/heap.cc Wed Jul 29 05:34:21 2009 +++ /branches/bleeding_edge/src/heap.cc Thu Jul 30 00:33:05 2009 @@ -2103,6 +2103,11 @@ // properly initialized. ASSERT(map->instance_type() != JS_FUNCTION_TYPE); + // Both types of globla objects should be allocated using + // AllocateGloblaObject to be properly initialized. + ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); + ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); + // Allocate the backing storage for the properties. int prop_size = map->unused_property_fields() - map->inobject_properties(); Object* properties = AllocateFixedArray(prop_size, pretenure); @@ -2143,24 +2148,62 @@ Object* Heap::AllocateGlobalObject(JSFunction* constructor) { ASSERT(constructor->has_initial_map()); + Map* map = constructor->initial_map(); + // Make sure no field properties are described in the initial map. // This guarantees us that normalizing the properties does not // require us to change property values to JSGlobalPropertyCells. - ASSERT(constructor->initial_map()->NextFreePropertyIndex() == 0); + ASSERT(map->NextFreePropertyIndex() == 0); // Make sure we don't have a ton of pre-allocated slots in the // global objects. They will be unused once we normalize the object. - ASSERT(constructor->initial_map()->unused_property_fields() == 0); - ASSERT(constructor->initial_map()->inobject_properties() == 0); - - // Allocate the object based on the constructors initial map. - Object* result = AllocateJSObjectFromMap(constructor->initial_map(), TENURED); - if (result->IsFailure()) return result; - - // Normalize the result. - JSObject* global = JSObject::cast(result); - result = global->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); - if (result->IsFailure()) return result; + ASSERT(map->unused_property_fields() == 0); + ASSERT(map->inobject_properties() == 0); + + // Initial size of the backing store to avoid resize of the storage during + // bootstrapping. The size differs between the JS global object ad the + // builtins object. + int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; + + // Allocate a dictionary object for backing storage. + Object* obj = + StringDictionary::Allocate( + map->NumberOfDescribedProperties() * 2 + initial_size); + if (obj->IsFailure()) return obj; + StringDictionary* dictionary = StringDictionary::cast(obj); + + // The global object might be created from an object template with accessors. + // Fill these accessors into the dictionary. + DescriptorArray* descs = map->instance_descriptors(); + for (int i = 0; i < descs->number_of_descriptors(); i++) { + PropertyDetails details = descs->GetDetails(i); + ASSERT(details.type() == CALLBACKS); // Only accessors are expected. + PropertyDetails d = + PropertyDetails(details.attributes(), CALLBACKS, details.index()); + Object* value = descs->GetCallbacksObject(i); + value = Heap::AllocateJSGlobalPropertyCell(value); + if (value->IsFailure()) return value; + + Object* result = dictionary->Add(descs->GetKey(i), value, d); + if (result->IsFailure()) return result; + dictionary = StringDictionary::cast(result); + } + + // Allocate the global object and initialize it with the backing store. + obj = Allocate(map, OLD_POINTER_SPACE); + if (obj->IsFailure()) return obj; + JSObject* global = JSObject::cast(obj); + InitializeJSObjectFromMap(global, dictionary, map); + + // Create a new map for the global object. + obj = map->CopyDropDescriptors(); + if (obj->IsFailure()) return obj; + Map* new_map = Map::cast(obj); + + // Setup the global object as a normalized object. + global->set_map(new_map); + global->map()->set_instance_descriptors(Heap::empty_descriptor_array()); + global->set_properties(dictionary); // Make sure result is a global object with properties in dictionary. ASSERT(global->IsGlobalObject()); ======================================= --- /branches/bleeding_edge/src/objects.cc Tue Jul 28 11:11:12 2009 +++ /branches/bleeding_edge/src/objects.cc Thu Jul 30 00:33:05 2009 @@ -2127,7 +2127,10 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) { if (!HasFastProperties()) return this; - // Allocate new content + // The global object is always normalized. + ASSERT(!IsGlobalObject()); + + // Allocate new content. Object* obj = StringDictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); if (obj->IsFailure()) return obj; @@ -2141,10 +2144,6 @@ PropertyDetails d = PropertyDetails(details.attributes(), NORMAL, details.index()); Object* value = descs->GetConstantFunction(i); - if (IsGlobalObject()) { - value = Heap::AllocateJSGlobalPropertyCell(value); - if (value->IsFailure()) return value; - } Object* result = dictionary->Add(descs->GetKey(i), value, d); if (result->IsFailure()) return result; dictionary = StringDictionary::cast(result); @@ -2154,10 +2153,6 @@ PropertyDetails d = PropertyDetails(details.attributes(), NORMAL, details.index()); Object* value = FastPropertyAt(descs->GetFieldIndex(i)); - if (IsGlobalObject()) { - value = Heap::AllocateJSGlobalPropertyCell(value); - if (value->IsFailure()) return value; - } Object* result = dictionary->Add(descs->GetKey(i), value, d); if (result->IsFailure()) return result; dictionary = StringDictionary::cast(result); @@ -2167,10 +2162,6 @@ PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, details.index()); Object* value = descs->GetCallbacksObject(i); - if (IsGlobalObject()) { - value = Heap::AllocateJSGlobalPropertyCell(value); - if (value->IsFailure()) return value; - } Object* result = dictionary->Add(descs->GetKey(i), value, d); if (result->IsFailure()) return result; dictionary = StringDictionary::cast(result); @@ -2182,9 +2173,7 @@ case INTERCEPTOR: break; default: - case NORMAL: UNREACHABLE(); - break; } } --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
