From: rossberg@chromium.org Date: Wed, 5 Oct 2011 09:41:54 +0000 (+0000) Subject: Make 'Become' safe for retries. X-Git-Tag: upstream/4.7.83~18285 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2c975d6ae2187847f8975bce588d6da450e66082;p=platform%2Fupstream%2Fv8.git Make 'Become' safe for retries. R=ricow@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/8138003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9524 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/factory.cc b/src/factory.cc index 00fc6bb..252c97c 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -948,6 +948,13 @@ void Factory::BecomeJSFunction(Handle object) { } +void Factory::SetIdentityHash(Handle object, Object* hash) { + CALL_HEAP_FUNCTION_VOID( + isolate(), + object->SetIdentityHash(hash, ALLOW_CREATION)); +} + + Handle Factory::NewSharedFunctionInfo( Handle name, int number_of_literals, diff --git a/src/factory.h b/src/factory.h index 3c45291..85f46c5 100644 --- a/src/factory.h +++ b/src/factory.h @@ -265,6 +265,8 @@ class Factory { void BecomeJSObject(Handle object); void BecomeJSFunction(Handle object); + void SetIdentityHash(Handle object, Object* hash); + Handle NewFunction(Handle name, Handle prototype); diff --git a/src/heap.cc b/src/heap.cc index 522861d..8674ba0 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -3321,9 +3321,9 @@ MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) { } -MaybeObject* Heap::InitializeFunction(JSFunction* function, - SharedFunctionInfo* shared, - Object* prototype) { +void Heap::InitializeFunction(JSFunction* function, + SharedFunctionInfo* shared, + Object* prototype) { ASSERT(!prototype->IsMap()); function->initialize_properties(); function->initialize_elements(); @@ -3333,7 +3333,6 @@ MaybeObject* Heap::InitializeFunction(JSFunction* function, function->set_context(undefined_value()); function->set_literals(empty_fixed_array()); function->set_next_function_link(undefined_value()); - return function; } @@ -3379,7 +3378,8 @@ MaybeObject* Heap::AllocateFunction(Map* function_map, { MaybeObject* maybe_result = Allocate(function_map, space); if (!maybe_result->ToObject(&result)) return maybe_result; } - return InitializeFunction(JSFunction::cast(result), shared, prototype); + InitializeFunction(JSFunction::cast(result), shared, prototype); + return result; } @@ -3819,9 +3819,6 @@ MaybeObject* Heap::ReinitializeJSReceiver( JSReceiver* object, InstanceType type, int size) { ASSERT(type >= FIRST_JS_OBJECT_TYPE); - // Save identity hash. - MaybeObject* maybe_hash = object->GetIdentityHash(OMIT_CREATION); - // Allocate fresh map. // TODO(rossberg): Once we optimize proxies, cache these maps. Map* map; @@ -3837,10 +3834,22 @@ MaybeObject* Heap::ReinitializeJSReceiver( // Allocate the backing storage for the properties. int prop_size = map->unused_property_fields() - map->inobject_properties(); Object* properties; - { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, TENURED); - if (!maybe_properties->ToObject(&properties)) return maybe_properties; + maybe = AllocateFixedArray(prop_size, TENURED); + if (!maybe->ToObject(&properties)) return maybe; + + // Functions require some allocation, which might fail here. + SharedFunctionInfo* shared = NULL; + if (type == JS_FUNCTION_TYPE) { + String* name; + maybe = LookupAsciiSymbol(""); + if (!maybe->To(&name)) return maybe; + maybe = AllocateSharedFunctionInfo(name); + if (!maybe->To(&shared)) return maybe; } + // Because of possible retries of this function after failure, + // we must NOT fail after this point, where we have changed the type! + // Reset the map for the object. object->set_map(map); JSObject* jsobj = JSObject::cast(object); @@ -3851,17 +3860,9 @@ MaybeObject* Heap::ReinitializeJSReceiver( // Functions require some minimal initialization. if (type == JS_FUNCTION_TYPE) { map->set_function_with_prototype(true); - String* name; - maybe = LookupAsciiSymbol(""); - if (!maybe->To(&name)) return maybe; - SharedFunctionInfo* shared; - maybe = AllocateSharedFunctionInfo(name); - if (!maybe->To(&shared)) return maybe; - JSFunction* func; - maybe = InitializeFunction( - JSFunction::cast(object), shared, the_hole_value()); - if (!maybe->To(&func)) return maybe; - func->set_context(isolate()->context()->global_context()); + InitializeFunction(JSFunction::cast(object), shared, the_hole_value()); + JSFunction::cast(object)->set_context( + isolate()->context()->global_context()); } // Put in filler if the new object is smaller than the old. @@ -3870,13 +3871,6 @@ MaybeObject* Heap::ReinitializeJSReceiver( object->address() + map->instance_size(), size_difference); } - // Inherit identity, if it was present. - Object* hash; - if (maybe_hash->To(&hash) && hash->IsSmi()) { - maybe = jsobj->SetIdentityHash(hash, ALLOW_CREATION); - if (maybe->IsFailure()) return maybe; - } - return object; } diff --git a/src/heap.h b/src/heap.h index 4a1e01d..499c30e 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1685,12 +1685,11 @@ class Heap { static void ScavengeObjectSlow(HeapObject** p, HeapObject* object); // Initializes a function with a shared part and prototype. - // Returns the function. // Note: this code was factored out of AllocateFunction such that // other parts of the VM could use it. Specifically, a function that creates // instances of type JS_FUNCTION_TYPE benefit from the use of this function. // Please note this does not perform a garbage collection. - MUST_USE_RESULT inline MaybeObject* InitializeFunction( + inline void InitializeFunction( JSFunction* function, SharedFunctionInfo* shared, Object* prototype); diff --git a/src/objects.cc b/src/objects.cc index 105dfd1..3e280fd 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2606,6 +2606,9 @@ void JSProxy::Fix() { HandleScope scope(isolate); Handle self(this); + // Save identity hash. + MaybeObject* maybe_hash = GetIdentityHash(OMIT_CREATION); + if (IsJSFunctionProxy()) { isolate->factory()->BecomeJSFunction(self); // Code will be set on the JavaScript side. @@ -2613,6 +2616,13 @@ void JSProxy::Fix() { isolate->factory()->BecomeJSObject(self); } ASSERT(self->IsJSObject()); + + // Inherit identity, if it was present. + Object* hash; + if (maybe_hash->To(&hash) && hash->IsSmi()) { + Handle new_self(JSObject::cast(*self)); + isolate->factory()->SetIdentityHash(new_self, hash); + } }