Skip to content

Commit c160dbb

Browse files
committed
Add unit test for GC static memory, fix GC static memory
1 parent 447f5ea commit c160dbb

File tree

4 files changed

+102
-13
lines changed

4 files changed

+102
-13
lines changed

main.c

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ int main() {
1919

2020
x = pog_malloc(1);
2121

22+
DEBUG("%p\n", x);
23+
2224
pog_malloc(80);
2325
pog_malloc(80);
2426
pog_malloc(80);

pog_real_heap.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#define HEAP_CAP_REAL_CHUNKS 8192
1010
static pog_chunk real_alloced[HEAP_CAP_REAL_CHUNKS] = {0};
1111
static pog_chunk real_freed[HEAP_CAP_REAL_CHUNKS] = {0};
12-
static pog_chunk real_freed_tmp[HEAP_CAP_REAL_CHUNKS] = {0};
12+
static pog_chunk real_tmp[HEAP_CAP_REAL_CHUNKS] = {0};
1313
static size_t real_heap_size_words = 64;
1414

1515
int real_heap_expand(size_t words, size_t* alloced_chunks_size, size_t* freed_chunks_size) {
@@ -40,7 +40,7 @@ void pog_real_heap_init() {
4040
pog_init(heap_start, real_heap_size_words,
4141
&real_alloced[0], real_heap_size_words * 8,
4242
&real_freed[0], real_heap_size_words * 8,
43-
&real_freed_tmp[0], real_heap_size_words * 8,
43+
&real_tmp[0], real_heap_size_words * 8,
4444
&real_heap_expand);
4545

4646
//HACK: sometimes, sbrk(0) gives back a weird address space; leak two words to properly align brk

pogmalloc.c

+34-9
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,36 @@ void pog_debug() {
189189
#endif
190190

191191
#if FEATURE_GC
192+
void pog_gc_mark_region(const uintptr_t* start, const uintptr_t* end);
193+
194+
int pog_gc_region_find(pog_chunk chunk, const uintptr_t* p) {
195+
if (chunk.start <= p && p < chunk.start + chunk.size) {
196+
size_t idx = pog_chunk_by_ptr(&tmp_chunks_list, chunk.start);
197+
if (idx != (size_t) -1) {
198+
pog_chunk_remove(&tmp_chunks_list, idx);
199+
pog_gc_mark_region(chunk.start, chunk.start + chunk.size);
200+
}
201+
}
202+
}
203+
192204
void pog_gc_mark_region(const uintptr_t* start, const uintptr_t* end) {
193205
for (;start < end; start += 1) {
194206
const uintptr_t *p = (const uintptr_t *) *start;
195207
for (size_t i = 0; i < alloced_chunks_list.curr_size; ++i) {
196208
pog_chunk chunk = alloced_chunks_list.chunks[i];
197-
if (chunk.start <= p && p < chunk.start + chunk.size) {
198-
size_t idx = pog_chunk_by_ptr(&tmp_chunks_list, chunk.start);
199-
if (idx != (size_t) -1) {
200-
pog_chunk_remove(&tmp_chunks_list, idx);
201-
pog_gc_mark_region(chunk.start, chunk.start + chunk.size);
202-
}
203-
}
209+
pog_gc_region_find(chunk, p);
210+
}
211+
}
212+
}
213+
214+
void pog_gc_mark_static_region(const uintptr_t* start, const uintptr_t* end) {
215+
for (;start < end; start += 1) {
216+
const uintptr_t *p = (const uintptr_t *) *start;
217+
if (p == NULL)
218+
continue;
219+
for (size_t i = 0; i < alloced_chunks_list.curr_size; ++i) {
220+
pog_chunk chunk = alloced_chunks_list.chunks[i];
221+
pog_gc_region_find(chunk, (const uintptr_t *) *p);
204222
}
205223
}
206224
}
@@ -216,8 +234,15 @@ void pog_gc_collect() {
216234
//mark unused pointers on the heap and stack
217235
pog_gc_mark_region(stack_start, stack_base + 1);
218236

219-
//mark unused pointers in static memory
220-
pog_gc_mark_region((const uintptr_t *) static_mem_ptrs, (const uintptr_t *) (static_mem_ptrs + static_mem_curr_size));
237+
//you don't need to have static pointers marked
238+
if (static_mem_ptrs != NULL) {
239+
//mark unused pointers in static memory
240+
pog_gc_mark_region((const uintptr_t *) static_mem_ptrs, (const uintptr_t *) (static_mem_ptrs + static_mem_curr_size));
241+
242+
//in C, the line above works for static pointers, but in C++ it doesn't for some reason,
243+
//and we have to deref the ptr again 🤷‍
244+
pog_gc_mark_static_region((const uintptr_t *) static_mem_ptrs, (const uintptr_t *) (static_mem_ptrs + static_mem_curr_size));
245+
}
221246

222247
for (size_t i = 0; i < tmp_chunks_list.curr_size; i++) {
223248
DEBUG("%p marked unused\n", tmp_chunks_list.chunks[i].start);

test.cpp

+64-2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ TEST_CASE("GC unused stack pointer") {
103103
REQUIRE(alloced[0].size == (size_t) 1);
104104
REQUIRE(freed[0].size == (size_t) 7999);
105105

106+
pog_gc_collect();
107+
REQUIRE(alloced[0].size == (size_t) 1);
108+
REQUIRE(freed[0].size == (size_t) 7999);
109+
106110
a = nullptr;
107111
REQUIRE(alloced[0].size == (size_t) 1);
108112
REQUIRE(freed[0].size == (size_t) 7999);
@@ -127,6 +131,12 @@ TEST_CASE("GC multiple unused stack pointers") {
127131
REQUIRE(alloced[2].size == (size_t) 1);
128132
REQUIRE(freed[0].size == (size_t) 7997);
129133

134+
pog_gc_collect();
135+
REQUIRE(alloced[0].size == (size_t) 1);
136+
REQUIRE(alloced[1].size == (size_t) 1);
137+
REQUIRE(alloced[2].size == (size_t) 1);
138+
REQUIRE(freed[0].size == (size_t) 7997);
139+
130140
a = nullptr;
131141
REQUIRE(alloced[0].size == (size_t) 1);
132142
REQUIRE(freed[0].size == (size_t) 7997);
@@ -182,6 +192,13 @@ TEST_CASE("GC pointers in heap without GC root") {
182192
REQUIRE(alloced[3].size == (size_t) 2);
183193
REQUIRE(freed[0].size == (size_t) 7992);
184194

195+
pog_gc_collect();
196+
REQUIRE(alloced[0].size == (size_t) 2);
197+
REQUIRE(alloced[1].size == (size_t) 2);
198+
REQUIRE(alloced[2].size == (size_t) 2);
199+
REQUIRE(alloced[3].size == (size_t) 2);
200+
REQUIRE(freed[0].size == (size_t) 7992);
201+
185202
b->next = nullptr;
186203
c = nullptr;
187204
d = nullptr;
@@ -209,6 +226,51 @@ TEST_CASE("GC pointers in heap without GC root") {
209226
REQUIRE(freed[0].size == (size_t) 8000);
210227
}
211228

229+
static char* x;
230+
static char* y;
231+
static char* z;
232+
233+
#define STATIC_MEM_CAP 2048
234+
uintptr_t test_static_mem[STATIC_MEM_CAP];
235+
212236
TEST_CASE("GC static pointers that have been set to null") {
213-
//TODO
214-
}
237+
pog_gc_init(&test_static_mem, STATIC_MEM_CAP);
238+
pog_gc_mark_static(&x);
239+
pog_gc_mark_static(&y);
240+
pog_gc_mark_static(&z);
241+
242+
pog_static_heap_init();
243+
244+
x = (char*) pog_malloc(1);
245+
y = (char*) pog_malloc(1);
246+
z = (char*) pog_malloc(1);
247+
248+
REQUIRE(alloced[0].size == (size_t) 1);
249+
REQUIRE(alloced[1].size == (size_t) 1);
250+
REQUIRE(alloced[2].size == (size_t) 1);
251+
REQUIRE(freed[0].size == (size_t) 7997);
252+
253+
pog_gc_collect();
254+
REQUIRE(alloced[0].size == (size_t) 1);
255+
REQUIRE(alloced[1].size == (size_t) 1);
256+
REQUIRE(alloced[2].size == (size_t) 1);
257+
REQUIRE(freed[0].size == (size_t) 7997);
258+
259+
x = nullptr;
260+
pog_gc_collect();
261+
REQUIRE(alloced[0].size == (size_t) 1);
262+
REQUIRE(alloced[1].size == (size_t) 1);
263+
REQUIRE(freed[0].size == (size_t) 1);
264+
REQUIRE(freed[1].size == (size_t) 7997);
265+
266+
y = nullptr;
267+
z = nullptr;
268+
pog_gc_collect();
269+
REQUIRE(freed[0].size == (size_t) 1);
270+
REQUIRE(freed[1].size == (size_t) 1);
271+
REQUIRE(freed[2].size == (size_t) 1);
272+
REQUIRE(freed[3].size == (size_t) 7997);
273+
274+
pog_squash();
275+
REQUIRE(freed[0].size == (size_t) 8000);
276+
}

0 commit comments

Comments
 (0)