Commit 6cfc5f1e authored by kasperl@chromium.org's avatar kasperl@chromium.org

Treat the builtins object like other global objects (with

cells in old space for properties) and avoid allocating tons
of unused properties in new space when creating new contexts.
Review URL: http://codereview.chromium.org/151146

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2319 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 70331f67
......@@ -684,7 +684,7 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
}
Object* CallStubCompiler::CompileCallGlobal(JSGlobalObject* object,
Object* CallStubCompiler::CompileCallGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
JSFunction* function,
String* name) {
......@@ -879,7 +879,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
}
Object* StoreStubCompiler::CompileStoreGlobal(JSGlobalObject* object,
Object* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
String* name) {
// ----------- S t a t e -------------
......@@ -1012,7 +1012,7 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
}
Object* LoadStubCompiler::CompileLoadGlobal(JSGlobalObject* object,
Object* LoadStubCompiler::CompileLoadGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
String* name,
bool is_dont_delete) {
......
......@@ -539,7 +539,7 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
{ // --- G l o b a l ---
// Step 1: create a fresh inner JSGlobalObject
Handle<JSGlobalObject> object;
Handle<GlobalObject> object;
{
Handle<JSFunction> js_global_function;
Handle<ObjectTemplateInfo> js_global_template;
......@@ -579,8 +579,7 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
}
js_global_function->initial_map()->set_is_hidden_prototype();
SetExpectedNofProperties(js_global_function, 100);
object = Factory::NewJSGlobalObject(js_global_function);
object = Factory::NewGlobalObject(js_global_function);
}
// Set the global context for the global object.
......@@ -962,12 +961,10 @@ bool Genesis::InstallNatives() {
Handle<String> name = Factory::LookupAsciiSymbol("builtins");
builtins_fun->shared()->set_instance_class_name(*name);
SetExpectedNofProperties(builtins_fun, 100);
// Allocate the builtins object.
Handle<JSBuiltinsObject> builtins =
Handle<JSBuiltinsObject>::cast(Factory::NewJSObject(builtins_fun,
TENURED));
Handle<JSBuiltinsObject>::cast(Factory::NewGlobalObject(builtins_fun));
builtins->set_builtins(*builtins);
builtins->set_global_context(*global_context());
builtins->set_global_receiver(*builtins);
......@@ -1190,10 +1187,6 @@ bool Genesis::InstallNatives() {
apply->shared()->set_length(2);
}
// Make sure that the builtins object has fast properties.
// If the ASSERT below fails, please increase the expected number of
// properties for the builtins object.
ASSERT(builtins->HasFastProperties());
#ifdef DEBUG
builtins->Verify();
#endif
......
......@@ -619,10 +619,10 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
}
Handle<JSGlobalObject> Factory::NewJSGlobalObject(
Handle<GlobalObject> Factory::NewGlobalObject(
Handle<JSFunction> constructor) {
CALL_HEAP_FUNCTION(Heap::AllocateJSGlobalObject(*constructor),
JSGlobalObject);
CALL_HEAP_FUNCTION(Heap::AllocateGlobalObject(*constructor),
GlobalObject);
}
......
......@@ -183,9 +183,8 @@ class Factory : public AllStatic {
static Handle<JSObject> NewJSObject(Handle<JSFunction> constructor,
PretenureFlag pretenure = NOT_TENURED);
// JS global objects are pretenured.
static Handle<JSGlobalObject> NewJSGlobalObject(
Handle<JSFunction> constructor);
// Global objects are pretenured.
static Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor);
// JS objects are pretenured when allocated by the bootstrapper and
// runtime.
......
......@@ -1558,7 +1558,7 @@ Object* Heap::AllocateProxy(Address proxy, PretenureFlag pretenure) {
Object* Heap::AllocateSharedFunctionInfo(Object* name) {
Object* result = Allocate(shared_function_info_map(), NEW_SPACE);
Object* result = Allocate(shared_function_info_map(), OLD_POINTER_SPACE);
if (result->IsFailure()) return result;
SharedFunctionInfo* share = SharedFunctionInfo::cast(result);
......@@ -2050,7 +2050,7 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
// Allocate the backing storage for the properties.
int prop_size = map->unused_property_fields() - map->inobject_properties();
Object* properties = AllocateFixedArray(prop_size);
Object* properties = AllocateFixedArray(prop_size, pretenure);
if (properties->IsFailure()) return properties;
// Allocate the JSObject.
......@@ -2080,19 +2080,24 @@ Object* Heap::AllocateJSObject(JSFunction* constructor,
// Allocate the object based on the constructors initial map.
Object* result =
AllocateJSObjectFromMap(constructor->initial_map(), pretenure);
// Make sure result is NOT a JS global object if valid.
ASSERT(result->IsFailure() || !result->IsJSGlobalObject());
// Make sure result is NOT a global object if valid.
ASSERT(result->IsFailure() || !result->IsGlobalObject());
return result;
}
Object* Heap::AllocateJSGlobalObject(JSFunction* constructor) {
Object* Heap::AllocateGlobalObject(JSFunction* constructor) {
ASSERT(constructor->has_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);
// 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;
......@@ -2102,8 +2107,8 @@ Object* Heap::AllocateJSGlobalObject(JSFunction* constructor) {
result = global->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (result->IsFailure()) return result;
// Make sure result is a JS global object with properties in dictionary.
ASSERT(global->IsJSGlobalObject());
// Make sure result is a global object with properties in dictionary.
ASSERT(global->IsGlobalObject());
ASSERT(!global->HasFastProperties());
return global;
}
......@@ -2182,7 +2187,7 @@ Object* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor,
// Allocate the backing storage for the properties.
int prop_size = map->unused_property_fields() - map->inobject_properties();
Object* properties = AllocateFixedArray(prop_size);
Object* properties = AllocateFixedArray(prop_size, TENURED);
if (properties->IsFailure()) return properties;
// Reset the map for the object.
......
......@@ -289,11 +289,11 @@ class Heap : public AllStatic {
static Object* AllocateJSObject(JSFunction* constructor,
PretenureFlag pretenure = NOT_TENURED);
// Allocates and initializes a new JS global object based on a constructor.
// Allocates and initializes a new global object based on a constructor.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
static Object* AllocateJSGlobalObject(JSFunction* constructor);
static Object* AllocateGlobalObject(JSFunction* constructor);
// Returns a deep copy of the JavaScript object.
// Properties and elements are copied too.
......
......@@ -715,7 +715,7 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
}
Object* CallStubCompiler::CompileCallGlobal(JSGlobalObject* object,
Object* CallStubCompiler::CompileCallGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
JSFunction* function,
String* name) {
......@@ -911,7 +911,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
}
Object* StoreStubCompiler::CompileStoreGlobal(JSGlobalObject* object,
Object* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
String* name) {
// ----------- S t a t e -------------
......@@ -1092,7 +1092,7 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
}
Object* LoadStubCompiler::CompileLoadGlobal(JSGlobalObject* object,
Object* LoadStubCompiler::CompileLoadGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
String* name,
bool is_dont_delete) {
......
......@@ -419,11 +419,11 @@ void CallIC::UpdateCaches(LookupResult* lookup,
}
case NORMAL: {
if (!object->IsJSObject()) return;
if (object->IsJSGlobalObject()) {
if (object->IsGlobalObject()) {
// The stub generated for the global object picks the value directly
// from the property cell. So the property must be directly on the
// global object.
Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object);
Handle<GlobalObject> global = Handle<GlobalObject>::cast(object);
if (lookup->holder() != *global) return;
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
......@@ -624,11 +624,11 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
break;
}
case NORMAL: {
if (object->IsJSGlobalObject()) {
if (object->IsGlobalObject()) {
// The stub generated for the global object picks the value directly
// from the property cell. So the property must be directly on the
// global object.
Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object);
Handle<GlobalObject> global = Handle<GlobalObject>::cast(object);
if (lookup->holder() != *global) return;
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
......@@ -976,13 +976,13 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
break;
}
case NORMAL: {
if (!receiver->IsJSGlobalObject()) {
if (!receiver->IsGlobalObject()) {
return;
}
// The stub generated for the global object picks the value directly
// from the property cell. So the property must be directly on the
// global object.
Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver);
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
code = StubCache::ComputeStoreGlobal(*name, *global, cell);
......
......@@ -402,7 +402,7 @@ Object* JSObject::DeleteLazyProperty(LookupResult* result,
Object* JSObject::GetNormalizedProperty(LookupResult* result) {
ASSERT(!HasFastProperties());
Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
value = JSGlobalPropertyCell::cast(value)->value();
}
ASSERT(!value->IsJSGlobalPropertyCell());
......@@ -412,7 +412,7 @@ Object* JSObject::GetNormalizedProperty(LookupResult* result) {
Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
ASSERT(!HasFastProperties());
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(
property_dictionary()->ValueAt(result->GetDictionaryEntry()));
......@@ -431,7 +431,7 @@ Object* JSObject::SetNormalizedProperty(String* name,
int entry = property_dictionary()->FindStringEntry(name);
if (entry == Dictionary::kNotFound) {
Object* store_value = value;
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
store_value = Heap::AllocateJSGlobalPropertyCell(value);
if (store_value->IsFailure()) return store_value;
}
......@@ -445,7 +445,7 @@ Object* JSObject::SetNormalizedProperty(String* name,
details = PropertyDetails(details.attributes(),
details.type(),
property_dictionary()->DetailsAt(entry).index());
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
cell->set_value(value);
......@@ -464,7 +464,7 @@ Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
int entry = dictionary->FindStringEntry(name);
if (entry != Dictionary::kNotFound) {
// If we have a global object set the cell to the hole.
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.IsDontDelete() && mode != FORCE_DELETION) {
return Heap::false_value();
......@@ -1342,7 +1342,7 @@ Object* JSObject::AddSlowProperty(String* name,
ASSERT(!HasFastProperties());
Dictionary* dict = property_dictionary();
Object* store_value = value;
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
// In case name is an orphaned property reuse the cell.
int entry = dict->FindStringEntry(name);
if (entry != Dictionary::kNotFound) {
......@@ -1703,7 +1703,7 @@ void JSObject::LocalLookupRealNamedProperty(String* name,
// Make sure to disallow caching for uninitialized constants
// found in the dictionary-mode objects.
Object* value = property_dictionary()->ValueAt(entry);
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
PropertyDetails d = property_dictionary()->DetailsAt(entry);
if (d.IsDeleted()) {
result->NotFound();
......@@ -2114,7 +2114,7 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
PropertyDetails d =
PropertyDetails(details.attributes(), NORMAL, details.index());
Object* value = r.GetConstantFunction();
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
value = Heap::AllocateJSGlobalPropertyCell(value);
if (value->IsFailure()) return value;
}
......@@ -2127,7 +2127,7 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
PropertyDetails d =
PropertyDetails(details.attributes(), NORMAL, details.index());
Object* value = FastPropertyAt(r.GetFieldIndex());
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
value = Heap::AllocateJSGlobalPropertyCell(value);
if (value->IsFailure()) return value;
}
......@@ -2140,7 +2140,7 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
PropertyDetails d =
PropertyDetails(details.attributes(), CALLBACKS, details.index());
Object* value = r.GetCallbacksObject();
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
value = Heap::AllocateJSGlobalPropertyCell(value);
if (value->IsFailure()) return value;
}
......@@ -2203,9 +2203,9 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
Object* JSObject::TransformToFastProperties(int unused_property_fields) {
if (HasFastProperties()) return this;
ASSERT(!IsJSGlobalObject());
ASSERT(!IsGlobalObject());
return property_dictionary()->
TransformPropertiesToFastFor(this, unused_property_fields);
TransformPropertiesToFastFor(this, unused_property_fields);
}
......@@ -2740,7 +2740,7 @@ Object* JSObject::DefineGetterSetter(String* name,
// For the global object allocate a new map to invalidate the global inline
// caches which have a global property cell reference directly in the code.
if (IsJSGlobalObject()) {
if (IsGlobalObject()) {
Object* new_map = map()->CopyDropDescriptors();
if (new_map->IsFailure()) return new_map;
set_map(Map::cast(new_map));
......@@ -6739,7 +6739,7 @@ Object* JSObject::PrepareElementsForSort(uint32_t limit) {
}
Object* JSGlobalObject::GetPropertyCell(LookupResult* result) {
Object* GlobalObject::GetPropertyCell(LookupResult* result) {
ASSERT(!HasFastProperties());
Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
ASSERT(value->IsJSGlobalPropertyCell());
......
......@@ -3059,6 +3059,9 @@ class GlobalObject: public JSObject {
// [global receiver]: the global receiver object of the context
DECL_ACCESSORS(global_receiver, JSObject)
// Retrieve the property cell used to store a property.
Object* GetPropertyCell(LookupResult* result);
// Casting.
static inline GlobalObject* cast(Object* obj);
......@@ -3079,9 +3082,6 @@ class GlobalObject: public JSObject {
class JSGlobalObject: public GlobalObject {
public:
// Retrieve the property cell used to store a property.
Object* GetPropertyCell(LookupResult* result);
// Casting.
static inline JSGlobalObject* cast(Object* obj);
......
......@@ -260,7 +260,7 @@ class LookupResult BASE_EMBEDDED {
case NORMAL: {
Object* value;
value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
if (holder()->IsJSGlobalObject()) {
if (holder()->IsGlobalObject()) {
value = JSGlobalPropertyCell::cast(value)->value();
}
return value;
......
......@@ -2609,7 +2609,7 @@ static Object* Runtime_KeyedGetProperty(Arguments args) {
if ((entry != Dictionary::kNotFound) &&
(dictionary->DetailsAt(entry).type() == NORMAL)) {
Object* value = dictionary->ValueAt(entry);
if (receiver->IsJSGlobalObject()) {
if (receiver->IsGlobalObject()) {
value = JSGlobalPropertyCell::cast(value)->value();
}
return value;
......
......@@ -173,7 +173,7 @@ Object* StubCache::ComputeLoadNormal(String* name, JSObject* receiver) {
Object* StubCache::ComputeLoadGlobal(String* name,
JSGlobalObject* receiver,
GlobalObject* receiver,
JSGlobalPropertyCell* cell,
bool is_dont_delete) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
......@@ -336,7 +336,7 @@ Object* StubCache::ComputeStoreField(String* name,
Object* StubCache::ComputeStoreGlobal(String* name,
JSGlobalObject* receiver,
GlobalObject* receiver,
JSGlobalPropertyCell* cell) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
Object* code = receiver->map()->FindInCodeCache(name, flags);
......@@ -537,7 +537,7 @@ Object* StubCache::ComputeCallNormal(int argc,
Object* StubCache::ComputeCallGlobal(int argc,
InLoopFlag in_loop,
String* name,
JSGlobalObject* receiver,
GlobalObject* receiver,
JSGlobalPropertyCell* cell,
JSFunction* function) {
Code::Flags flags =
......
......@@ -79,7 +79,7 @@ class StubCache : public AllStatic {
static Object* ComputeLoadGlobal(String* name,
JSGlobalObject* receiver,
GlobalObject* receiver,
JSGlobalPropertyCell* cell,
bool is_dont_delete);
......@@ -119,7 +119,7 @@ class StubCache : public AllStatic {
Map* transition = NULL);
static Object* ComputeStoreGlobal(String* name,
JSGlobalObject* receiver,
GlobalObject* receiver,
JSGlobalPropertyCell* cell);
static Object* ComputeStoreCallback(String* name,
......@@ -164,7 +164,7 @@ class StubCache : public AllStatic {
static Object* ComputeCallGlobal(int argc,
InLoopFlag in_loop,
String* name,
JSGlobalObject* receiver,
GlobalObject* receiver,
JSGlobalPropertyCell* cell,
JSFunction* function);
......@@ -433,7 +433,7 @@ class LoadStubCompiler: public StubCompiler {
JSObject* holder,
String* name);
Object* CompileLoadGlobal(JSGlobalObject* object,
Object* CompileLoadGlobal(GlobalObject* object,
JSGlobalPropertyCell* holder,
String* name,
bool is_dont_delete);
......@@ -479,7 +479,7 @@ class StoreStubCompiler: public StubCompiler {
AccessorInfo* callbacks,
String* name);
Object* CompileStoreInterceptor(JSObject* object, String* name);
Object* CompileStoreGlobal(JSGlobalObject* object,
Object* CompileStoreGlobal(GlobalObject* object,
JSGlobalPropertyCell* holder,
String* name);
......@@ -517,7 +517,7 @@ class CallStubCompiler: public StubCompiler {
Object* CompileCallInterceptor(Object* object,
JSObject* holder,
String* name);
Object* CompileCallGlobal(JSGlobalObject* object,
Object* CompileCallGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
JSFunction* function,
String* name);
......
......@@ -65,7 +65,7 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* a,
Object* CallStubCompiler::CompileCallGlobal(JSGlobalObject* object,
Object* CallStubCompiler::CompileCallGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
JSFunction* function,
String* name) {
......@@ -109,7 +109,7 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* a,
}
Object* LoadStubCompiler::CompileLoadGlobal(JSGlobalObject* object,
Object* LoadStubCompiler::CompileLoadGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
String* name,
bool is_dont_delete) {
......@@ -141,7 +141,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* a, String* b) {
}
Object* StoreStubCompiler::CompileStoreGlobal(JSGlobalObject* object,
Object* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
JSGlobalPropertyCell* cell,
String* name) {
UNIMPLEMENTED();
......
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