diff --git a/src/GC/include/cheap.h b/src/GC/include/cheap.h index 7d803a8..84f5971 100644 --- a/src/GC/include/cheap.h +++ b/src/GC/include/cheap.h @@ -7,6 +7,7 @@ extern "C" { #endif +#define DEBUG #define WRAPPER_DEBUG #ifdef WRAPPER_DEBUG diff --git a/src/GC/include/heap.hpp b/src/GC/include/heap.hpp index 2d116bb..b6fe104 100644 --- a/src/GC/include/heap.hpp +++ b/src/GC/include/heap.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "chunk.hpp" #include "profiler.hpp" @@ -52,7 +53,6 @@ namespace GC char *const m_heap; size_t m_size {0}; - char *m_heap_top {nullptr}; // static Heap *m_instance {nullptr}; uintptr_t *m_stack_top {nullptr}; bool m_profiler_enable {false}; @@ -60,6 +60,7 @@ namespace GC std::vector m_allocated_chunks; std::vector m_freed_chunks; std::list m_free_list; + std::unordered_map m_chunk_table; static bool profiler_enabled(); // static Chunk *get_at(std::vector &list, size_t n); @@ -69,6 +70,8 @@ namespace GC void free(Heap &heap); void free_overlap(Heap &heap); void mark(uintptr_t *start, const uintptr_t *end, std::vector &worklist); + void mark_hash(uintptr_t *start, const uintptr_t *end); + void create_table(); void print_line(Chunk *chunk); void print_worklist(std::vector &list); void mark_step(uintptr_t start, uintptr_t end, std::vector &worklist); diff --git a/src/GC/lib/heap.cpp b/src/GC/lib/heap.cpp index ff1743d..f999ef8 100644 --- a/src/GC/lib/heap.cpp +++ b/src/GC/lib/heap.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "heap.hpp" @@ -9,7 +10,7 @@ #define time_now std::chrono::high_resolution_clock::now() #define to_us std::chrono::duration_cast -using std::cout, std::endl, std::vector, std::hex, std::dec; +using std::cout, std::endl, std::vector, std::hex, std::dec, std::unordered_map; namespace GC { @@ -91,6 +92,12 @@ namespace GC // Profiler::record(AllocStart, a_ms); heap.collect(); // If memory is not enough after collect, crash with OOM error + if (heap.m_size > HEAP_SIZE) + { + throw std::runtime_error(std::string("Error: Heap out of memory")); + } + //throw std::runtime_error(std::string("Error: Heap out of memory")); + } if (heap.m_size + size > HEAP_SIZE) { if (profiler_enabled) @@ -116,6 +123,7 @@ namespace GC auto new_chunk = new Chunk(size, (uintptr_t *)(heap.m_heap + heap.m_size)); heap.m_size += size; + heap.m_total_size += size; heap.m_allocated_chunks.push_back(new_chunk); if (profiler_enabled) @@ -152,7 +160,8 @@ namespace GC //auto chunk = Heap::get_at(heap.m_freed_chunks, i); auto chunk = heap.m_freed_chunks[i]; auto iter = heap.m_freed_chunks.begin(); - advance(iter, i); + i++; + //advance(iter, i); if (chunk->m_size > size) { // Split the chunk, use one part and add the remaining part to @@ -214,8 +223,12 @@ namespace GC uintptr_t *stack_top = heap.m_stack_top; - auto work_list = heap.m_allocated_chunks; - mark(stack_bottom, stack_top, work_list); + //auto work_list = heap.m_allocated_chunks; + //mark(stack_bottom, stack_top, work_list); + + // Testing mark_hash, previous woking implementation above + create_table(); + mark_hash(stack_bottom, stack_top); sweep(heap); @@ -426,6 +439,7 @@ namespace GC heap.m_freed_chunks.pop_back(); if (profiler_enabled) Profiler::record(ChunkFreed, chunk); + heap.m_size -= chunk->m_size; delete chunk; } } @@ -488,6 +502,7 @@ namespace GC { if (profiler_enabled) Profiler::record(ChunkFreed, chunk); + heap.m_size -= chunk->m_size; delete chunk; } else diff --git a/src/GC/lib/profiler.cpp b/src/GC/lib/profiler.cpp index ae31f0d..78a0b8e 100644 --- a/src/GC/lib/profiler.cpp +++ b/src/GC/lib/profiler.cpp @@ -11,7 +11,7 @@ #include "event.hpp" #include "profiler.hpp" -// #define MAC_OS +#define MAC_OS namespace GC { diff --git a/src/GC/tests/h_test.cpp b/src/GC/tests/h_test.cpp index 625e36a..6ce727e 100644 --- a/src/GC/tests/h_test.cpp +++ b/src/GC/tests/h_test.cpp @@ -11,7 +11,7 @@ struct Node { }; Node *create_chain(int depth) { - cout << "entering create_chain"; + cout << "entering create_chain" << endl; std::vector nodes; if (depth > 0) { Node *last_node = static_cast(GC::Heap::alloc(sizeof(Node))); @@ -36,14 +36,14 @@ void create_array(size_t size) { } void detach_pointer(long **ptr) { - cout << "entering detach_pointer"; + cout << "entering detach_pointer" << endl; long *dummy_ptr = nullptr; *ptr = dummy_ptr; cout << "\nexiting detach_pointer" << endl; } Node *test_chain(int depth, bool detach) { - cout << "entering test_chain"; + cout << "entering test_chain" << endl; auto stack_start = reinterpret_cast(__builtin_frame_address(0)); Node *node_chain = create_chain(depth); @@ -86,9 +86,8 @@ int main() { Node *root1 = static_cast(gc.alloc(sizeof(Node))); Node *root2 = static_cast(gc.alloc(sizeof(Node))); - root1 = test_chain(58000, false); - root2 = test_chain(58000, false); - + root1 = test_chain(100000, false); + //root2 = test_chain(58000, false); gc.collect(GC::COLLECT_ALL); auto end = std::chrono::high_resolution_clock::now(); diff --git a/src/GC/tests/h_test.out.dSYM/Contents/Info.plist b/src/GC/tests/h_test.out.dSYM/Contents/Info.plist new file mode 100644 index 0000000..3db2218 --- /dev/null +++ b/src/GC/tests/h_test.out.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.h_test.out + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/GC/tests/h_test.out.dSYM/Contents/Resources/DWARF/h_test.out b/src/GC/tests/h_test.out.dSYM/Contents/Resources/DWARF/h_test.out new file mode 100644 index 0000000..0d4c74f Binary files /dev/null and b/src/GC/tests/h_test.out.dSYM/Contents/Resources/DWARF/h_test.out differ diff --git a/src/GC/tests/wrapper_test.c b/src/GC/tests/wrapper_test.c index 729cf69..2055b8c 100644 --- a/src/GC/tests/wrapper_test.c +++ b/src/GC/tests/wrapper_test.c @@ -12,17 +12,7 @@ typedef struct node { Node *HEAD = NULL; Node *CURRENT = NULL; -// Creates a linked list of length depth. Global head "HEAD" is updated. -void *create_linked_list(int depth) { - HEAD = (Node*)(cheap_alloc(sizeof(Node))); - HEAD->id = 0; - // Purposely omitting adding a child to "last_node", since its the last node - for (int i = 1; i < depth - 1; i++) { - insert_first(i); - } -} - -void *insert_first(int node_id) { +void insert_first(int node_id) { Node *new_head; new_head = (Node*)(cheap_alloc(sizeof(Node))); new_head->id = node_id; @@ -31,15 +21,33 @@ void *insert_first(int node_id) { HEAD = new_head; } -void test_linked_list(int list_length){ +// Creates a linked list of length depth. Global head "HEAD" is updated. +Node *create_linked_list(int depth) { + HEAD = (Node*)(cheap_alloc(sizeof(Node))); + HEAD->id = 0; + // Purposely omitting adding a child to "last_node", since its the last node + for (int i = 1; i < depth - 1; i++) { + insert_first(i); + } + return HEAD; +} + +void create_garbage(int amount) { + for (int i = 0; i < amount; i++) { + long *garbage = (long*)(cheap_alloc(sizeof(long))); + } +} + +int main () { cheap_init(); cheap_t *heap = cheap_the(); cheap_set_profiler(heap, true); - create_linked_list(list_length); - cheap_dispose(); - free(heap); -} -int main (int argc, char **argv) { - test_linked_list(30); + // Every node in this list should be marked + Node *head = create_linked_list(5); + // Everything create here should be swept + create_garbage(30); + + cheap_dispose(); + return 0; } \ No newline at end of file