Debugged mark()

Co-authored-by: ValterMiari <ValterMiari@users.noreply.github.com>
This commit is contained in:
Victor Olin 2023-02-17 12:14:11 +01:00
parent d40350a263
commit 5f6a18a2ab
5 changed files with 66 additions and 33 deletions

View file

@ -7,19 +7,23 @@ CFLAGS = -Wall -Wextra -v -g -std=gnu++20 -stdlib=libc++ -I
VGFLAGS = --leak-check=full --show-leak-kinds=all
heap:
$(CC) $(CFLAGS)$(PWD_V) lib/heap.cpp
$(CC) $(CFLAGS)$(PWD) lib/heap.cpp
h_test:
rm -f tests/h_test.out
$(CC) $(CFLAGS)$(PWD_V) tests/h_test.cpp lib/heap.cpp -o tests/h_test.out
$(CC) $(CFLAGS)$(PWD) tests/h_test.cpp lib/heap.cpp -o tests/h_test.out
h_test_vg:
make h_test
valgrind $(VGFLAGS) tests/h_test.out
h_test_dbg:
make h_test
lldb tests/h_test.out launch
linker:
rm -f tests/linker.out
$(CC) $(CFLAGS)$(PWD_V) tests/linker.cpp lib/heap.cpp -o tests/linker.out
$(CC) $(CFLAGS)$(PWD) tests/linker.cpp lib/heap.cpp -o tests/linker.out
linker_vg:
make linker

View file

@ -32,6 +32,7 @@ namespace GC {
// void compact();
void mark(uintptr_t *start, const uintptr_t *end, std::vector<Chunk *> worklist);
void print_line(Chunk *chunk);
void print_worklist(std::vector<Chunk *> list);
inline static Heap *m_instance = nullptr;
const char *m_heap;

View file

@ -23,6 +23,7 @@ namespace GC {
}
// kolla freed chunks innan
// denna är helt onödig just nu, freed chunks kommer alltid va tom
for (size_t i = 0; i < m_freed_chunks.size(); i++) {
auto cp = m_freed_chunks.at(i);
if (cp->size > size)
@ -90,7 +91,14 @@ namespace GC {
void Heap::collect(uint flags) {
cout << "DEBUG COLLECT\nFLAGS: " << flags << endl;
cout << "DEBUG COLLECT\nFLAGS: ";
if (flags & MARK)
cout << "\n - MARK";
if (flags & SWEEP)
cout << "\n - SWEEP";
if (flags & FREE)
cout << "\n - FREE";
cout << endl;
// get the frame adress, whwere local variables and saved registers are located
auto stack_start = reinterpret_cast<uintptr_t *>(__builtin_frame_address(0));
cout << "Stack start:\t" << stack_start << endl;
@ -101,6 +109,7 @@ namespace GC {
// reinterpret_cast<const uintptr_t *>(__builtin_frame_address(10));
auto work_list = m_allocated_chunks;
// print_worklist(work_list);
if (flags & MARK) {
mark(stack_start, stack_end, work_list);
@ -136,24 +145,28 @@ namespace GC {
}
// TODO: return the worklist filtered on mark = true
void Heap::mark(uintptr_t *start, const uintptr_t *end, vector<Chunk*> work_list) {
// 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<Chunk*> worklist) {
for (; start > end; start--) { // to find adresses thats in the worklist
cout << "Value of start pointer:\t" << start << endl;
for (size_t i = 0; i < work_list.size(); i++) { // fix this
auto chunk = work_list.at(i);
cout << "Chunk value:\t" << chunk->start << endl;
cout << "Chunk pointer value:\t" << &chunk << endl;
if (chunk->start <= start && start < chunk->start + chunk->size) {
if (*start % 8 == 0) { // all pointers must be aligned as double words
for (size_t i = 0; i < worklist.size(); i++) { // fix this
auto chunk = worklist.at(i);
uintptr_t c_start = reinterpret_cast<uintptr_t>(chunk->start);
uintptr_t c_end = reinterpret_cast<uintptr_t>(chunk->start + chunk->size);
if (c_start <= *start && *start < c_end) {
uintptr_t c_start = reinterpret_cast<uintptr_t>(chunk->start);
if (!chunk->marked) {
chunk->marked = true;
work_list.erase(work_list.begin() + i);
mark(reinterpret_cast<uintptr_t *>(chunk->start + chunk->size), end, work_list); //
worklist.erase(worklist.begin() + i);
auto new_stack_start = reinterpret_cast<uintptr_t *>(start);
mark(new_stack_start, end, worklist); //
return;
}
}
}
}
}
}
/* void mark_test(vector<Chunk *> worklist) {
while (worklist.size() > 0) {
@ -204,6 +217,12 @@ namespace GC {
cout << "Marked: " << chunk->marked << "\nStart adr: " << chunk->start << "\nSize: " << chunk->size << " B\n" << endl;
}
void Heap::print_worklist(std::vector<Chunk *> list) {
for (auto cp : list) {
cout << "Chunk at:\t" << cp->start << "\nSize:\t\t" << cp->size << endl;
}
}
void Heap::print_contents() {
if (m_allocated_chunks.size()) {
cout << "\nALLOCATED CHUNKS #" << m_allocated_chunks.size() << endl;

View file

@ -5,28 +5,26 @@ GC::Heap *gc = GC::Heap::the2();
void init() {
auto stack_start = reinterpret_cast<uintptr_t *>(__builtin_frame_address(0));
auto stack_end = stack_start - 160;
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<int *>(gc->alloc(sizeof(int) * 300));
for (int i = 0; i < (sizeof(int) * 300); i++) {
int *arr = static_cast<int *>(gc->alloc(sizeof(int) * 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;
}
std::cout << "First stack pointer:\t" << &arr << std::endl;
long a = 20;
long *l = static_cast<long *>(gc->alloc(sizeof(long)));
*l = 20;
// This doesn't get allocated on our heap, but how is it viewed on valgr?
int *arr2 = new int[1000];
for (int i = 0; i < 1000; i++) {
arr2[i] = i;
}
l = &a;
//*l = 20;
}
int main() {
auto stack_start = reinterpret_cast<uintptr_t *>(__builtin_frame_address(0));
std::cout << "Stack start from main:\t" << stack_start << std::endl;
init();
gc->collect(MARK | SWEEP);
gc->collect(MARK | SWEEP | FREE);
gc->print_contents();
//delete gc;
return 0;

View file

@ -6,16 +6,13 @@ Goal for next week (17/2):
- Functioning garbage collector
- Test it with valgrind
TODO:
## GC TODO:
- Merge to main branch
## Algorithm
Potential algorithms:
- mark & sweep
- Don't empty m_free_chunks, reuse in a better way **Victor fixes this**
## Tests TODO
### Library linking
**Victor fixes this**
Compile the GC lib and a test separately, link them together
and evalutate the following:
@ -24,3 +21,17 @@ and evalutate the following:
__builtin_return_address(0)
__builtin_return_address(1)
### GC Init and __b_f_a
1. Save the first stack fram globally as the stack start
2. For each call to collect, save the prev stack frame as the stack end
3. Scan through the span
gc_init()
global stack_end = __builtin_frame_address(1)
collect()
global stack_start = __builtin_frame_address(1)
sweep()
for all addr in range(stack_end, stack_start)
mark if chunk