2 // Testing garbage collection with polymorphic datatypes
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<T> :: collectable
21 | node (TREE<T>, class T, TREE<T>)
24 instantiate datatype TREE<int>, TREE<const char *>;
26 //////////////////////////////////////////////////////////////////////////////
27 // Compute the sum of all nodes of a tree
28 //////////////////////////////////////////////////////////////////////////////
32 case leaf i: return i;
33 case node(x,i,y): return sum(x) + i + sum(y);
37 //////////////////////////////////////////////////////////////////////////////
38 // Count the number of pointer sharings.
39 //////////////////////////////////////////////////////////////////////////////
40 int sharing (TREE<int> t)
43 case leaf _: return 0;
44 case node(x,i,y): return sharing(x) + sharing(y)
45 + ((x != empty && x == y) ? 1 : 0);
49 //////////////////////////////////////////////////////////////////////////////
50 // Compute the size of a tree
51 //////////////////////////////////////////////////////////////////////////////
56 case leaf _: return 1;
57 case node(x,i,y): return size(x) + 1 + size(y);
61 //////////////////////////////////////////////////////////////////////////////
62 // Check a tree for correctness.
63 //////////////////////////////////////////////////////////////////////////////
65 void check (TREE<T> t)
70 assert (HM::is_mapped(t) &&
71 HM::page_gc(t) == GC::get_default_gc().gc_id());
72 assert (HM::get_object_map().is_marked(t));
77 //////////////////////////////////////////////////////////////////////////////
78 // Routine to make a random tree of a certain size.
79 //////////////////////////////////////////////////////////////////////////////
80 TREE<int> make_tree(int n)
81 { if (n == 0) return empty;
82 int split = rand() % n;
83 int data = rand() % n;
85 if ((n % 2 == 1) && (rand() % 2 == 1)) {
86 TREE<int> t = make_tree(n/2);
87 return node(t, data, t);
90 return node(make_tree(split), data, make_tree(n - split - 1));
95 for (int trial = 1; trial <= TRIALS; trial++) {
96 cout << "Trial number " << trial << '\n' << flush;
97 TREE<int> tree1 = make_tree(NODES);
98 int size1 = size(tree1);
99 int sum1 = sum(tree1);
100 int sharing1 = sharing (tree1);
103 cout << "Size = " << size1 << " check sum = " << sum1
104 << " pointer sharing = " << sharing1 << '\n' << flush;
106 make_tree(NODES); // this just generates a lot of garbage
108 // Now traverse the tree check things.
109 assert(size(tree1) == NODES);
110 assert(sum(tree1) == sum1);
111 assert(sharing(tree1) == sharing1);
113 cout << "Trial number " << trial << " has passed\n";
120 "This test generate random dags and try to see if garbage collection\n"
121 "works on preserving pointer sharing correctly. I'll do this "
122 << TRIALS << " times.\n";
125 // force an explicit garbage collection
126 cout << "Finished. Now I'm forcing another garbage collection to clean\n"
127 "things up. There should be very little garbage left at the end.\n";
128 GC::garbage_collect();