diff --git a/src/GC/include/cheap.h b/src/GC/include/cheap.h index 7d803a8..7bfab4e 100644 --- a/src/GC/include/cheap.h +++ b/src/GC/include/cheap.h @@ -7,7 +7,11 @@ extern "C" { #endif +<<<<<<< HEAD #define WRAPPER_DEBUG +======= +#define DEBUG +>>>>>>> 74e0282 (Added Hash map marking) #ifdef WRAPPER_DEBUG typedef struct cheap diff --git a/src/GC/include/heap.hpp b/src/GC/include/heap.hpp index 2d116bb..28c1276 100644 --- a/src/GC/include/heap.hpp +++ b/src/GC/include/heap.hpp @@ -3,13 +3,20 @@ #include #include #include +#include #include "chunk.hpp" #include "profiler.hpp" +<<<<<<< HEAD #define HEAP_SIZE 320//65536 #define FREE_THRESH (uint) 0 // #define HEAP_DEBUG +======= +#define HEAP_SIZE 2097152 //256 //65536 //2097152 +#define FREE_THRESH (uint) 100000 //1000 +#define DEBUG +>>>>>>> 74e0282 (Added Hash map marking) namespace GC { @@ -52,14 +59,22 @@ namespace GC char *const m_heap; size_t m_size {0}; +<<<<<<< HEAD char *m_heap_top {nullptr}; +======= + size_t m_total_size {0}; +>>>>>>> 74e0282 (Added Hash map marking) // static Heap *m_instance {nullptr}; uintptr_t *m_stack_top {nullptr}; bool m_profiler_enable {false}; std::vector m_allocated_chunks; std::vector m_freed_chunks; +<<<<<<< HEAD std::list m_free_list; +======= + std::unordered_map m_chunk_table; +>>>>>>> 74e0282 (Added Hash map marking) static bool profiler_enabled(); // static Chunk *get_at(std::vector &list, size_t n); @@ -69,6 +84,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..c344ee8 100644 --- a/src/GC/lib/heap.cpp +++ b/src/GC/lib/heap.cpp @@ -2,6 +2,7 @@ #include #include #include +<<<<<<< HEAD #include #include "heap.hpp" @@ -10,6 +11,13 @@ #define to_us std::chrono::duration_cast using std::cout, std::endl, std::vector, std::hex, std::dec; +======= +#include + +#include "heap.hpp" + +using std::cout, std::endl, std::vector, std::hex, std::dec, std::unordered_map; +>>>>>>> 74e0282 (Added Hash map marking) namespace GC { @@ -91,12 +99,20 @@ namespace GC // Profiler::record(AllocStart, a_ms); heap.collect(); // If memory is not enough after collect, crash with OOM error +<<<<<<< HEAD if (heap.m_size + size > HEAP_SIZE) { if (profiler_enabled) Profiler::dispose(); throw std::runtime_error(std::string("Error: Heap out of memory")); } +======= + 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")); +>>>>>>> 74e0282 (Added Hash map marking) } // If a chunk was recycled, return the old chunk address @@ -116,6 +132,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 +169,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 +232,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); @@ -306,6 +328,7 @@ namespace GC rangeWL.clear(); } +<<<<<<< HEAD void Heap::mark_range(vector &ranges, vector &worklist) { Heap &heap = Heap::the(); @@ -352,10 +375,42 @@ namespace GC { wliter++; } +======= + void Heap::create_table() + { + Heap &heap = Heap::the(); + unordered_map chunk_table; + for (auto chunk : heap.m_allocated_chunks) { + auto pair = std::make_pair(reinterpret_cast(chunk->m_start), chunk); + heap.m_chunk_table.insert(pair); + } + } + + void Heap::mark_hash(uintptr_t *start, const uintptr_t* const end) + { + Heap &heap = Heap::the(); + for (; start <= end; start++) + { + auto search = heap.m_chunk_table.find(*start); + if (search != heap.m_chunk_table.end()) + { + Chunk *chunk = search->second; + auto c_start = reinterpret_cast(chunk->m_start); + auto c_size = reinterpret_cast(chunk->m_size); + auto c_end = reinterpret_cast(c_start + c_size); + if (!chunk->m_marked) + { + chunk->m_marked = true; + mark_hash(chunk->m_start, c_end); +>>>>>>> 74e0282 (Added Hash map marking) } } } } +<<<<<<< HEAD +======= + +>>>>>>> 74e0282 (Added Hash map marking) /** * Sweeps the heap, unmarks the marked chunks for the next cycle, @@ -426,6 +481,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 +544,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