From 6da43b7e4d10854d14b79398246f78e5e6cb0d82 Mon Sep 17 00:00:00 2001 From: "antonm@chromium.org" Date: Thu, 29 Oct 2009 23:06:59 +0000 Subject: [PATCH] Add a test which verifies that weak reference callbacks cannot be invoked while scavenging. BUG=25819 Review URL: http://codereview.chromium.org/334043 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3179 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- test/cctest/test-api.cc | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 1d4b2c34c3..b3c8515fc0 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -3157,6 +3157,58 @@ THREADED_TEST(WeakReference) { } +static bool in_scavenge = false; +static int last = -1; + +static void ForceScavenge(v8::Persistent obj, void* data) { + CHECK_EQ(-1, last); + last = 0; + obj.Dispose(); + obj.Clear(); + in_scavenge = true; + i::Heap::PerformScavenge(); + in_scavenge = false; + *(reinterpret_cast(data)) = true; +} + +static void CheckIsNotInvokedInScavenge(v8::Persistent obj, + void* data) { + CHECK_EQ(0, last); + last = 1; + *(reinterpret_cast(data)) = in_scavenge; + obj.Dispose(); + obj.Clear(); +} + +THREADED_TEST(NoWeakRefCallbacksInScavenge) { + // Test verifies that scavenge cannot invoke WeakReferenceCallbacks. + // Calling callbacks from scavenges is unsafe as objects held by those + // handlers might have become strongly reachable, but scavenge doesn't + // check that. + v8::Persistent context = Context::New(); + Context::Scope context_scope(context); + + v8::Persistent object_a; + v8::Persistent object_b; + + { + v8::HandleScope handle_scope; + object_b = v8::Persistent::New(v8::Object::New()); + object_a = v8::Persistent::New(v8::Object::New()); + } + + bool object_a_disposed = false; + object_a.MakeWeak(&object_a_disposed, &ForceScavenge); + bool released_in_scavenge = false; + object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); + + while (!object_a_disposed) { + i::Heap::CollectAllGarbage(false); + } + CHECK(!released_in_scavenge); +} + + v8::Handle args_fun;