From 3860d0ec4f04ed1307631574d96cf2634bdacb2f Mon Sep 17 00:00:00 2001 From: valtermiari Date: Mon, 20 Feb 2023 14:34:57 +0100 Subject: [PATCH] Tweaked sweeping, test with detached pointers --- src/GC/lib/heap.cpp | 42 +++++++++++++++++++++-------------------- src/GC/tests/h_test.cpp | 32 ++++++++++++++++++------------- src/GC/todo.md | 1 + 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/GC/lib/heap.cpp b/src/GC/lib/heap.cpp index d13cec6..f2d04ee 100644 --- a/src/GC/lib/heap.cpp +++ b/src/GC/lib/heap.cpp @@ -192,49 +192,51 @@ namespace GC { } } - // Not optimal for now, it doesn't have to loop over all objects - // but mark needs some refinements before this can be optimised + /** + * Sweeps the heap, unmarks the marked chunks for the next cycle, + * adds the unmarked nodes to the vector of freed chunks; to be freed. + * + * @param *heap The heap to oporate on. + */ void Heap::sweep(Heap *heap) { for (auto it = heap->m_allocated_chunks.begin(); it != heap->m_allocated_chunks.end();) { auto chunk = *it; - if (!chunk->marked) { + + // Unmark the marked chunks for the next iteration. + if (chunk->marked) { + chunk->marked = false; + ++it; + } + else { + // Add the unmarked chunks to freed chunks and remove from + // the list of allocated chunks heap->m_freed_chunks.push_back(chunk); it = heap->m_allocated_chunks.erase(it); } - else { - ++it; - } } } - // TODO: return the worklist filtered on mark = true // This assumes that there are no chains of pointers, will be fixed later on void Heap::mark(uintptr_t *start, const uintptr_t *end, vector worklist) { for (; start > end; start--) { // to find adresses thats in the worklist if (*start % 8 == 0) { // all pointers must be aligned as double words for (auto it = worklist.begin(); it != worklist.end();) { - //for (size_t i = 0; i < worklist.size(); i++) { // fix this - //auto chunk = worklist.at(i); auto chunk = *it; uintptr_t c_start = reinterpret_cast(chunk->start); uintptr_t c_end = reinterpret_cast(chunk->start + chunk->size); - if (c_start <= *start && *start < c_end) { - uintptr_t c_start = reinterpret_cast(chunk->start); - if (!chunk->marked) { + // Check if the stack pointer aligns with the chunk + if ((c_start <= *start && *start < c_end) && chunk != nullptr) { + cout << "Chunk start:\t" << c_start << endl; + cout << "Chunk end:\t" << c_end << endl; + if (!chunk->marked) { chunk->marked = true; - //worklist.erase(worklist.begin() + i); it = worklist.erase(it); - //auto new_stack_start = reinterpret_cast(start); - //mark(new_stack_start, end, worklist); // - //return; } - else { + else ++it; - } } - else { + else ++it; - } } } } diff --git a/src/GC/tests/h_test.cpp b/src/GC/tests/h_test.cpp index 65f51d6..cd93f7e 100644 --- a/src/GC/tests/h_test.cpp +++ b/src/GC/tests/h_test.cpp @@ -9,36 +9,42 @@ GC::Heap *gc = GC::Heap::the(); *dst = local; } */ +void create_array(size_t size) { + int *arr = static_cast(gc->alloc(sizeof(int) * size)); +} + +void detach_pointer(long **ptr) { + long dummy = 10; // dummy value + long *dummy_ptr = &dummy; + *ptr = dummy_ptr; + std::cout << "Dummy pointer: \t" << dummy_ptr << std::endl; + std::cout << "Detach pointer result:\t" << ptr << std::endl; +} + void init() { auto stack_start = reinterpret_cast(__builtin_frame_address(0)); - //auto stack_end = stack_start - 40; std::cout << "Stack start from init:\t" << stack_start << std::endl; - //std::cout << "Imaginary stack end:\t" << stack_end << std::endl; int *arr = static_cast(gc->alloc(sizeof(int) * 100)); + create_array(100); + //arr = create_array(100); //std::cout << "Arr_ptr" << std::hex << arr << "\n\n\n" << std::endl; for (int i = 0; i < (sizeof(int) * 100); i++) { arr[i] = i; } - for (int i = 0; i < (sizeof(int) * 20); i++) { - gc->alloc(sizeof(int)); - } std::cout << "Pointer for arr:\t" << &arr << std::endl; - long a = 20; long *l = static_cast(gc->alloc(sizeof(long))); - std::cout << "Pointer for l:\t\t" << &l << std::endl; - int *i = static_cast(gc->alloc(sizeof(int))); - std::cout << "Pointer for i:\t\t" << &i << std::endl; - //l = &a; - //*l = 20; + std::cout << "l points to:\t\t" << l << std::endl; + detach_pointer(&l); + std::cout << "l points to:\t\t" << l << std::endl; + // l still gets marked, which is not supposed to happen } int main() { auto stack_start = reinterpret_cast(__builtin_frame_address(0)); std::cout << "Stack start from main:\t" << stack_start << std::endl; init(); - gc->collect(MARK | SWEEP); // some bug in free (vector out of range) + gc->collect(MARK); // some bug in free (vector out of range) gc->print_contents(); - //delete gc; return 0; } \ No newline at end of file diff --git a/src/GC/todo.md b/src/GC/todo.md index 009ab51..f1e60a2 100644 --- a/src/GC/todo.md +++ b/src/GC/todo.md @@ -8,6 +8,7 @@ Goal for next week (24/2): ## GC TODO: - Merge to main branch - Fix singleton references +- Think about how we want to determine if some object is a pointer or not, probably will have to discuss that with Samuel. Since it is not ideal to determine in the GC if an object is a pointer or not. It should preferably be done in a previous stage. ## Tests TODO ### Library linking