From: mstarzinger@chromium.org Date: Thu, 18 Jul 2013 07:59:48 +0000 (+0000) Subject: Handlify JSFunction::SetPrototype method. X-Git-Tag: upstream/4.7.83~13319 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=13f7c56e05ea4e3172b570ede5bd3c62546e0d4e;p=platform%2Fupstream%2Fv8.git Handlify JSFunction::SetPrototype method. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/19594002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15738 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/accessors.cc b/src/accessors.cc index e441de4..648f113 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -450,26 +450,23 @@ Handle Accessors::FunctionGetPrototype(Handle object) { MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) { Isolate* isolate = Isolate::Current(); - JSFunction* function = FindInstanceOf(isolate, object); - if (function == NULL) return isolate->heap()->undefined_value(); - while (!function->should_have_prototype()) { - function = FindInstanceOf(isolate, function->GetPrototype()); + JSFunction* function_raw = FindInstanceOf(isolate, object); + if (function_raw == NULL) return isolate->heap()->undefined_value(); + while (!function_raw->should_have_prototype()) { + function_raw = FindInstanceOf(isolate, + function_raw->GetPrototype()); // There has to be one because we hit the getter. - ASSERT(function != NULL); + ASSERT(function_raw != NULL); } - if (!function->has_prototype()) { - Object* prototype; - { MaybeObject* maybe_prototype - = isolate->heap()->AllocateFunctionPrototype(function); - if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; - } - Object* result; - { MaybeObject* maybe_result = function->SetPrototype(prototype); - if (!maybe_result->ToObject(&result)) return maybe_result; - } + if (!function_raw->has_prototype()) { + HandleScope scope(isolate); + Handle function(function_raw); + Handle proto = isolate->factory()->NewFunctionPrototype(function); + JSFunction::SetPrototype(function, proto); + function_raw = *function; } - return function->prototype(); + return function_raw->prototype(); } @@ -503,9 +500,7 @@ MaybeObject* Accessors::FunctionSetPrototype(JSObject* object, old_value = isolate->factory()->NewFunctionPrototype(function); } - Handle result; - MaybeObject* maybe_result = function->SetPrototype(*value); - if (!maybe_result->ToHandle(&result, isolate)) return maybe_result; + JSFunction::SetPrototype(function, value); ASSERT(function->prototype() == *value); if (is_observed && !old_value->SameValue(*value)) { diff --git a/src/accessors.h b/src/accessors.h index 9a83ab8..a7e67b5 100644 --- a/src/accessors.h +++ b/src/accessors.h @@ -77,8 +77,6 @@ class Accessors : public AllStatic { }; // Accessor functions called directly from the runtime system. - MUST_USE_RESULT static MaybeObject* FunctionGetPrototype(Object* object, - void*); static Handle FunctionGetPrototype(Handle object); MUST_USE_RESULT static MaybeObject* FunctionSetPrototype(JSObject* object, @@ -95,6 +93,7 @@ class Accessors : public AllStatic { static MaybeObject* FunctionGetLength(Object* object, void*); static MaybeObject* FunctionGetName(Object* object, void*); static MaybeObject* FunctionGetCaller(Object* object, void*); + static MaybeObject* FunctionGetPrototype(Object* object, void*); MUST_USE_RESULT static MaybeObject* ArraySetLength(JSObject* object, Object* value, void*); static MaybeObject* ArrayGetLength(Object* object, void*); diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 249b31c..d8d065c 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -200,7 +200,7 @@ class Genesis BASE_EMBEDDED { // detached from the other objects in the snapshot. void HookUpInnerGlobal(Handle inner_global); // New context initialization. Used for creating a context from scratch. - bool InitializeGlobal(Handle inner_global, + void InitializeGlobal(Handle inner_global, Handle empty_function); void InitializeExperimentalGlobal(); // Installs the contents of the native .js files on the global objects. @@ -829,7 +829,7 @@ void Genesis::HookUpInnerGlobal(Handle inner_global) { // This is only called if we are not using snapshots. The equivalent // work in the snapshot case is done in HookUpInnerGlobal. -bool Genesis::InitializeGlobal(Handle inner_global, +void Genesis::InitializeGlobal(Handle inner_global, Handle empty_function) { // --- G l o b a l C o n t e x t --- // Use the empty function as closure (no scope info). @@ -1053,10 +1053,8 @@ bool Genesis::InitializeGlobal(Handle inner_global, Handle name = factory->NewStringFromAscii(CStrVector("JSON")); Handle cons = factory->NewFunction(name, factory->the_hole_value()); - { MaybeObject* result = cons->SetInstancePrototype( - native_context()->initial_object_prototype()); - if (result->IsFailure()) return false; - } + JSFunction::SetInstancePrototype(cons, + Handle(native_context()->initial_object_prototype(), isolate)); cons->SetInstanceClassName(*name); Handle json_object = factory->NewJSObject(cons, TENURED); ASSERT(json_object->IsJSObject()); @@ -1277,7 +1275,6 @@ bool Genesis::InitializeGlobal(Handle inner_global, native_context()->set_random_seed(*zeroed_byte_array); memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize); } - return true; } @@ -2632,7 +2629,7 @@ Genesis::Genesis(Isolate* isolate, Handle global_proxy = CreateNewGlobals(global_template, global_object, &inner_global); HookUpGlobalProxy(inner_global, global_proxy); - if (!InitializeGlobal(inner_global, empty_function)) return; + InitializeGlobal(inner_global, empty_function); InstallJSFunctionResultCaches(); InitializeNormalizedMapCaches(); if (!InstallNatives()) return; diff --git a/src/factory.cc b/src/factory.cc index dc07768..b135a9c 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -935,7 +935,7 @@ Handle Factory::NewFunctionWithPrototype(Handle name, initial_map->set_constructor(*function); } - SetPrototypeProperty(function, prototype); + JSFunction::SetPrototype(function, prototype); return function; } diff --git a/src/handles.cc b/src/handles.cc index c02801f..48114d9 100644 --- a/src/handles.cc +++ b/src/handles.cc @@ -169,12 +169,6 @@ void SetExpectedNofProperties(Handle func, int nof) { } -void SetPrototypeProperty(Handle func, Handle value) { - CALL_HEAP_FUNCTION_VOID(func->GetIsolate(), - func->SetPrototype(*value)); -} - - static int ExpectedNofPropertiesFromEstimate(int estimate) { // If no properties are added in the constructor, they are more likely // to be added later. diff --git a/src/handles.h b/src/handles.h index 140c34e..90db7d1 100644 --- a/src/handles.h +++ b/src/handles.h @@ -313,9 +313,6 @@ Handle SubString(Handle str, // Sets the expected number of properties for the function's instances. void SetExpectedNofProperties(Handle func, int nof); -// Sets the prototype property for a function instance. -void SetPrototypeProperty(Handle func, Handle value); - // Sets the expected number of properties based on estimate from compiler. void SetExpectedNofPropertiesFromEstimate(Handle shared, int estimate); diff --git a/src/objects.cc b/src/objects.cc index bb6b4fd..5f2a7b5 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -9532,57 +9532,53 @@ Handle CacheInitialJSArrayMaps(Handle native_context, } -MaybeObject* JSFunction::SetInstancePrototype(Object* value) { +void JSFunction::SetInstancePrototype(Handle function, + Handle value) { ASSERT(value->IsJSReceiver()); - Heap* heap = GetHeap(); // First some logic for the map of the prototype to make sure it is in fast // mode. if (value->IsJSObject()) { - MaybeObject* ok = JSObject::cast(value)->OptimizeAsPrototype(); - if (ok->IsFailure()) return ok; + JSObject::OptimizeAsPrototype(Handle::cast(value)); } // Now some logic for the maps of the objects that are created by using this // function as a constructor. - if (has_initial_map()) { + if (function->has_initial_map()) { // If the function has allocated the initial map replace it with a // copy containing the new prototype. Also complete any in-object // slack tracking that is in progress at this point because it is // still tracking the old copy. - if (shared()->IsInobjectSlackTrackingInProgress()) { - shared()->CompleteInobjectSlackTracking(); + if (function->shared()->IsInobjectSlackTrackingInProgress()) { + function->shared()->CompleteInobjectSlackTracking(); } - Map* new_map; - MaybeObject* maybe_object = initial_map()->Copy(); - if (!maybe_object->To(&new_map)) return maybe_object; - new_map->set_prototype(value); + Handle new_map = Map::Copy(handle(function->initial_map())); + new_map->set_prototype(*value); // If the function is used as the global Array function, cache the // initial map (and transitioned versions) in the native context. - Context* native_context = context()->native_context(); + Context* native_context = function->context()->native_context(); Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); if (array_function->IsJSFunction() && - this == JSFunction::cast(array_function)) { - MaybeObject* ok = CacheInitialJSArrayMaps(native_context, new_map); - if (ok->IsFailure()) return ok; + *function == JSFunction::cast(array_function)) { + CacheInitialJSArrayMaps(handle(native_context), new_map); } - set_initial_map(new_map); + function->set_initial_map(*new_map); } else { // Put the value in the initial map field until an initial map is // needed. At that point, a new initial map is created and the // prototype is put into the initial map where it belongs. - set_prototype_or_initial_map(value); + function->set_prototype_or_initial_map(*value); } - heap->ClearInstanceofCache(); - return value; + function->GetHeap()->ClearInstanceofCache(); } -MaybeObject* JSFunction::SetPrototype(Object* value) { - ASSERT(should_have_prototype()); - Object* construct_prototype = value; +void JSFunction::SetPrototype(Handle function, + Handle value) { + ASSERT(function->should_have_prototype()); + Handle construct_prototype = value; // If the value is not a JSReceiver, store the value in the map's // constructor field so it can be accessed. Also, set the prototype @@ -9592,22 +9588,20 @@ MaybeObject* JSFunction::SetPrototype(Object* value) { // Copy the map so this does not affect unrelated functions. // Remove map transitions because they point to maps with a // different prototype. - Map* new_map; - MaybeObject* maybe_new_map = map()->Copy(); - if (!maybe_new_map->To(&new_map)) return maybe_new_map; + Handle new_map = Map::Copy(handle(function->map())); - Heap* heap = new_map->GetHeap(); - set_map(new_map); - new_map->set_constructor(value); + function->set_map(*new_map); + new_map->set_constructor(*value); new_map->set_non_instance_prototype(true); - construct_prototype = - heap->isolate()->context()->native_context()-> - initial_object_prototype(); + Isolate* isolate = new_map->GetIsolate(); + construct_prototype = handle( + isolate->context()->native_context()->initial_object_prototype(), + isolate); } else { - map()->set_non_instance_prototype(false); + function->map()->set_non_instance_prototype(false); } - return SetInstancePrototype(construct_prototype); + return SetInstancePrototype(function, construct_prototype); } diff --git a/src/objects.h b/src/objects.h index 3f8ff36..08b1e10 100644 --- a/src/objects.h +++ b/src/objects.h @@ -6695,8 +6695,10 @@ class JSFunction: public JSObject { inline bool has_instance_prototype(); inline Object* prototype(); inline Object* instance_prototype(); - MUST_USE_RESULT MaybeObject* SetInstancePrototype(Object* value); - MUST_USE_RESULT MaybeObject* SetPrototype(Object* value); + static void SetPrototype(Handle function, + Handle value); + static void SetInstancePrototype(Handle function, + Handle value); // After prototype is removed, it will not be created when accessed, and // [[Construct]] from this function will not be allowed.