Revision: 9524
Author:   [email protected]
Date:     Wed Oct  5 02:41:54 2011
Log:      Make 'Become' safe for retries.

[email protected]
BUG=
TEST=

Review URL: http://codereview.chromium.org/8138003
http://code.google.com/p/v8/source/detail?r=9524

Modified:
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/factory.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/objects.cc

=======================================
--- /branches/bleeding_edge/src/factory.cc      Fri Sep 23 01:00:06 2011
+++ /branches/bleeding_edge/src/factory.cc      Wed Oct  5 02:41:54 2011
@@ -946,6 +946,13 @@
       isolate()->heap()->ReinitializeJSReceiver(
           *object, JS_FUNCTION_TYPE, JSFunction::kSize));
 }
+
+
+void Factory::SetIdentityHash(Handle<JSObject> object, Object* hash) {
+  CALL_HEAP_FUNCTION_VOID(
+      isolate(),
+      object->SetIdentityHash(hash, ALLOW_CREATION));
+}


 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
=======================================
--- /branches/bleeding_edge/src/factory.h       Fri Sep 23 01:00:06 2011
+++ /branches/bleeding_edge/src/factory.h       Wed Oct  5 02:41:54 2011
@@ -265,6 +265,8 @@
   void BecomeJSObject(Handle<JSReceiver> object);
   void BecomeJSFunction(Handle<JSReceiver> object);

+  void SetIdentityHash(Handle<JSObject> object, Object* hash);
+
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Object> prototype);

=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Sep 29 05:27:31 2011
+++ /branches/bleeding_edge/src/heap.cc Wed Oct  5 02:41:54 2011
@@ -3321,9 +3321,9 @@
 }


-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 @@
   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* 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 @@
     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,9 +3834,21 @@
   // 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("<freezing call trap>");
+    if (!maybe->To<String>(&name)) return maybe;
+    maybe = AllocateSharedFunctionInfo(name);
+    if (!maybe->To<SharedFunctionInfo>(&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);
@@ -3851,17 +3860,9 @@
   // Functions require some minimal initialization.
   if (type == JS_FUNCTION_TYPE) {
     map->set_function_with_prototype(true);
-    String* name;
-    maybe = LookupAsciiSymbol("<freezing call trap>");
-    if (!maybe->To<String>(&name)) return maybe;
-    SharedFunctionInfo* shared;
-    maybe = AllocateSharedFunctionInfo(name);
-    if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe;
-    JSFunction* func;
-    maybe = InitializeFunction(
-        JSFunction::cast(object), shared, the_hole_value());
-    if (!maybe->To<JSFunction>(&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.
@@ -3869,13 +3870,6 @@
     CreateFillerObjectAt(
         object->address() + map->instance_size(), size_difference);
   }
-
-  // Inherit identity, if it was present.
-  Object* hash;
-  if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) {
-    maybe = jsobj->SetIdentityHash(hash, ALLOW_CREATION);
-    if (maybe->IsFailure()) return maybe;
-  }

   return object;
 }
=======================================
--- /branches/bleeding_edge/src/heap.h  Thu Sep 29 05:27:31 2011
+++ /branches/bleeding_edge/src/heap.h  Wed Oct  5 02:41:54 2011
@@ -1685,12 +1685,11 @@
   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);
=======================================
--- /branches/bleeding_edge/src/objects.cc      Tue Oct  4 08:54:57 2011
+++ /branches/bleeding_edge/src/objects.cc      Wed Oct  5 02:41:54 2011
@@ -2606,6 +2606,9 @@
   HandleScope scope(isolate);
   Handle<JSProxy> 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 @@
     isolate->factory()->BecomeJSObject(self);
   }
   ASSERT(self->IsJSObject());
+
+  // Inherit identity, if it was present.
+  Object* hash;
+  if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) {
+    Handle<JSObject> new_self(JSObject::cast(*self));
+    isolate->factory()->SetIdentityHash(new_self, hash);
+  }
 }


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to