Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index da1f9c6df69e91103badedbfa6586d7f3a2814cf..522ffcf05bddf4da12e5b3a387680dfa7e52f53a 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -50,15 +50,19 @@ static bool IsNaN(double x) { |
#endif |
} |
-using ::v8::ObjectTemplate; |
-using ::v8::Value; |
+using ::v8::AccessorInfo; |
using ::v8::Context; |
+using ::v8::Extension; |
+using ::v8::Function; |
+using ::v8::HandleScope; |
using ::v8::Local; |
-using ::v8::String; |
+using ::v8::Object; |
+using ::v8::ObjectTemplate; |
+using ::v8::Persistent; |
using ::v8::Script; |
-using ::v8::Function; |
-using ::v8::AccessorInfo; |
-using ::v8::Extension; |
+using ::v8::String; |
+using ::v8::Value; |
+using ::v8::V8; |
namespace i = ::i; |
@@ -1789,6 +1793,98 @@ THREADED_TEST(GlobalHandle) { |
} |
+static int NumberOfWeakCalls = 0; |
+static void WeakPointerCallback(Persistent<Value> handle, void* id) { |
+ CHECK_EQ(reinterpret_cast<void*>(1234), id); |
+ NumberOfWeakCalls++; |
+ handle.Dispose(); |
+} |
+ |
+THREADED_TEST(ApiObjectGroups) { |
+ HandleScope scope; |
+ LocalContext env; |
+ |
+ NumberOfWeakCalls = 0; |
+ |
+ Persistent<Object> g1s1; |
+ Persistent<Object> g1s2; |
+ Persistent<Object> g1c1; |
+ Persistent<Object> g2s1; |
+ Persistent<Object> g2s2; |
+ Persistent<Object> g2c1; |
+ |
+ { |
+ HandleScope scope; |
+ g1s1 = Persistent<Object>::New(Object::New()); |
+ g1s2 = Persistent<Object>::New(Object::New()); |
+ g1c1 = Persistent<Object>::New(Object::New()); |
+ g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ |
+ g2s1 = Persistent<Object>::New(Object::New()); |
+ g2s2 = Persistent<Object>::New(Object::New()); |
+ g2c1 = Persistent<Object>::New(Object::New()); |
+ g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ } |
+ |
+ Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
+ |
+ // Connect group 1 and 2, make a cycle. |
+ CHECK(g1s2->Set(0, g2s2)); |
+ CHECK(g2s1->Set(0, g1s1)); |
+ |
+ { |
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
+ Persistent<Value> g1_children[] = { g1c1 }; |
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
+ Persistent<Value> g2_children[] = { g2c1 }; |
+ V8::AddObjectGroup(g1_objects, 2); |
+ V8::AddImplicitRefGroup(g1s1, g1_children, 1); |
+ V8::AddObjectGroup(g2_objects, 2); |
+ V8::AddImplicitRefGroup(g2s2, g2_children, 1); |
Vitaly Repeshko
2011/03/15 18:45:35
It would be interesting to test longer chains of i
|
+ } |
+ // Do a full GC |
+ i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); |
+ |
+ // All object should be alive. |
+ CHECK_EQ(0, NumberOfWeakCalls); |
+ |
+ // Weaken the root. |
+ root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ // But make children strong roots---all the objects (except for children) |
+ // should be collectable now. |
+ g1c1.ClearWeak(); |
+ g2c1.ClearWeak(); |
+ |
+ // Groups are deleted, rebuild groups. |
+ { |
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
+ Persistent<Value> g1_children[] = { g1c1 }; |
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
+ Persistent<Value> g2_children[] = { g2c1 }; |
+ V8::AddObjectGroup(g1_objects, 2); |
+ V8::AddImplicitRefGroup(g1s1, g1_children, 1); |
+ V8::AddObjectGroup(g2_objects, 2); |
+ V8::AddImplicitRefGroup(g2s2, g2_children, 1); |
+ } |
+ |
+ i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); |
+ |
+ // All objects should be gone. 5 global handles in total. |
+ CHECK_EQ(5, NumberOfWeakCalls); |
+ |
+ // And now make children weak again and collect them. |
+ g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
+ |
+ i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); |
+ CHECK_EQ(7, NumberOfWeakCalls); |
+} |
+ |
+ |
THREADED_TEST(ScriptException) { |
v8::HandleScope scope; |
LocalContext env; |