1 //////////////////////////////////////////////////////////////////////////////
2 // Program to test garbage collection with pointer sharing.
3 //////////////////////////////////////////////////////////////////////////////
9 #include <AD/gc/gcheaps.h>
11 #define NODES (256 * 1024)
15 //////////////////////////////////////////////////////////////////////////////
16 // Datatype TREE is just a simple binary tree (actually a dag in our case).
17 //////////////////////////////////////////////////////////////////////////////
18 datatype TREE :: collectable = empty | node (TREE, int, TREE);
19 instantiate datatype TREE;
21 //////////////////////////////////////////////////////////////////////////////
22 // Compute the sum of all nodes of a tree
23 //////////////////////////////////////////////////////////////////////////////
27 case node(x,i,y): return sum(x) + i + sum(y);
31 //////////////////////////////////////////////////////////////////////////////
32 // Count the number of pointer sharings.
33 //////////////////////////////////////////////////////////////////////////////
37 case node(x,i,y): return sharing(x) + sharing(y)
38 + ((x != empty && x == y) ? 1 : 0);
42 //////////////////////////////////////////////////////////////////////////////
43 // Compute the size of a tree
44 //////////////////////////////////////////////////////////////////////////////
48 case node(x,i,y): return size(x) + 1 + size(y);
52 //////////////////////////////////////////////////////////////////////////////
53 // Check a tree for correctness.
54 //////////////////////////////////////////////////////////////////////////////
59 assert (HM::is_mapped(t) &&
60 HM::page_gc(t) == GC::get_default_gc().gc_id());
61 assert (HM::get_object_map().is_marked(t));
66 //////////////////////////////////////////////////////////////////////////////
67 // Routine to make a random tree of a certain size.
68 //////////////////////////////////////////////////////////////////////////////
70 { if (n == 0) return empty;
71 int split = rand() % n;
72 int data = rand() % n;
74 if ((n % 2 == 1) && (rand() % 2 == 1)) {
75 TREE t = make_tree(n/2);
76 return node(t, data, t);
79 return node(make_tree(split), data, make_tree(n - split - 1));
84 for (int trial = 1; trial <= TRIALS; trial++) {
85 cout << "Trial number " << trial << '\n' << flush;
86 TREE tree1 = make_tree(NODES);
87 int size1 = size(tree1);
88 int sum1 = sum(tree1);
89 int sharing1 = sharing (tree1);
92 cout << "Size = " << size1 << " check sum = " << sum1
93 << " pointer sharing = " << sharing1 << '\n' << flush;
95 make_tree(NODES); // this just generates a lot of garbage
97 // Now traverse the tree check things.
98 assert(size(tree1) == NODES);
99 assert(sum(tree1) == sum1);
100 assert(sharing(tree1) == sharing1);
102 cout << "Trial number " << trial << " has passed\n";
109 "This test generate random dags and try to see if garbage collection\n"
110 "works on preserving pointer sharing correctly. I'll do this "
111 << TRIALS << " times.\n";
114 // force an explicit garbage collection
115 cout << "Finished. Now I'm forcing another garbage collection to clean\n"
116 "things up. There should be very little garbage left at the end.\n";
117 GC::garbage_collect();