Index: src/factory.cc |
diff --git a/src/factory.cc b/src/factory.cc |
index bb998a42de3cc55d36c981d5dc10eef61bd6f419..4927cac376176dbea65ca4ed45c2d893ee0b8d02 100644 |
--- a/src/factory.cc |
+++ b/src/factory.cc |
@@ -538,15 +538,22 @@ Handle<Cell> Factory::NewCell(Handle<Object> value) { |
} |
-Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) { |
- AllowDeferredHandleDereference convert_to_cell; |
+Handle<PropertyCell> Factory::NewPropertyCellWithHole() { |
CALL_HEAP_FUNCTION( |
isolate(), |
- isolate()->heap()->AllocatePropertyCell(*value), |
+ isolate()->heap()->AllocatePropertyCell(), |
PropertyCell); |
} |
+Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) { |
+ AllowDeferredHandleDereference convert_to_cell; |
+ Handle<PropertyCell> cell = NewPropertyCellWithHole(); |
+ PropertyCell::SetValueInferType(cell, value); |
+ return cell; |
+} |
+ |
+ |
Handle<AllocationSite> Factory::NewAllocationSite() { |
CALL_HEAP_FUNCTION( |
isolate(), |
@@ -1052,14 +1059,79 @@ Handle<JSModule> Factory::NewJSModule(Handle<Context> context, |
} |
-Handle<GlobalObject> Factory::NewGlobalObject( |
- Handle<JSFunction> constructor) { |
- CALL_HEAP_FUNCTION(isolate(), |
- isolate()->heap()->AllocateGlobalObject(*constructor), |
+// TODO(mstarzinger): Temporary wrapper until handlified. |
+static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyDetails details) { |
+ CALL_HEAP_FUNCTION(dict->GetIsolate(), |
+ dict->Add(*name, *value, details), |
+ NameDictionary); |
+} |
+ |
+ |
+static Handle<GlobalObject> NewGlobalObjectFromMap(Isolate* isolate, |
+ Handle<Map> map) { |
+ CALL_HEAP_FUNCTION(isolate, |
+ isolate->heap()->Allocate(*map, OLD_POINTER_SPACE), |
GlobalObject); |
} |
+Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) { |
+ ASSERT(constructor->has_initial_map()); |
+ Handle<Map> map(constructor->initial_map()); |
+ ASSERT(map->is_dictionary_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 PropertyCells. |
+ 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(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. |
+ int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size; |
+ Handle<NameDictionary> dictionary = NewNameDictionary(at_least_space_for); |
+ |
+ // The global object might be created from an object template with accessors. |
+ // Fill these accessors into the dictionary. |
+ Handle<DescriptorArray> descs(map->instance_descriptors()); |
+ for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { |
+ PropertyDetails details = descs->GetDetails(i); |
+ ASSERT(details.type() == CALLBACKS); // Only accessors are expected. |
+ PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1); |
+ Handle<Name> name(descs->GetKey(i)); |
+ Handle<Object> value(descs->GetCallbacksObject(i), isolate()); |
+ Handle<PropertyCell> cell = NewPropertyCell(value); |
+ NameDictionaryAdd(dictionary, name, cell, d); |
+ } |
+ |
+ // Allocate the global object and initialize it with the backing store. |
+ Handle<GlobalObject> global = NewGlobalObjectFromMap(isolate(), map); |
+ isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map); |
+ |
+ // Create a new map for the global object. |
+ Handle<Map> new_map = Map::CopyDropDescriptors(map); |
+ new_map->set_dictionary_map(true); |
+ |
+ // Set up the global object as a normalized object. |
+ global->set_map(*new_map); |
+ global->set_properties(*dictionary); |
+ |
+ // Make sure result is a global object with properties in dictionary. |
+ ASSERT(global->IsGlobalObject() && !global->HasFastProperties()); |
+ return global; |
+} |
+ |
Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map, |
PretenureFlag pretenure, |