use typename
[prop.git] / tests / test_gc23.cc
blob2f720792ce4145122f78c6f45886f53c65a6ed64
1 //////////////////////////////////////////////////////////////////////////////
2 // This program tests the garbage collector classes.
3 // We'll allocate a long linked list in the collectable heap, then invoke
4 // garbage collection a few times.
5 //
6 // Note: In your application you'll only have to include <AD/gc/gcobject.h>.
7 // In this case we'll have to import some other implementation dependent
8 // information since we'll have do some poking around with the heap.
9 //////////////////////////////////////////////////////////////////////////////
11 #include <assert.h>
12 #include <iostream.h>
13 #include <AD/gc/bgc.h>
14 #include <AD/gc/gcobject.h>
15 #include <AD/gc/gcheaps.h>
17 #define LENGTH (256)
18 #define UNIT (16 * 64)
19 #define HEAP_POINTERS 100
20 #define TRIALS 100
22 //////////////////////////////////////////////////////////////////////////////
23 // The list class defined below is made a garbage collectable class by
24 // deriving from GCObject and adding a tracing method ``trace.''
25 //////////////////////////////////////////////////////////////////////////////
26 class LIST : public GCObject {
27 public:
28 char c; // some position dependent storage
29 int x[20]; // some other position independent junk
30 LIST * next; // the link
32 // The constructor
33 LIST(LIST * n, char c1) : next(n), c(c1)
34 { for (int i = 0; i < 20; i++) x[i] = i; }
36 private:
37 // The tracing method.
38 void trace(GC * gc) { next = (LIST *)gc->trace(next); }
41 //////////////////////////////////////////////////////////////////////////////
42 // Method to print a list, currently unused.
43 //////////////////////////////////////////////////////////////////////////////
44 void print(LIST * x)
45 { if (x) { cout << x->c; print(x->next); }
48 //////////////////////////////////////////////////////////////////////////////
49 // This method checks that a list is well and okay.
50 //////////////////////////////////////////////////////////////////////////////
51 void verify (LIST * x)
52 { int count = 0;
53 // cout << "Verifying list\n" << flush;
54 for ( ; x; x = x->next, count++) {
56 // Make sure that it lies within the collectable heap.
58 assert (HM::is_mapped(x) && HM::page_gc(x) == bgc.gc_id());
59 assert (HM::get_object_map().is_marked(x));
61 // Check its contents
62 for (int i = 0; i < 20; i++)
63 assert (x->x[i] == i);
64 assert (x->c == (LENGTH - count - 1) / UNIT + 'a');
67 // Make sure that it has the right length.
68 assert (count == LENGTH);
72 void do_some_stuff(int trial)
74 LIST ** heap = new LIST * [HEAP_POINTERS];
76 // Allocate a list
77 int j;
78 for (j = 0; j < HEAP_POINTERS; j++) {
79 LIST * x = 0;
80 for (int i = 0; i < LENGTH; i++) {
81 x = new LIST (x,i / UNIT + 'a');
82 // The following line generates some garbage.
83 new LIST (x, i / UNIT + 'a');
85 heap[j] = x;
88 cout << "List allocated\n";
89 // cout << "Address of heap[] = " << (void*)heap << '\n';
90 // GCHeapManager::print_report(cout);
91 for (j = 0; j < HEAP_POINTERS; j++) {
92 // cout << "[" << j << "]" << flush;
93 verify(heap[j]);
96 GC::get_default_gc().collect();
97 for (j = 0; j < HEAP_POINTERS; j++) {
98 // cout << "[" << j << "]" << flush;
99 verify(heap[j]);
101 GC::get_default_gc().collect();
103 for (j = 0; j < HEAP_POINTERS; j++) {
104 // cout << "[" << j << "]" << flush;
105 verify(heap[j]);
107 for (j = 0; j < HEAP_POINTERS; j++) {
108 heap[j] = 0;
110 cout << "Trial = " << trial << " List is okay\n" << flush;
111 GC::get_default_gc().collect();
112 delete [] heap;
115 int main()
117 GC::get_default_gc().set_verbosity(
118 GC::gc_print_debugging_info | GC::get_default_gc().verbosity());
119 GC::get_default_gc().set_initial_heap_size(1024*1024);
120 GC::Statistics stats = GC::get_default_gc().statistics();
121 cout << "Algorithm: " << stats.algorithm << '\n'
122 << "Version: " << stats.version << '\n';
124 for (int i = 0; i < TRIALS; i++)
125 do_some_stuff(i);
127 GC::get_default_gc().collect();
129 stats = GC::get_default_gc().statistics();
130 size_t memory_allocated = sizeof(LIST) * LENGTH * 2 * HEAP_POINTERS;
132 cout << "\n"
133 "Memory allocated: " << memory_allocated << '\n'
134 << "Final heap size: "
135 << stats.bytes_managed + GCHeapManager::bytes_free() << '\n'
136 << "Bytes retained: " << stats.bytes_used << '\n'
137 << "Retention rate: "
138 << (stats.bytes_used * 100 / memory_allocated) << "%\n"
139 << "\n"
140 "If you don't see a crash by now then it's probably ok :-)\n"
141 "Ideally, the heap should be completely reclaimed at this\n"
142 "point, but since the collector is conservative, retention\n"
143 "may occur.\n"
144 "\n"
145 "Actually this test is bit unfair, since we are allocating\n"
146 "a long linked list, a strongly connected data structure, and if\n"
147 "any one part of the list is incorrectly promoted then a large\n"
148 "portion of the storage will be retained.\n"
149 "\n"
150 "Happy GC!\n";
151 return 0;