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