Implemented free chunk swaps and filtering

This commit is contained in:
Victor Olin 2023-02-18 13:31:16 +01:00
parent 5f6a18a2ab
commit c6c0468c8d
3 changed files with 49 additions and 14 deletions

View file

@ -15,6 +15,8 @@
#define FREE (uint) 0x4 #define FREE (uint) 0x4
#define COLLECT_ALL (uint) 0x7 #define COLLECT_ALL (uint) 0x7
#define FREE_THRESH (uint) 20
namespace GC { namespace GC {
class Heap { class Heap {
@ -29,6 +31,8 @@ namespace GC {
void collect(); void collect();
void sweep(); void sweep();
void free();
void free_overlap();
// void compact(); // void compact();
void mark(uintptr_t *start, const uintptr_t *end, std::vector<Chunk *> worklist); void mark(uintptr_t *start, const uintptr_t *end, std::vector<Chunk *> worklist);
void print_line(Chunk *chunk); void print_line(Chunk *chunk);

View file

@ -79,14 +79,42 @@ namespace GC {
// compact(); // compact();
free();
// We shouldn't do this, since then m_freed_chunks doesnt' have any real purpose, // 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 // it should be used in alloc, it isn't if we delete *all* of its contentes
// release free chunks // release free chunks
while (m_freed_chunks.size()) { // while (m_freed_chunks.size()) {
auto chunk_pointer = m_freed_chunks.back(); // auto chunk_pointer = m_freed_chunks.back();
m_freed_chunks.pop_back(); // m_freed_chunks.pop_back();
delete chunk_pointer; // deletes chunk object, doesn't free memory to the OS // 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<Chunk *> 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) { void Heap::collect(uint flags) {
@ -119,14 +147,18 @@ namespace GC {
sweep(); sweep();
} }
//release free chunks
if (flags & FREE) { if (flags & FREE) {
while (m_freed_chunks.size()) { free();
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
}
} }
//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 // Not optimal for now, it doesn't have to loop over all objects

View file

@ -2,9 +2,8 @@
## Project ## Project
Goal for next week (17/2): Goal for next week (24/2):
- Functioning garbage collector - Debug
- Test it with valgrind
## GC TODO: ## GC TODO:
- Merge to main branch - Merge to main branch
@ -30,7 +29,7 @@ and evalutate the following:
global stack_end = __builtin_frame_address(1) global stack_end = __builtin_frame_address(1)
collect() collect()
global stack_start = __builtin_frame_address(1) local stack_start = __builtin_frame_address(1)
sweep() sweep()
for all addr in range(stack_end, stack_start) for all addr in range(stack_end, stack_start)