Added Hash map marking

This commit is contained in:
valtermiari 2023-05-04 13:51:53 +02:00 committed by Victor Olin
parent 3e188553d6
commit a5c5d122b2
8 changed files with 133 additions and 28 deletions

View file

@ -2,6 +2,7 @@
#include <stdexcept>
#include <stdlib.h>
#include <vector>
<<<<<<< HEAD
#include <chrono>
#include "heap.hpp"
@ -10,6 +11,13 @@
#define to_us std::chrono::duration_cast<std::chrono::microseconds>
using std::cout, std::endl, std::vector, std::hex, std::dec;
=======
#include <unordered_map>
#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<AddrRange *> &ranges, vector<Chunk *> &worklist)
{
Heap &heap = Heap::the();
@ -352,10 +375,42 @@ namespace GC
{
wliter++;
}
=======
void Heap::create_table()
{
Heap &heap = Heap::the();
unordered_map<uintptr_t, Chunk*> chunk_table;
for (auto chunk : heap.m_allocated_chunks) {
auto pair = std::make_pair(reinterpret_cast<uintptr_t>(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<uintptr_t>(chunk->m_start);
auto c_size = reinterpret_cast<uintptr_t>(chunk->m_size);
auto c_end = reinterpret_cast<uintptr_t*>(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