Restore invariant (next of first deallocated must point to the head) before calling into weak
callbacks. Otherwise if callback allocates a new handle, it could orphan some global handles (with disastorous consequences if those global handles are cached). Review URL: http://codereview.chromium.org/395024 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3318 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
41749529dd
commit
9a545949a4
@ -165,6 +165,9 @@ class GlobalHandles::Node : public Malloced {
|
||||
// It's fine though to reuse nodes that were destroyed in weak callback
|
||||
// as those cannot be deallocated until we are back from the callback.
|
||||
set_first_free(NULL);
|
||||
if (first_deallocated()) {
|
||||
first_deallocated()->set_next(head());
|
||||
}
|
||||
// Leaving V8.
|
||||
VMState state(EXTERNAL);
|
||||
func(object, par);
|
||||
@ -270,6 +273,7 @@ Handle<Object> GlobalHandles::Create(Object* value) {
|
||||
// Next try deallocated list
|
||||
result = first_deallocated();
|
||||
set_first_deallocated(result->next_free());
|
||||
ASSERT(result->next() == head());
|
||||
set_head(result);
|
||||
} else {
|
||||
// Allocate a new node.
|
||||
|
@ -6226,6 +6226,31 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
|
||||
i::Heap::CollectAllGarbage(false);
|
||||
}
|
||||
|
||||
void DisposingCallback(v8::Persistent<v8::Value> handle, void*) {
|
||||
handle.Dispose();
|
||||
}
|
||||
|
||||
void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) {
|
||||
v8::HandleScope scope;
|
||||
v8::Persistent<v8::Object>::New(v8::Object::New());
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
|
||||
LocalContext context;
|
||||
|
||||
v8::Persistent<v8::Object> handle1, handle2, handle3;
|
||||
{
|
||||
v8::HandleScope scope;
|
||||
handle3 = v8::Persistent<v8::Object>::New(v8::Object::New());
|
||||
handle2 = v8::Persistent<v8::Object>::New(v8::Object::New());
|
||||
handle1 = v8::Persistent<v8::Object>::New(v8::Object::New());
|
||||
}
|
||||
handle2.MakeWeak(NULL, DisposingCallback);
|
||||
handle3.MakeWeak(NULL, HandleCreatingCallback);
|
||||
i::Heap::CollectAllGarbage(false);
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(CheckForCrossContextObjectLiterals) {
|
||||
v8::V8::Initialize();
|
||||
|
Loading…
Reference in New Issue
Block a user