From 5267d7b884be41aea02449e383212f9611cc31b2 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Tue, 5 Nov 2013 12:11:27 +0000 Subject: [PATCH] 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 --- src/factory.cc | 20 ++++++++++++++++++++ src/factory.h | 4 ++++ src/heap.cc | 37 ++----------------------------------- src/heap.h | 3 --- src/objects.cc | 9 +++++++++ src/objects.h | 1 + src/runtime.cc | 16 +++++++--------- 7 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/factory.cc b/src/factory.cc index c0b4f53..7886627 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -583,6 +583,12 @@ Handle Factory::NewFunctionPrototype(Handle function) { } +Handle Factory::NewInitialMap(Handle function) { + CALL_HEAP_FUNCTION( + isolate(), isolate()->heap()->AllocateInitialMap(*function), Map); +} + + Handle Factory::CopyWithPreallocatedFieldDescriptors(Handle src) { CALL_HEAP_FUNCTION( isolate(), src->CopyWithPreallocatedFieldDescriptors(), Map); @@ -1050,6 +1056,7 @@ Handle Factory::InternalizedStringFromString(Handle value) { Handle Factory::NewJSObject(Handle constructor, PretenureFlag pretenure) { + JSFunction::EnsureHasInitialMap(constructor); CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); @@ -1196,6 +1203,19 @@ void Factory::SetContent(Handle array, } +Handle Factory::NewJSGeneratorObject( + Handle function) { + ASSERT(function->shared()->is_generator()); + JSFunction::EnsureHasInitialMap(function); + Handle map(function->initial_map()); + ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE); + CALL_HEAP_FUNCTION( + isolate(), + isolate()->heap()->AllocateJSObjectFromMap(*map), + JSGeneratorObject); +} + + Handle Factory::NewJSArrayBuffer() { Handle array_buffer_fun( isolate()->context()->native_context()->array_buffer_fun()); diff --git a/src/factory.h b/src/factory.h index 47a8f43..2e02ed1 100644 --- a/src/factory.h +++ b/src/factory.h @@ -263,6 +263,8 @@ class Factory { Handle NewFunctionPrototype(Handle function); + Handle NewInitialMap(Handle function); + Handle CopyWithPreallocatedFieldDescriptors(Handle map); // Copy the map adding more inobject properties if possible without @@ -343,6 +345,8 @@ class Factory { void SetContent(Handle array, Handle elements); + Handle NewJSGeneratorObject(Handle function); + Handle NewJSArrayBuffer(); Handle NewJSTypedArray(ExternalArrayType type); diff --git a/src/heap.cc b/src/heap.cc index f7751c1..7f5d323 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -4640,15 +4640,7 @@ MaybeObject* Heap::AllocateJSObjectFromMapWithAllocationSite( MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, PretenureFlag pretenure) { - // Allocate the initial map if absent. - 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); - } + ASSERT(constructor->has_initial_map()); // Allocate the object based on the constructors initial map. MaybeObject* result = AllocateJSObjectFromMap( constructor->initial_map(), pretenure); @@ -4663,15 +4655,7 @@ MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, Handle allocation_site) { - // Allocate the initial map if absent. - 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); - } + ASSERT(constructor->has_initial_map()); // Allocate the object based on the constructors initial map, or the payload // advice Map* initial_map = constructor->initial_map(); @@ -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) { // Allocate a fresh map. Modules do not have a prototype. Map* map; diff --git a/src/heap.h b/src/heap.h index 3a02955..a18525c 100644 --- a/src/heap.h +++ b/src/heap.h @@ -631,9 +631,6 @@ class Heap { JSFunction* constructor, Handle allocation_site); - MUST_USE_RESULT MaybeObject* AllocateJSGeneratorObject( - JSFunction* function); - MUST_USE_RESULT MaybeObject* AllocateJSModule(Context* context, ScopeInfo* scope_info); diff --git a/src/objects.cc b/src/objects.cc index 57adb19..6f371a8 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -9885,6 +9885,15 @@ void JSFunction::RemovePrototype() { } +void JSFunction::EnsureHasInitialMap(Handle function) { + if (function->has_initial_map()) return; + Isolate* isolate = function->GetIsolate(); + Handle initial_map = isolate->factory()->NewInitialMap(function); + function->set_initial_map(*initial_map); + initial_map->set_constructor(*function); +} + + void JSFunction::SetInstanceClassName(String* name) { shared()->set_instance_class_name(name); } diff --git a/src/objects.h b/src/objects.h index 64f6a4f..e7586f5 100644 --- a/src/objects.h +++ b/src/objects.h @@ -7279,6 +7279,7 @@ class JSFunction: public JSObject { inline Map* initial_map(); inline void set_initial_map(Map* value); inline bool has_initial_map(); + static void EnsureHasInitialMap(Handle function); // Get and set the prototype property on a JSFunction. If the // function has an initial map the prototype is set on the initial diff --git a/src/runtime.cc b/src/runtime.cc index 51a27ab..dd36a53 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -2974,30 +2974,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) { RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) { - SealHandleScope shs(isolate); + HandleScope scope(isolate); ASSERT(args.length() == 0); JavaScriptFrameIterator it(isolate); JavaScriptFrame* frame = it.frame(); - JSFunction* function = frame->function(); + Handle function(frame->function()); RUNTIME_ASSERT(function->shared()->is_generator()); - JSGeneratorObject* generator; + Handle generator; if (frame->IsConstructor()) { - generator = JSGeneratorObject::cast(frame->receiver()); + generator = handle(JSGeneratorObject::cast(frame->receiver())); } else { - MaybeObject* maybe_generator = - isolate->heap()->AllocateJSGeneratorObject(function); - if (!maybe_generator->To(&generator)) return maybe_generator; + generator = isolate->factory()->NewJSGeneratorObject(function); } - generator->set_function(function); + generator->set_function(*function); generator->set_context(Context::cast(frame->context())); generator->set_receiver(frame->receiver()); generator->set_continuation(0); generator->set_operand_stack(isolate->heap()->empty_fixed_array()); generator->set_stack_handler_index(-1); - return generator; + return *generator; } -- 2.7.4