Skip to content

Commit

Permalink
Try to fix reliability issue with gc reachability testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre Delaunay committed Aug 2, 2024
1 parent 6b93bdc commit fcc572c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 19 deletions.
9 changes: 9 additions & 0 deletions src/stdlib/garbage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void BoehmGarbageCollector::free(void* ptr) {
if (ptr == nullptr) {
return;
}
// TODO: remove the ptr from the allocation
GCObjectHeader* hdr = header(ptr);
if (hdr->finalizer) {
hdr->finalizer(ptr);
Expand Down Expand Up @@ -84,14 +85,22 @@ void BoehmGarbageCollector::mark_obj(void* obj, GCGen gen) {
void BoehmGarbageCollector::sweep(GCGen gen) {
Array<GCObjectHeader*> allocs;
for (GCObjectHeader* obj: allocations(gen)) {
if (obj == nullptr) {
continue;
}
if (!obj->marked) {
kwdebug(outlog(), "free {}", (void*)(obj));
if (obj->finalizer) {
obj->finalizer(obj->data());
}
std::free(obj);
} else {
obj->marked = 0;
allocs.push_back(obj);
}
}

// TODO: promotion logic here
allocations(gen) = allocs;
}

Expand Down
3 changes: 3 additions & 0 deletions src/stdlib/garbage.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ enum class GCGen
*
* The header could also be dynamically allocated separately for common
* type/size
*
* Currently the GC never runs, some heuristic needs to be put in place
* to make it run periodically
*/
struct BoehmGarbageCollector {

Expand Down
65 changes: 46 additions & 19 deletions tests/garbage_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include "stdlib/garbage.h"
#include <algorithm>


#define KIWI_NOINLINE __attribute__ ((noinline))


namespace lython {

class GargabeCollector;
Expand Down Expand Up @@ -485,6 +489,16 @@ ListBool* make_list(BoehmGarbageCollector& gc, bool val, ListBool* prev) {
return lst;
}

void KIWI_NOINLINE print(ListBool* list) {
int i = 0;
while(list != nullptr) {
std::cout << i << " ";
list = list->next;
i += 1;
}
}


TEST_CASE("BoehmGarbageCollector_Marks recursively find pointers") {
BoehmGarbageCollector gc;

Expand Down Expand Up @@ -515,7 +529,7 @@ TEST_CASE("BoehmGarbageCollector_Globals") {
}


void* test_all_there() {
ListBool* KIWI_NOINLINE test_all_there() {
BoehmGarbageCollector gc;

ListBool* n1 = make_list(gc, true, nullptr);
Expand All @@ -532,10 +546,10 @@ void* test_all_there() {
REQUIRE(gc.allocations(GCGen::Temporary).size() == 5);

// need to return it else it might not be in the stack anymore
return (void*)n5;
return n5;
}

void* test_only_two() {
ListBool* KIWI_NOINLINE test_only_two() {
BoehmGarbageCollector gc;

ListBool* n1 = make_list(gc, true, nullptr);
Expand All @@ -549,19 +563,23 @@ void* test_only_two() {
gc.collect();
gc.dump(std::cout);

printf("%lu \n", gc.allocations(GCGen::Temporary).size());
printf("%lu \n", gc.allocations(GCGen::Medium).size());
printf("%lu \n", gc.allocations(GCGen::Long).size());

REQUIRE(gc.allocations(GCGen::Temporary).size() == 2);

// need to return it else it might not be in the stack anymore
return (void*)n2;
return n2;
}


TEST_CASE("BoehmGarbageCollector_AllReachable") {
test_all_there();
print(test_all_there());
}


void* test_nested() {
ListBool* KIWI_NOINLINE test_nested() {
BoehmGarbageCollector gc;

ListBool* n5 = make_list(
Expand All @@ -582,24 +600,16 @@ void* test_nested() {
}

TEST_CASE("BoehmGarbageCollector_AllReachable_Nested") {
test_nested();
print(test_nested());
}


TEST_CASE("BoehmGarbageCollector_Collect_Garbage") {
test_only_two();
print(test_only_two());
}

void print(ListBool* list) {
int i = 0;
while(list != nullptr) {
std::cout << i << " ";
list = list->next;
i += 1;
}
}

ListBool* test_relocated(BoehmGarbageCollector& gc) {
ListBool* KIWI_NOINLINE test_relocated(BoehmGarbageCollector& gc) {

ListBool* n5 =
make_list(gc, true,
Expand Down Expand Up @@ -638,14 +648,31 @@ ListBool* test_relocated(BoehmGarbageCollector& gc) {
return n5;
}


char KIWI_NOINLINE reset_frame() {
volatile char data[1024 * 1024 * 1024];
char c = 0;
for(int i; i < sizeof(data); i++) {
c += data[i];
}
return c;
}


TEST_CASE("BoehmGarbageCollector_Relocate") {
BoehmGarbageCollector gc;

ListBool* l = test_relocated(gc);
reset_frame();

gc.dump(std::cout);
//gc.dump(std::cout);
gc.collect();
gc.dump(std::cout);
//gc.dump(std::cout);

print(l);

gc.collect();


// 6 allocations
// only 2 should remain reachable
Expand Down

0 comments on commit fcc572c

Please sign in to comment.