Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index cf84538d830120829bcee127a9e2be3a8998e0b0..7c6dade83ab5949cd03f3df3b09c7a837b94926b 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -4432,58 +4432,87 @@ THREADED_TEST(WeakReference) { |
} |
-static bool in_scavenge = false; |
-static int last = -1; |
- |
-static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
- CHECK_EQ(-1, last); |
- last = 0; |
+static void DisposeAndSetFlag(v8::Persistent<v8::Value> obj, void* data) { |
obj.Dispose(); |
obj.Clear(); |
- in_scavenge = true; |
- HEAP->PerformScavenge(); |
- in_scavenge = false; |
*(reinterpret_cast<bool*>(data)) = true; |
} |
-static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, |
- void* data) { |
- CHECK_EQ(0, last); |
- last = 1; |
- *(reinterpret_cast<bool*>(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. |
+THREADED_TEST(IndependentWeakHandle) { |
v8::Persistent<Context> context = Context::New(); |
Context::Scope context_scope(context); |
v8::Persistent<v8::Object> object_a; |
- v8::Persistent<v8::Object> object_b; |
{ |
v8::HandleScope handle_scope; |
- object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); |
object_a = v8::Persistent<v8::Object>::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); |
+ object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag); |
+ object_a.MarkIndependent(); |
+ HEAP->PerformScavenge(); |
+ CHECK(object_a_disposed); |
+} |
- while (!object_a_disposed) { |
- HEAP->CollectAllGarbage(false); |
+ |
+static void InvokeScavenge() { |
+ HEAP->PerformScavenge(); |
+} |
+ |
+ |
+static void InvokeMarkSweep() { |
+ HEAP->CollectAllGarbage(false); |
+} |
+ |
+ |
+static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
+ obj.Dispose(); |
+ obj.Clear(); |
+ *(reinterpret_cast<bool*>(data)) = true; |
+ InvokeScavenge(); |
+} |
+ |
+ |
+static void ForceMarkSweep(v8::Persistent<v8::Value> obj, void* data) { |
+ obj.Dispose(); |
+ obj.Clear(); |
+ *(reinterpret_cast<bool*>(data)) = true; |
+ InvokeMarkSweep(); |
+} |
+ |
+ |
+THREADED_TEST(GCFromWeakCallbacks) { |
Vitaly Repeshko
2011/05/16 21:40:37
Please add a test where an independent weak callba
Vyacheslav Egorov (Chromium)
2011/05/17 11:55:31
Done.
|
+ v8::Persistent<Context> context = Context::New(); |
+ Context::Scope context_scope(context); |
+ |
+ static const int kNumberOfGCTypes = 2; |
+ v8::WeakReferenceCallback gc_forcing_callback[kNumberOfGCTypes] = |
+ {&ForceScavenge, &ForceMarkSweep}; |
+ |
+ typedef void (*GCInvoker)(); |
+ GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; |
+ |
+ for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { |
Vitaly Repeshko
2011/05/16 21:40:37
Nice!
|
+ for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { |
+ v8::Persistent<v8::Object> object; |
+ { |
+ v8::HandleScope handle_scope; |
+ object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
+ } |
+ bool disposed = false; |
+ object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]); |
+ object.MarkIndependent(); |
+ invoke_gc[outer_gc](); |
+ CHECK(disposed); |
+ } |
} |
- CHECK(!released_in_scavenge); |
} |
Vitaly Repeshko
2011/05/16 21:40:37
nit: Remove extra blank line.
Vyacheslav Egorov (Chromium)
2011/05/17 11:55:31
Done.
|
+ |
v8::Handle<Function> args_fun; |