Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Unified Diff: runtime/vm/dart_api_impl_test.cc

Issue 9605033: Implement a garbage collection prologue and epilogue callback mechanism. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix a comment Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/dart_api_impl_test.cc
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index f6380aa8119c1b7115945363c739bf5edab5c1de..b19b4fcf2c4a76ee50da47c6e3cc930722c5e9d1 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1646,6 +1646,171 @@ TEST_CASE(ImplicitReferences) {
EXPECT(Dart_IsNull(weak3));
}
+
+static int global_prologue_callback_status = 0;
+
+
+static void PrologueCallbackTimes2() {
+ global_prologue_callback_status *= 2;
+}
+
+
+static void PrologueCallbackTimes3() {
+ global_prologue_callback_status *= 3;
+}
+
+
+static int global_epilogue_callback_status = 0;
+
+
+static void EpilogueCallbackTimes4() {
+ global_epilogue_callback_status *= 4;
turnidge 2012/03/07 00:25:16 How about relatively prime numbers? 4 -> 5, 5 ->
cshapiro 2012/03/07 03:06:10 I think I avoid this case by separating the value
+}
+
+
+static void EpilogueCallbackTimes5() {
+ global_epilogue_callback_status *= 5;
+}
+
+
+TEST_CASE(GarbageCollectionCallbacks) {
turnidge 2012/03/07 00:25:16 Consider splitting into a few smaller tests. I li
cshapiro 2012/03/07 03:06:10 Done.
+ // Add a prologue callback.
+ EXPECT_VALID(Dart_NewGcPrologueCallback(&PrologueCallbackTimes2));
+
+ // Add the same prologue callback again. This is an error.
+ EXPECT(Dart_IsError(Dart_NewGcPrologueCallback(&PrologueCallbackTimes2)));
+
+ // Garbage collect new space. This should not invoke the prologue
+ // callback. No status values should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+ EXPECT_EQ(3, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+
+ // Garbage collect old space. This should invoke the prologue
+ // callback. The prologue status value should change.
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(6, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+
+ // Garbage collect old space again. Callbacks are persistent so the
+ // prolog status value should change again.
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(12, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+
+ // Add an GC epilogue callback.
+ EXPECT_VALID(Dart_NewGcEpilogueCallback(&EpilogueCallbackTimes4));
+
+ // Add the same epilogue callback again. This is an error.
+ EXPECT(Dart_IsError(Dart_NewGcEpilogueCallback(&EpilogueCallbackTimes4)));
+
+ // Garbage collect new space. This should not invoke the prologue
+ // or the epilogue callback. No status values should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+ EXPECT_EQ(3, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+
+ // Garbage collect old space. This should invoke the prologue and
+ // the epilogue callbacks. The prologue and epilogue status values
+ // should change.
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(6, global_prologue_callback_status);
+ EXPECT_EQ(28, global_epilogue_callback_status);
+
+ // Garbage collect old space again. Callbacks are persistent so the
+ // prologue and epilogue status values should change again.
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(12, global_prologue_callback_status);
+ EXPECT_EQ(112, global_epilogue_callback_status);
+
+ // Add another GC prologue callback.
+ EXPECT_VALID(Dart_NewGcPrologueCallback(&PrologueCallbackTimes3));
+
+ // Garbage collect old space. This should invoke both prologue
+ // callbacks and the epilogue callback. The prologue and epilogue
+ // status values should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(18, global_prologue_callback_status);
+ EXPECT_EQ(28, global_epilogue_callback_status);
+
+ // Add another GC epilogue callback.
+ EXPECT_VALID(Dart_NewGcEpilogueCallback(&EpilogueCallbackTimes5));
+
+ // Garbage collect old space. This should invoke both prologue
+ // callbacks and both epilogue callbacks. The prologue and epilogue
+ // status values should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(18, global_prologue_callback_status);
+ EXPECT_EQ(140, global_epilogue_callback_status);
+
+ // Remove an epilogue callback.
+ EXPECT_VALID(Dart_DeleteGcEpilogueCallback(&EpilogueCallbackTimes4));
+
+ // Garbage collect old space. This should invoke both prologue
+ // callbacks and the remaining epilogue callback. The prologue and
+ // epilogue status values should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(18, global_prologue_callback_status);
+ EXPECT_EQ(35, global_epilogue_callback_status);
+
+ // Try removing the epilogue callback again. This is an error.
+ EXPECT(Dart_IsError(Dart_DeleteGcEpilogueCallback(&EpilogueCallbackTimes4)));
+
+ // Remove the remaining epilogue callback.
+ EXPECT_VALID(Dart_DeleteGcEpilogueCallback(&EpilogueCallbackTimes5));
+
+ // Try removing the remaining epilogue callback again. This is an
+ // error.
+ EXPECT(Dart_IsError(Dart_DeleteGcEpilogueCallback(&EpilogueCallbackTimes5)));
+
+ // Garbage collect old space. This should invoke both prologue
+ // callbacks. The prologue status value should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(18, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+
+ // Remove a prologue callback.
+ EXPECT_VALID(Dart_DeleteGcPrologueCallback(&PrologueCallbackTimes3));
+
+ // Try removing the prologue callback again. This is an error.
+ EXPECT(Dart_IsError(Dart_DeleteGcPrologueCallback(&PrologueCallbackTimes3)));
+
+ // Garbage collect old space. This should invoke the remaining
+ // prologue callback. The prologue status value should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(6, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+
+ // Remove the remaining prologue callback.
+ EXPECT_VALID(Dart_DeleteGcPrologueCallback(&PrologueCallbackTimes2));
+
+ // Try removing the remaining prologue callback again. This is an
+ // error.
+ EXPECT(Dart_IsError(Dart_DeleteGcPrologueCallback(&PrologueCallbackTimes2)));
+
+ // Garbage collect old space. No callbacks should be invoked. No
+ // status values should change.
+ global_prologue_callback_status = 3;
+ global_epilogue_callback_status = 7;
+ Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ EXPECT_EQ(3, global_prologue_callback_status);
+ EXPECT_EQ(7, global_epilogue_callback_status);
+}
+
#endif

Powered by Google App Engine
This is Rietveld 408576698