OILS / mycpp / gc_stress_test.cc View on Github | oilshell.org

222 lines, 126 significant
1// gc_stress_test.cc: Do many allocations and collections under ASAN
2
3#include <unistd.h> // STDERR_FILENO
4
5#include "mycpp/runtime.h"
6#include "vendor/greatest.h"
7
8// TODO:
9// - Assert the number of collections
10// - Assert the number of heap growths
11// - maybe number of allocations?
12
13int count(int n) {
14 int dummy = 42;
15 StackRoots _roots({&dummy});
16 // log("d %p", &dummy);
17
18 if (n == 0) {
19 return 0;
20 } else {
21 return 1 + count(n - 1);
22 }
23}
24
25TEST overflowing_roots_test() {
26 gHeap.Init();
27
28 log("count 4000 = %d", count(4000));
29
30 // When our stack roots were limited, this would crash
31 log("count 5000 = %d", count(5000));
32 log("count 20000 = %d", count(20000));
33 log("count 25000 = %d", count(25000));
34 // Stack overflow in ASAN
35 // log("count 29000 = %d", count(29000));
36 // Stack overflow in dbg
37 // log("count 200000 = %d", count(200000));
38
39 PASS();
40}
41
42TEST str_simple_test() {
43 gHeap.Init();
44
45 BigStr* s = nullptr;
46 StackRoots _roots({&s});
47
48 int total = 0;
49 for (int i = 0; i < 400; ++i) {
50 unsigned char c = i % 256;
51 s = chr(c);
52 /* log("i = %d", i); */
53 ASSERT_EQ_FMT(c, ord(s), "%d"); // Check for memory corruption
54 total += len(s);
55 }
56
57 log("total = %d", total);
58 gHeap.PrintStats(STDERR_FILENO);
59
60 PASS();
61}
62
63GLOBAL_STR(b, "b");
64GLOBAL_STR(bx, "bx");
65
66TEST str_growth_test() {
67 gHeap.Init();
68
69 BigStr* s = nullptr;
70 StackRoots _roots({&s});
71
72 gHeap.PrintStats(STDERR_FILENO);
73
74 s = StrFromC("b");
75 int n = 300;
76 int total = 0;
77 for (int i = 0; i < n; ++i) {
78 total += len(s); // count it first
79
80 // log("--- %p %d", s, len(s));
81 // print(s);
82 s = s->replace(b, bx);
83 // print(s);
84 }
85 log("total = %d", total);
86
87 int expected = (n * (n + 1)) / 2;
88 ASSERT_EQ_FMT(expected, total, "%d");
89
90 gHeap.PrintStats(STDERR_FILENO);
91
92 PASS();
93}
94
95// Simple test with just List on the heap.
96TEST list_append_test() {
97 gHeap.Init();
98
99 List<int>* L = nullptr;
100 StackRoots _roots({&L});
101
102 int length = 1;
103 L = NewList<int>(42, length);
104
105 int n = 1000;
106 int total = 0;
107 for (int i = 0; i < n; ++i) {
108 total += len(L); // count it first
109
110 // log("sliced L = %p", L);
111 L->append(43); // append to end
112 }
113 log("total = %d", total);
114 ASSERT_EQ_FMT(500500, total, "%d");
115
116 PASS();
117}
118
119TEST list_slice_append_test() {
120 gHeap.Init();
121
122 List<int>* L = nullptr;
123 StackRoots _roots({&L});
124
125 int length = 5;
126 L = NewList<int>(42, length);
127
128 int n = 300;
129 int total = 0;
130 for (int i = 0; i < n; ++i) {
131 /* log("i = %d", i); */
132 total += len(L); // count it first
133
134 L = L->slice(1);
135 assert(len(L) == 4);
136
137 L->append(43); // append to end
138 assert(len(L) == 5);
139 }
140 log("total = %d", total);
141
142 int expected = n * length;
143 ASSERT_EQ_FMT(expected, total, "%d");
144
145 PASS();
146}
147
148TEST list_str_growth_test() {
149 gHeap.Init();
150
151 BigStr* s = nullptr;
152 List<BigStr*>* L = nullptr;
153 StackRoots _roots({&s, &L});
154 // StackRoots _roots({&L});
155
156 s = StrFromC("b");
157 L = Alloc<List<BigStr*>>();
158
159#if 0
160 int total = 0;
161 int n = 40;
162 for (int i = 0; i < n; ++i) {
163 log("i = %d", i);
164 //total += len(s);
165
166 L->append(s);
167
168 // This works if we don't have 's'. Because it's global?
169 //L->append(bx);
170 }
171 log("total = %d", total);
172
173 int expected = (n * (n + 1)) / 2;
174 ASSERT_EQ_FMT(expected, total, "%d");
175#endif
176
177 PASS();
178}
179
180TEST dict_growth_test() {
181 gHeap.Init();
182
183 BigStr* s = nullptr;
184 Dict<BigStr*, int>* D = nullptr;
185 StackRoots _roots({&s, &D});
186
187 s = StrFromC("abcdefg");
188 D = Alloc<Dict<BigStr*, int>>();
189
190 int total = 0;
191 for (int i = 0; i < 40; ++i) {
192 total += len(s);
193 s = s->replace(b, bx);
194 D->set(s, 42);
195 }
196 log("total = %d", total);
197
198 // TODO: Test NewDict(), etc.
199
200 PASS();
201}
202
203GREATEST_MAIN_DEFS();
204
205int main(int argc, char** argv) {
206 gHeap.Init();
207
208 GREATEST_MAIN_BEGIN();
209
210 RUN_TEST(overflowing_roots_test);
211 RUN_TEST(str_simple_test);
212 RUN_TEST(str_growth_test);
213 RUN_TEST(list_append_test);
214 RUN_TEST(list_slice_append_test);
215 RUN_TEST(list_str_growth_test);
216 RUN_TEST(dict_growth_test);
217
218 gHeap.CleanProcessExit();
219
220 GREATEST_MAIN_END();
221 return 0;
222}