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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2582 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2009-07-30 07:33:05 +00:00
parent 79b52509d3
commit d8563e4d1e
2 changed files with 57 additions and 25 deletions

View File

@ -2103,6 +2103,11 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
// 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::AllocateJSObject(JSFunction* constructor,
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);
ASSERT(map->unused_property_fields() == 0);
ASSERT(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;
// 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;
// Normalize the result.
JSObject* global = JSObject::cast(result);
result = global->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (result->IsFailure()) return result;
// 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());

View File

@ -2127,7 +2127,10 @@ PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) {
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 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
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 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
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 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
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 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
case INTERCEPTOR:
break;
default:
case NORMAL:
UNREACHABLE();
break;
}
}