Minor changes

Co-authored-by: ValterMiari <ValterMiari@users.noreply.github.com>
This commit is contained in:
Victor Olin 2023-03-21 14:31:40 +01:00
parent edeff09e86
commit 8081bc5d67
11 changed files with 39 additions and 81 deletions

View file

@ -1,4 +1,4 @@
/* // TODO: include these properly // TODO: include these properly
#include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/GCMetadata.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
@ -13,4 +13,4 @@ namespace {
GCRegistry::Add<GC> GCRegistry::Add<GC>
X("gc", "The bespoken garbage collector."); X("gc", "The bespoken garbage collector.");
} */ }

View file

@ -1,4 +1,4 @@
/* #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
using namespace llvm; using namespace llvm;
@ -13,4 +13,4 @@ namespace {
GCMetadataPrinterRegistry::Add<MyGCPrinter> GCMetadataPrinterRegistry::Add<MyGCPrinter>
X("gc", "The bespoken garbage collector."); X("gc", "The bespoken garbage collector.");
} */ }

View file

@ -1,4 +1,4 @@
/* /// The map for a single function's stack frame. One of these is /// The map for a single function's stack frame. One of these is
/// compiled as constant data into the executable for each function. /// compiled as constant data into the executable for each function.
/// ///
/// Storage of metadata values is elided if the %metadata parameter to /// Storage of metadata values is elided if the %metadata parameter to
@ -60,4 +60,4 @@ void traverseStackMap() {
Constant *RootMetadata = RI->Metadata; Constant *RootMetadata = RI->Metadata;
} }
} }
} */ }

View file

@ -20,22 +20,20 @@ heap:
h_test: h_test:
rm -f tests/h_test.out rm -f tests/h_test.out
$(CC) $(WFLAGS) $(STDFLAGS) $(LIB_INCL) tests/h_test.cpp lib/heap.cpp lib/profiler.cpp lib/event.cpp -o tests/h_test.out # $(CC) $(WFLAGS) $(STDFLAGS) $(LIB_INCL) tests/h_test.cpp lib/heap.cpp lib/profiler.cpp lib/event.cpp -o tests/h_test.out
$(CC) $(STDFLAGS) $(WFLAGS) $(LIB_INCL) -o tests/h_test.out tests/h_test.cpp lib/gcoll.a
h_test_vg: h_test_vg: h_test
make h_test
valgrind $(VGFLAGS) tests/h_test.out valgrind $(VGFLAGS) tests/h_test.out
h_test_dbg: h_test_dbg: h_test
make h_test
lldb tests/h_test.out launch lldb tests/h_test.out launch
linker: linker:
rm -f tests/linker.out rm -f tests/linker.out
$(CC) $(WFLAGS) $(STDFLAGS) $(LIB_INCL) tests/linker.cpp lib/heap.cpp -o tests/linker.out $(CC) $(WFLAGS) $(STDFLAGS) $(LIB_INCL) tests/linker.cpp lib/heap.cpp -o tests/linker.out
linker_vg: linker_vg: linker
make linker
valgrind $(VGFLAGS) tests/linker.out valgrind $(VGFLAGS) tests/linker.out
game: game:

View file

@ -60,6 +60,7 @@ namespace GC
GCEventType get_type(); GCEventType get_type();
std::time_t get_time_stamp(); std::time_t get_time_stamp();
Chunk *get_chunk(); Chunk *get_chunk();
const char *const type_to_string(); size_t get_size();
const char *type_to_string();
}; };
} }

View file

@ -11,6 +11,7 @@
#define HEAP_SIZE 65536 #define HEAP_SIZE 65536
#define FREE_THRESH (uint)20 #define FREE_THRESH (uint)20
#define DEBUG
namespace GC namespace GC
{ {
@ -93,7 +94,7 @@ namespace GC
static void dispose(); static void dispose();
static void *alloc(size_t size); static void *alloc(size_t size);
// DEBUG ONLY #ifdef DEBUG
static inline Heap *debug_the() static inline Heap *debug_the()
{ {
if (m_instance) // if m_instance is not a nullptr if (m_instance) // if m_instance is not a nullptr
@ -106,5 +107,6 @@ namespace GC
void print_contents(); // print dummy things void print_contents(); // print dummy things
void print_allocated_chunks(Heap *heap); // print the contents in m_allocated_chunks void print_allocated_chunks(Heap *heap); // print the contents in m_allocated_chunks
void set_profiler(bool mode); void set_profiler(bool mode);
#endif
}; };
} }

