Chromium Code Reviews| Index: test/cctest/test-object-observe.cc |
| diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc |
| index a096828ff66dd13234d67a176b62d1faf6d09efb..f99abbdfab496b07b6c688368a4a171c9aecc66f 100644 |
| --- a/test/cctest/test-object-observe.cc |
| +++ b/test/cctest/test-object-observe.cc |
| @@ -613,3 +613,97 @@ TEST(GetNotifierFromSameOrigin) { |
| CHECK(CompileRun("Object.getNotifier(obj)")->IsObject()); |
| } |
| } |
| + |
| + |
| +static int GetGlobalObjectsCount() { |
| + CcTest::heap()->EnsureHeapIsIterable(); |
| + int count = 0; |
| + i::HeapIterator it(CcTest::heap()); |
| + for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) |
| + if (object->IsJSGlobalObject()) count++; |
| + return count; |
| +} |
| + |
| + |
| +static void CheckSurvivingGlobalObjectsCount(int expected) { |
| + // We need to collect all garbage twice to be sure that everything |
| + // has been collected. This is because inline caches are cleared in |
| + // the first garbage collection but some of the maps have already |
| + // been marked at that point. Therefore some of the maps are not |
| + // collected until the second garbage collection. |
| + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| + CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| + int count = GetGlobalObjectsCount(); |
| +#ifdef DEBUG |
| + if (count != expected) CcTest::heap()->TracePathToGlobal(); |
| +#endif |
| + CHECK_EQ(expected, count); |
| +} |
| + |
| + |
| +TEST(DontLeakContextOnObserve) { |
| + HandleScope scope(CcTest::isolate()); |
| + Handle<Value> foo = String::NewFromUtf8(CcTest::isolate(), "foo"); |
| + LocalContext context(CcTest::isolate()); |
| + context->SetSecurityToken(foo); |
| + CompileRun("var obj = {};"); |
| + Handle<Value> object = CompileRun("obj"); |
| + { |
| + HandleScope scope(CcTest::isolate()); |
| + LocalContext context2(CcTest::isolate()); |
| + context2->SetSecurityToken(foo); |
| + context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"), |
| + object); |
| + CompileRun("function observer() {};" |
| + "Object.observe(obj, observer, ['foo', 'bar', 'baz']);" |
| + "Object.unobserve(obj, observer);"); |
| + } |
| + |
| + v8::V8::ContextDisposedNotification(); |
| + CheckSurvivingGlobalObjectsCount(1); |
| +} |
| + |
| + |
| +TEST(DontLeakContextOnGetNotifier) { |
| + HandleScope scope(CcTest::isolate()); |
| + Handle<Value> foo = String::NewFromUtf8(CcTest::isolate(), "foo"); |
| + LocalContext context(CcTest::isolate()); |
| + context->SetSecurityToken(foo); |
| + CompileRun("var obj = {};"); |
| + Handle<Value> object = CompileRun("obj"); |
| + { |
| + HandleScope scope(CcTest::isolate()); |
| + LocalContext context2(CcTest::isolate()); |
| + context2->SetSecurityToken(foo); |
| + context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"), |
| + object); |
| + CompileRun("function observer() {};" |
|
Toon Verwaest
2014/05/02 14:17:34
I guess you don't need the observer here.
rafaelw
2014/05/02 16:18:12
Done.
|
| + "Object.getNotifier(obj);"); |
| + } |
| + |
| + v8::V8::ContextDisposedNotification(); |
| + CheckSurvivingGlobalObjectsCount(1); |
| +} |
| + |
| + |
| +TEST(DontLeakContextOnNotifierPerformChange) { |
| + HandleScope scope(CcTest::isolate()); |
| + Handle<Value> foo = String::NewFromUtf8(CcTest::isolate(), "foo"); |
| + LocalContext context(CcTest::isolate()); |
| + context->SetSecurityToken(foo); |
| + CompileRun("var obj = {};"); |
| + Handle<Value> object = CompileRun("obj"); |
| + { |
| + HandleScope scope(CcTest::isolate()); |
| + LocalContext context2(CcTest::isolate()); |
| + context2->SetSecurityToken(foo); |
| + context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"), |
| + object); |
| + CompileRun("function observer() {};" |
|
Toon Verwaest
2014/05/02 14:17:34
no observer needed here either
rafaelw
2014/05/02 16:18:12
Done.
|
| + "var n = Object.getNotifier(obj);" |
| + "n.performChange('foo', function() {});"); |
| + } |
| + |
| + v8::V8::ContextDisposedNotification(); |
| + CheckSurvivingGlobalObjectsCount(1); |
| +} |