Minor changes
Co-authored-by: ValterMiari <ValterMiari@users.noreply.github.com>
This commit is contained in:
parent
edeff09e86
commit
8081bc5d67
11 changed files with 39 additions and 81 deletions
|
|
@ -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.");
|
||||||
} */
|
}
|
||||||
|
|
@ -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.");
|
||||||
} */
|
}
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} */
|
}
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -22,8 +22,13 @@ namespace GC
|
||||||
{
|
{
|
||||||
return m_chunk;
|
return m_chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GCEvent::get_size()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
const char *const GCEvent::type_to_string()
|
const char *GCEvent::type_to_string()
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue