diff --git a/src/GC/include/heap.hpp b/src/GC/include/heap.hpp index be1b12e..0bd3d36 100644 --- a/src/GC/include/heap.hpp +++ b/src/GC/include/heap.hpp @@ -15,6 +15,8 @@ #define FREE (uint) 0x4 #define COLLECT_ALL (uint) 0x7 +#define FREE_THRESH (uint) 20 + namespace GC { class Heap { @@ -29,6 +31,8 @@ namespace GC { void collect(); void sweep(); + void free(); + void free_overlap(); // void compact(); void mark(uintptr_t *start, const uintptr_t *end, std::vector worklist); void print_line(Chunk *chunk); diff --git a/src/GC/lib/heap.cpp b/src/GC/lib/heap.cpp index f01233b..480fc3b 100644 --- a/src/GC/lib/heap.cpp +++ b/src/GC/lib/heap.cpp @@ -79,16 +79,44 @@ namespace GC { // compact(); + free(); + // We shouldn't do this, since then m_freed_chunks doesnt' have any real purpose, // it should be used in alloc, it isn't if we delete *all* of its contentes // release free chunks - while (m_freed_chunks.size()) { - auto chunk_pointer = m_freed_chunks.back(); - m_freed_chunks.pop_back(); - delete chunk_pointer; // deletes chunk object, doesn't free memory to the OS + // while (m_freed_chunks.size()) { + // auto chunk_pointer = m_freed_chunks.back(); + // m_freed_chunks.pop_back(); + // delete chunk_pointer; // deletes chunk object, doesn't free memory to the OS + // } + } + + void Heap::free() { + if (m_freed_chunks.size() > FREE_THRESH) { + while (m_freed_chunks.size()) { + auto chunk = m_freed_chunks.back(); + m_freed_chunks.pop_back(); + delete chunk; + } + } else { + free_overlap(); } } + void Heap::free_overlap() { + std::vector filtered; + size_t i = 0; + filtered.push_back(m_freed_chunks.at(i++)); + for (; i < m_freed_chunks.size(); i++) { + auto prev = filtered.back(); + auto next = m_freed_chunks.at(i); + if (next->start > (prev->start + prev->size)) { + filtered.push_back(next); + } + } + m_freed_chunks.swap(filtered); + } + void Heap::collect(uint flags) { cout << "DEBUG COLLECT\nFLAGS: "; @@ -119,14 +147,18 @@ namespace GC { sweep(); } - //release free chunks if (flags & FREE) { - while (m_freed_chunks.size()) { - auto chunk_pointer = m_freed_chunks.back(); - m_freed_chunks.pop_back(); - delete chunk_pointer; // deletes chunk object, doesn't free heap memory to the OS - } + free(); } + + //release free chunks + // if (flags & FREE) { + // while (m_freed_chunks.size()) { + // auto chunk_pointer = m_freed_chunks.back(); + // m_freed_chunks.pop_back(); + // delete chunk_pointer; // deletes chunk object, doesn't free heap memory to the OS + // } + // } } // Not optimal for now, it doesn't have to loop over all objects diff --git a/src/GC/todo.md b/src/GC/todo.md index a327d71..3386d65 100644 --- a/src/GC/todo.md +++ b/src/GC/todo.md @@ -2,9 +2,8 @@ ## Project -Goal for next week (17/2): -- Functioning garbage collector -- Test it with valgrind +Goal for next week (24/2): +- Debug ## GC TODO: - Merge to main branch @@ -30,7 +29,7 @@ and evalutate the following: global stack_end = __builtin_frame_address(1) collect() - global stack_start = __builtin_frame_address(1) + local stack_start = __builtin_frame_address(1) sweep() for all addr in range(stack_end, stack_start)