Introduce JSFunction::EnsureHasInitialMap method.

This change enforces explicit allocation of the initial map for each
JSFunction to introduce a proper layering between the JSFunction class
and the Heap class. A follow-up change will then handlify the two
functions AllocateInitialMap and AllocateFunctionPrototype.

R=rossberg@chromium.org
BUG=v8:2877

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17480 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 74ad230a
...@@ -583,6 +583,12 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { ...@@ -583,6 +583,12 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
} }
Handle<Map> Factory::NewInitialMap(Handle<JSFunction> function) {
CALL_HEAP_FUNCTION(
isolate(), isolate()->heap()->AllocateInitialMap(*function), Map);
}
Handle<Map> Factory::CopyWithPreallocatedFieldDescriptors(Handle<Map> src) { Handle<Map> Factory::CopyWithPreallocatedFieldDescriptors(Handle<Map> src) {
CALL_HEAP_FUNCTION( CALL_HEAP_FUNCTION(
isolate(), src->CopyWithPreallocatedFieldDescriptors(), Map); isolate(), src->CopyWithPreallocatedFieldDescriptors(), Map);
...@@ -1050,6 +1056,7 @@ Handle<String> Factory::InternalizedStringFromString(Handle<String> value) { ...@@ -1050,6 +1056,7 @@ Handle<String> Factory::InternalizedStringFromString(Handle<String> value) {
Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
PretenureFlag pretenure) { PretenureFlag pretenure) {
JSFunction::EnsureHasInitialMap(constructor);
CALL_HEAP_FUNCTION( CALL_HEAP_FUNCTION(
isolate(), isolate(),
isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject);
...@@ -1196,6 +1203,19 @@ void Factory::SetContent(Handle<JSArray> array, ...@@ -1196,6 +1203,19 @@ void Factory::SetContent(Handle<JSArray> array,
} }
Handle<JSGeneratorObject> Factory::NewJSGeneratorObject(
Handle<JSFunction> function) {
ASSERT(function->shared()->is_generator());
JSFunction::EnsureHasInitialMap(function);
Handle<Map> map(function->initial_map());
ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateJSObjectFromMap(*map),
JSGeneratorObject);
}
Handle<JSArrayBuffer> Factory::NewJSArrayBuffer() { Handle<JSArrayBuffer> Factory::NewJSArrayBuffer() {
Handle<JSFunction> array_buffer_fun( Handle<JSFunction> array_buffer_fun(
isolate()->context()->native_context()->array_buffer_fun()); isolate()->context()->native_context()->array_buffer_fun());
......
...@@ -263,6 +263,8 @@ class Factory { ...@@ -263,6 +263,8 @@ class Factory {
Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function); Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);
Handle<Map> NewInitialMap(Handle<JSFunction> function);
Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map); Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map);
// Copy the map adding more inobject properties if possible without // Copy the map adding more inobject properties if possible without
...@@ -343,6 +345,8 @@ class Factory { ...@@ -343,6 +345,8 @@ class Factory {
void SetContent(Handle<JSArray> array, Handle<FixedArrayBase> elements); void SetContent(Handle<JSArray> array, Handle<FixedArrayBase> elements);
Handle<JSGeneratorObject> NewJSGeneratorObject(Handle<JSFunction> function);
Handle<JSArrayBuffer> NewJSArrayBuffer(); Handle<JSArrayBuffer> NewJSArrayBuffer();
Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type); Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type);
......
...@@ -4640,15 +4640,7 @@ MaybeObject* Heap::AllocateJSObjectFromMapWithAllocationSite( ...@@ -4640,15 +4640,7 @@ MaybeObject* Heap::AllocateJSObjectFromMapWithAllocationSite(
MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
PretenureFlag pretenure) { PretenureFlag pretenure) {
// Allocate the initial map if absent. ASSERT(constructor->has_initial_map());
if (!constructor->has_initial_map()) {
Object* initial_map;
{ MaybeObject* maybe_initial_map = AllocateInitialMap(constructor);
if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map;
}
constructor->set_initial_map(Map::cast(initial_map));
Map::cast(initial_map)->set_constructor(constructor);
}
// Allocate the object based on the constructors initial map. // Allocate the object based on the constructors initial map.
MaybeObject* result = AllocateJSObjectFromMap( MaybeObject* result = AllocateJSObjectFromMap(
constructor->initial_map(), pretenure); constructor->initial_map(), pretenure);
...@@ -4663,15 +4655,7 @@ MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, ...@@ -4663,15 +4655,7 @@ MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor,
Handle<AllocationSite> allocation_site) { Handle<AllocationSite> allocation_site) {
// Allocate the initial map if absent. ASSERT(constructor->has_initial_map());
if (!constructor->has_initial_map()) {
Object* initial_map;
{ MaybeObject* maybe_initial_map = AllocateInitialMap(constructor);
if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map;
}
constructor->set_initial_map(Map::cast(initial_map));
Map::cast(initial_map)->set_constructor(constructor);
}
// Allocate the object based on the constructors initial map, or the payload // Allocate the object based on the constructors initial map, or the payload
// advice // advice
Map* initial_map = constructor->initial_map(); Map* initial_map = constructor->initial_map();
...@@ -4703,23 +4687,6 @@ MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, ...@@ -4703,23 +4687,6 @@ MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor,
} }
MaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) {
ASSERT(function->shared()->is_generator());
Map *map;
if (function->has_initial_map()) {
map = function->initial_map();
} else {
// Allocate the initial map if absent.
MaybeObject* maybe_map = AllocateInitialMap(function);
if (!maybe_map->To(&map)) return maybe_map;
function->set_initial_map(map);
map->set_constructor(function);
}
ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
return AllocateJSObjectFromMap(map);
}
MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) { MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) {
// Allocate a fresh map. Modules do not have a prototype. // Allocate a fresh map. Modules do not have a prototype.
Map* map; Map* map;
......
...@@ -631,9 +631,6 @@ class Heap { ...@@ -631,9 +631,6 @@ class Heap {
JSFunction* constructor, JSFunction* constructor,
Handle<AllocationSite> allocation_site); Handle<AllocationSite> allocation_site);
MUST_USE_RESULT MaybeObject* AllocateJSGeneratorObject(
JSFunction* function);
MUST_USE_RESULT MaybeObject* AllocateJSModule(Context* context, MUST_USE_RESULT MaybeObject* AllocateJSModule(Context* context,
ScopeInfo* scope_info); ScopeInfo* scope_info);
......
...@@ -9885,6 +9885,15 @@ void JSFunction::RemovePrototype() { ...@@ -9885,6 +9885,15 @@ void JSFunction::RemovePrototype() {
} }
void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
if (function->has_initial_map()) return;
Isolate* isolate = function->GetIsolate();
Handle<Map> initial_map = isolate->factory()->NewInitialMap(function);
function->set_initial_map(*initial_map);
initial_map->set_constructor(*function);
}
void JSFunction::SetInstanceClassName(String* name) { void JSFunction::SetInstanceClassName(String* name) {
shared()->set_instance_class_name(name); shared()->set_instance_class_name(name);
} }
......
...@@ -7279,6 +7279,7 @@ class JSFunction: public JSObject { ...@@ -7279,6 +7279,7 @@ class JSFunction: public JSObject {
inline Map* initial_map(); inline Map* initial_map();
inline void set_initial_map(Map* value); inline void set_initial_map(Map* value);
inline bool has_initial_map(); inline bool has_initial_map();
static void EnsureHasInitialMap(Handle<JSFunction> function);
// Get and set the prototype property on a JSFunction. If the // Get and set the prototype property on a JSFunction. If the
// function has an initial map the prototype is set on the initial // function has an initial map the prototype is set on the initial
......
...@@ -2974,30 +2974,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) { ...@@ -2974,30 +2974,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) { RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
SealHandleScope shs(isolate); HandleScope scope(isolate);
ASSERT(args.length() == 0); ASSERT(args.length() == 0);
JavaScriptFrameIterator it(isolate); JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame(); JavaScriptFrame* frame = it.frame();
JSFunction* function = frame->function(); Handle<JSFunction> function(frame->function());
RUNTIME_ASSERT(function->shared()->is_generator()); RUNTIME_ASSERT(function->shared()->is_generator());
JSGeneratorObject* generator; Handle<JSGeneratorObject> generator;
if (frame->IsConstructor()) { if (frame->IsConstructor()) {
generator = JSGeneratorObject::cast(frame->receiver()); generator = handle(JSGeneratorObject::cast(frame->receiver()));
} else { } else {
MaybeObject* maybe_generator = generator = isolate->factory()->NewJSGeneratorObject(function);
isolate->heap()->AllocateJSGeneratorObject(function);
if (!maybe_generator->To(&generator)) return maybe_generator;
} }
generator->set_function(function); generator->set_function(*function);
generator->set_context(Context::cast(frame->context())); generator->set_context(Context::cast(frame->context()));
generator->set_receiver(frame->receiver()); generator->set_receiver(frame->receiver());
generator->set_continuation(0); generator->set_continuation(0);
generator->set_operand_stack(isolate->heap()->empty_fixed_array()); generator->set_operand_stack(isolate->heap()->empty_fixed_array());
generator->set_stack_handler_index(-1); generator->set_stack_handler_index(-1);
return generator; return *generator;
} }
......
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