From 87dc0fef2d714f2a6666e32d11dd4fe2d1ce4ecf Mon Sep 17 00:00:00 2001 From: Victor Olin Date: Tue, 21 Mar 2023 17:35:33 +0100 Subject: [PATCH] Comments --- src/GC/include/chunk.hpp | 7 ++++++ src/GC/include/event.hpp | 7 +++++- src/GC/include/heap.hpp | 41 +++++++++++++++++++++++++++++--- src/GC/include/profiler.hpp | 9 +++++++ src/GC/lib/event.cpp | 29 ++++++++++++++++++++++- src/GC/lib/profiler.cpp | 47 +++++++++++++++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 5 deletions(-) diff --git a/src/GC/include/chunk.hpp b/src/GC/include/chunk.hpp index 335388f..50e13fe 100644 --- a/src/GC/include/chunk.hpp +++ b/src/GC/include/chunk.hpp @@ -5,6 +5,13 @@ namespace GC { + /** + * The basic element of what can be stored on + * the heap. A chunk contains a start address + * on the actual heap, the size of memory that + * is allocated at that address and if the + * chunk is reachable (marked). + */ struct Chunk { bool m_marked {false}; diff --git a/src/GC/include/event.hpp b/src/GC/include/event.hpp index 272a69a..298ccab 100644 --- a/src/GC/include/event.hpp +++ b/src/GC/include/event.hpp @@ -9,7 +9,9 @@ namespace GC { - + /** + * Types of events that can occur on the heap. + */ enum GCEventType { HeapInit, @@ -24,6 +26,9 @@ namespace GC ProfilerDispose }; + /** + * Stores metadeta about an event on the heap. + */ class GCEvent { private: diff --git a/src/GC/include/heap.hpp b/src/GC/include/heap.hpp index 8c2b4a3..08b3e78 100644 --- a/src/GC/include/heap.hpp +++ b/src/GC/include/heap.hpp @@ -15,7 +15,10 @@ namespace GC { - + /** + * Flags for the collect overlead for conditional + * collection (mark/sweep/free/all). + */ enum CollectOption { MARK=0x1, SWEEP=0x2, @@ -24,9 +27,16 @@ namespace GC COLLECT_ALL=0x7 }; + /** + * The heap class to represent the heap for the + * garbage collection. The heap is a singleton + * instance and can be retrieved by Heap::the() + * inside the heap class. The heap is represented + * by a char array of size 65536 and can enable + * a profiler to track the actions on the heap. + */ class Heap { - private: Heap() : m_heap(static_cast(malloc(HEAP_SIZE))) {} @@ -35,6 +45,14 @@ namespace GC std::free((char *)m_heap); } + /** + * If m_instance is a nullptr (the singleton has not + * been initialized yet) initialize the singleton + * and return the pointer. Otherwise return the + * previously initialized pointer. + * + * @returns The pointer to the heap singleton. + */ static Heap *the() { if (m_instance) // if m_instance is not a nullptr @@ -43,6 +61,16 @@ namespace GC return m_instance; } + /** + * Advances an iterator and returns an element + * at position `n`. + * + * @param list The list to retrieve an element from. + * + * @param n The position to retrieve an element at. + * + * @returns The pointer to the chunk at position n in list. + */ static Chunk *get_at(std::vector &list, size_t n) { auto iter = list.begin(); @@ -52,6 +80,13 @@ namespace GC return *iter; } + /** + * Returns a bool whether the profiler is enabled + * or not. + * + * @returns True or false if the profiler is enabled + * or disabled respectively. + */ inline bool profiler_enabled() { auto heap = Heap::the(); return heap->m_profiler_enable; @@ -60,7 +95,6 @@ namespace GC char *const m_heap; size_t m_size {0}; inline static Heap *m_instance {nullptr}; - // size_t m_allocated_size {0}; uintptr_t *m_stack_top {nullptr}; bool m_profiler_enable {false}; @@ -85,6 +119,7 @@ namespace GC * that the address of the topmost stack frame is * saved as the limit for scanning the stack in collect. */ + static void init(); static void dispose(); static void *alloc(size_t size); diff --git a/src/GC/include/profiler.hpp b/src/GC/include/profiler.hpp index 48f8bbe..ccdf463 100644 --- a/src/GC/include/profiler.hpp +++ b/src/GC/include/profiler.hpp @@ -16,6 +16,15 @@ namespace GC { delete c; } + /** + * Returns the instance of the Profiler singleton. + * If m_instance is the nullptr and the profiler + * is not initialized yet, initialize it and return + * the pointer to it. Otherwise return the previously + * initialized pointer. + * + * @returns The pointer to the profiler singleton. + */ static Profiler *the() { if (m_instance) diff --git a/src/GC/lib/event.cpp b/src/GC/lib/event.cpp index ee40fa9..2815a77 100644 --- a/src/GC/lib/event.cpp +++ b/src/GC/lib/event.cpp @@ -7,27 +7,54 @@ namespace GC { - + /** + * @returns The type of the event + */ GCEventType GCEvent::get_type() { return m_type; } + /** + * @returns The time the event happened in + * the form of time_t. + */ std::time_t GCEvent::get_time_stamp() { return m_timestamp; } + /** + * If the event is related to a chunk, this + * function returns the chunk that it is + * related to. If the event is independent + * of a chunk, it returns the nullptr. + * + * @returns A chunk pointer or the nullptr. + */ const Chunk *GCEvent::get_chunk() { return m_chunk; } + /** + * If the event is an AllocStart event, this + * returns the size of the alloc() request. + * otherwise this returns 0. + * + * @returns A number representing the number + * of bytes requested to alloc() + * or 0 if the event is not an + * AllocStart event. + */ size_t GCEvent::get_size() { return m_size; } + /** + * @returns The string conversion of the event type. + */ const char *GCEvent::type_to_string() { switch (m_type) diff --git a/src/GC/lib/profiler.cpp b/src/GC/lib/profiler.cpp index 09d5d17..e346f8d 100644 --- a/src/GC/lib/profiler.cpp +++ b/src/GC/lib/profiler.cpp @@ -13,6 +13,11 @@ namespace GC { + /** + * Records an event independent of a chunk. + * + * @param type The type of event to record. + */ void Profiler::record(GCEventType type) { auto event = new GCEvent(type); @@ -20,6 +25,14 @@ namespace GC profiler->m_events.push_back(event); } + /** + * This overload is only used with an AllocStart + * event. + * + * @param type The type of event to record. + * + * @param size The size of requested to alloc(). + */ void Profiler::record(GCEventType type, size_t size) { auto event = new GCEvent(type, size); @@ -27,6 +40,14 @@ namespace GC profiler->m_events.push_back(event); } + /** + * Records an event related to a chunk. + * + * @param type The type of event to record. + * + * @param chunk The chunk the event is connected + * to. + */ void Profiler::record(GCEventType type, Chunk *chunk) { // Create a copy of chunk to store in the profiler @@ -39,6 +60,10 @@ namespace GC profiler->m_events.push_back(event); } + /** + * Prints the history of the recorded events + * to a log file in the /tests/logs folder. + */ void Profiler::dump_trace() { auto profiler = Profiler::the(); @@ -85,6 +110,12 @@ namespace GC fstr << "--------------------------------" << std::endl; } + /** + * Deletes the profiler singleton and all + * the events recorded after recording + * the ProfilerDispose event and dumping + * the history to a log file. + */ void Profiler::dispose() { Profiler::record(ProfilerDispose); @@ -93,6 +124,13 @@ namespace GC delete profiler; } + /** + * Creates a filestream for the future + * log file to print the history to in + * dump_trace(). + * + * @returns The output stream to the file. + */ std::ofstream Profiler::create_file_stream() { // get current time @@ -114,6 +152,15 @@ namespace GC return fstr; } + /** + * This function retrieves the current path of the + * executable to use for log files. + * + * @returns The path to the logs folder. + * + * @throws A runtime error if the call + * to readlink() fails. + */ std::string Profiler::get_log_folder() { char buffer[1024];