From 3d6f7a29571a78a169852b649227b26caa01de4e Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Sun, 12 Jan 2025 15:50:17 +0100 Subject: [PATCH] feat: add data-kind to TracingObject to enable quasi-polymorphism --- src/TracingHeap/TracingHeap.c | 32 +++++++++++++++++++++++++------- src/TracingHeap/TracingHeap.h | 33 ++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/TracingHeap/TracingHeap.c b/src/TracingHeap/TracingHeap.c index 2be2aa1..ef48bcc 100644 --- a/src/TracingHeap/TracingHeap.c +++ b/src/TracingHeap/TracingHeap.c @@ -28,8 +28,16 @@ int TracingHeap_Create(TracingHeap* self, allocator_t* allocator) static void _TracingHeap_ForceDestroyObject(TracingHeap* self, TracingObject* object) { - size_t allocated_size = self->config.size_query(self->config.size_query_context, object->data); - self->config.destructor(self->config.destructor_context, object->data); + TracingHeapSizeQuery query_function = self->config.size_query[object->data_kind]; + void* query_function_context = self->config.size_query_context[object->data_kind]; + size_t allocated_size = query_function(query_function_context, object->data); + + TracingHeapDataDestructor destructor_function = self->config.destructor[object->data_kind]; + void* destructor_function_context = self->config.destructor_context[object->data_kind]; + + int destructor_code = destructor_function(destructor_function_context, object->data); + (void) destructor_code; + Allocator_Free(self->allocator, object, allocated_size); } @@ -151,8 +159,10 @@ int TracingHeap_TraceNext(TracingHeap* self) TracingObject* trace_object = _TracingHeap_PopColorList(self, TRACINGCOLOR_GREY); - int tracing_code = self->config.trace_data( - self->config.trace_context, + TracingHeapTraceData trace_function = self->config.trace_data[trace_object->data_kind]; + void* trace_context = self->config.trace_context[trace_object->data_kind]; + int tracing_code = trace_function( + trace_context, trace_object->data, _TracingHeap_TraceReferenceCallback, self @@ -181,9 +191,13 @@ size_t TracingHeap_TraceNextN(TracingHeap* self, size_t n, int* error_code) static int _TracingHeap_DestroyObject(TracingHeap* self, TracingObject* unreachable_object) { - size_t allocated_size = self->config.size_query(self->config.size_query_context, unreachable_object->data); + TracingHeapSizeQuery query_function = self->config.size_query[unreachable_object->data_kind]; + void* query_function_context = self->config.size_query_context[unreachable_object->data_kind]; + size_t allocated_size = query_function(query_function_context, unreachable_object->data); - int destructor_code = self->config.destructor(self->config.destructor_context, unreachable_object->data); + TracingHeapDataDestructor destructor_function = self->config.destructor[unreachable_object->data_kind]; + void* destructor_function_context = self->config.destructor_context[unreachable_object->data_kind]; + int destructor_code = destructor_function(destructor_function_context, unreachable_object->data); if (destructor_code) { return destructor_code; } @@ -248,11 +262,14 @@ int TracingHeap_EndTrace(TracingHeap* self) return EXIT_SUCCESS; } -void* TracingHeap_Allocate(TracingHeap* self, size_t bytes) +void* TracingHeap_Allocate(TracingHeap* self, size_t bytes, uint64_t data_kind) { if (self == NULL) { return NULL; } + if (data_kind > TRACINGHEAPDATAKIND_MAX) { + return NULL; + } TracingObject* object = Allocator_Allocate(self->allocator, sizeof(TracingObject) + bytes); if (object == NULL) { @@ -260,6 +277,7 @@ void* TracingHeap_Allocate(TracingHeap* self, size_t bytes) } object->color = self->reachable_color; + object->data_kind = data_kind; TracingObject** reachable_list_start = _TracingHeap_ColorListStart(self, self->reachable_color); object->color_next = *reachable_list_start; diff --git a/src/TracingHeap/TracingHeap.h b/src/TracingHeap/TracingHeap.h index 77d19ec..ee9d34a 100644 --- a/src/TracingHeap/TracingHeap.h +++ b/src/TracingHeap/TracingHeap.h @@ -5,6 +5,7 @@ #include #include +#include enum TracingColor { TRACINGCOLOR_BLACK, @@ -12,29 +13,43 @@ enum TracingColor { TRACINGCOLOR_WHITE, }; +union TracingObjectDataAlignment { + double d; + void* p; +}; + typedef struct TracingObject { + // color linked list members struct TracingObject* color_next; struct TracingObject* color_prev; - enum TracingColor color; + + // Selector for the callback function + // TODO: Think about something for 16-bit systems +#define TRACINGHEAPDATAKIND_MAX (((uint64_t) 1 << 62) - 1) + uint64_t data_kind: 62; + + // color of this object + enum TracingColor color: 2; // data member of the requested size - alignas(void*) char data[]; + alignas(union TracingObjectDataAlignment) char data[]; } TracingObject; + typedef int (*TracingHeapVisit) (void* context, void* reference); typedef int (*TracingHeapTraceData) (void* context, void* data, TracingHeapVisit trace_callback, void* callback_context); typedef int (*TracingHeapDataDestructor) (void* context, void* data); typedef size_t (*TracingHeapSizeQuery) (void* context, void* data); typedef struct TracingHeapConfig_s { - TracingHeapTraceData trace_data; - void* trace_context; + TracingHeapTraceData* trace_data; + void** trace_context; - TracingHeapDataDestructor destructor; - void* destructor_context; + TracingHeapDataDestructor* destructor; + void** destructor_context; - TracingHeapSizeQuery size_query; - void* size_query_context; + TracingHeapSizeQuery* size_query; + void** size_query_context; } TracingHeapConfig; typedef struct TracingHeap_s { @@ -52,7 +67,7 @@ typedef struct TracingHeap_s { int TracingHeap_Create(TracingHeap* self, allocator_t* allocator); void TracingHeap_Destroy(TracingHeap* self); -void* TracingHeap_Allocate(TracingHeap* self, size_t bytes); +void* TracingHeap_Allocate(TracingHeap* self, size_t bytes, uint64_t object_kind); int TracingHeap_BeginTrace(TracingHeap* self); bool TracingHeap_IsTraceFinished(TracingHeap* self);