View file

@ -23,7 +23,12 @@ namespace GC
return m_chunk; return m_chunk;
} }
const char *const GCEvent::type_to_string() size_t GCEvent::get_size()
{
return m_size;
}
const char *GCEvent::type_to_string()
{ {
switch (m_type) switch (m_type)
{ {

View file

@ -27,6 +27,7 @@ namespace GC
Heap *heap = Heap::the(); Heap *heap = Heap::the();
if (heap->profiler_enabled()) if (heap->profiler_enabled())
Profiler::record(HeapInit); Profiler::record(HeapInit);
#pragma clang diagnostic ignored "-Wframe-address" // clang complains because arg for __b_f_a is not 0
heap->m_stack_top = static_cast<uintptr_t *>(__builtin_frame_address(1)); heap->m_stack_top = static_cast<uintptr_t *>(__builtin_frame_address(1));
} }
@ -194,7 +195,6 @@ namespace GC
{ {
Heap *heap = Heap::the(); Heap *heap = Heap::the();
bool profiler_enabled = heap->profiler_enabled(); bool profiler_enabled = heap->profiler_enabled();
cout << "--- mark() was called ---\n" << endl;
if (profiler_enabled) if (profiler_enabled)
Profiler::record(MarkStart); Profiler::record(MarkStart);
// To find adresses thats in the worklist // To find adresses thats in the worklist
@ -224,7 +224,6 @@ namespace GC
if (profiler_enabled) if (profiler_enabled)
Profiler::record(ChunkMarked, chunk); Profiler::record(ChunkMarked, chunk);
chunk->marked = true; chunk->marked = true;
cout << "Marked this chunk ^\n" << endl;
// Remove the marked chunk from the worklist // Remove the marked chunk from the worklist
it = worklist.erase(it); it = worklist.erase(it);
// Recursively call mark, to see if the reachable chunk further points to another chunk // Recursively call mark, to see if the reachable chunk further points to another chunk
@ -245,55 +244,6 @@ namespace GC
} }
} }
// Testing a strategy where if a pointer on the stack is pointing to a chunk, nested chunks,
// that are not located on the stack frame, will possibly be adjecent to the found chunk,
// allowing for a different, more efficient strategy, that doesn't have to scan the stack frame
void Heap::mark_step(uintptr_t start, uintptr_t end, vector<Chunk *> &worklist) {
// Should loop through the chunk size, such that if the object holds a pointer,
// wherever that pointer is located in the object, that pointer, to another chunk,
// gets detected
cout << "--- mark_step() was called ---\n" << endl;
for (; start <= end; start += sizeof(uintptr_t))
{
auto it = worklist.begin();
auto end = worklist.end();
while (it != end)
{
Chunk *chunk = *it;
auto c_start = reinterpret_cast<uintptr_t>(chunk->start);
auto c_size = reinterpret_cast<uintptr_t>(chunk->size);
auto c_end = reinterpret_cast<uintptr_t>(c_start + c_size);
cout << "Value of Start:\t\t" << start << endl;
cout << "Chunk start:\t\t" << hex << c_start << endl;
cout << "Chunk end:\t\t" << hex << c_end << "\n" << endl;
if (c_start <= start && start < c_end)
{
if (!chunk->marked) {
// Mark the chunk and erase it from the worklist
chunk->marked = true;
it = worklist.erase(it);
cout << "Marked this chunk ^\n" << endl;
// Update the memory location we want to look at
//memory_location = c_end;
mark_step(c_start, c_end, worklist);
}
else
{
it++;
}
}
else
{
it++;
}
}
}
}
/** /**
* Sweeps the heap, unmarks the marked chunks for the next cycle, * Sweeps the heap, unmarks the marked chunks for the next cycle,
@ -303,9 +253,7 @@ namespace GC
*/ */
void Heap::sweep(Heap *heap) void Heap::sweep(Heap *heap)
{ {
cout << "--- sweep() was called ---" << endl;
auto iter = heap->m_allocated_chunks.begin(); auto iter = heap->m_allocated_chunks.begin();
auto stop = heap->m_allocated_chunks.end();
bool profiler_enabled = heap->profiler_enabled(); bool profiler_enabled = heap->profiler_enabled();
// This cannot "iter != stop", results in seg fault, since the end gets updated, I think. // This cannot "iter != stop", results in seg fault, since the end gets updated, I think.
while (iter != heap->m_allocated_chunks.end()) while (iter != heap->m_allocated_chunks.end())
@ -341,7 +289,6 @@ namespace GC
*/ */
void Heap::free(Heap *heap) void Heap::free(Heap *heap)
{ {
cout << "--- free() was called ---" << endl;
if (heap->m_freed_chunks.size() > FREE_THRESH) if (heap->m_freed_chunks.size() > FREE_THRESH)
{ {
bool profiler_enabled = heap->profiler_enabled(); bool profiler_enabled = heap->profiler_enabled();
@ -352,7 +299,6 @@ namespace GC
if (profiler_enabled) if (profiler_enabled)
Profiler::record(ChunkFreed, chunk); Profiler::record(ChunkFreed, chunk);
delete chunk; delete chunk;
cout << "Freed chunk was deleted" << endl;
} }
} }
// if there are chunks but not more than FREE_THRESH // if there are chunks but not more than FREE_THRESH

View file

@ -68,8 +68,10 @@ namespace GC
<< "\n Size: " << chunk->size << "\n Size: " << chunk->size
<< "\n Mark: " << chunk->marked; << "\n Mark: " << chunk->marked;
} }
fstr << "\n--------------------------------" << std::endl; // else if (event->get)
fstr << "\n";
} }
fstr << "--------------------------------" << std::endl;
} }
void Profiler::dispose() { void Profiler::dispose() {

View file

@ -68,6 +68,7 @@ void test_some_types() {
int main() { int main() {
GC::Heap::init(); GC::Heap::init();
GC::Heap *gc = GC::Heap::debug_the(); GC::Heap *gc = GC::Heap::debug_the();
gc->set_profiler(true);
gc->check_init(); gc->check_init();
auto stack_start = reinterpret_cast<uintptr_t *>(__builtin_frame_address(0)); auto stack_start = reinterpret_cast<uintptr_t *>(__builtin_frame_address(0));
std::cout << "Stack start from main:\t" << stack_start << std::endl; std::cout << "Stack start from main:\t" << stack_start << std::endl;
@ -96,5 +97,7 @@ int main() {
gc->collect(GC::COLLECT_ALL); gc->collect(GC::COLLECT_ALL);
gc->print_contents(); gc->print_contents();
gc->dispose();
return 0; return 0;
} }

View file

@ -1,16 +1,17 @@
# Garbage collection # Garbage collection
## Project ## Project
Deliver to samuel
Goal for next week (24/2):
- Write more complex tests
## GC TODO: ## GC TODO:
- Kolla linking med Valter/Victor - Code cleanup
- Fixa en a-fil/static lib till Samuel - Dokumentera
- Kolla vektor vs list complexity - Dokumentera alla filer och funktioner
- Se om det är bättre att lagra Chunk och inte Chunk* i data strukturerna, - Skriva reference guide för Samuel
då är alla efter varandra i minnet. - PR till master
## Tests TODO ## Tests TODO
- Write complex datastructures for tests with larger programs - Write complex datastructures for tests with larger programs
## Profiler grejer
- Fixa användning av `Profiler::record(GCEventType type, size_t size)` i både alloc och dump_trace