feat: add data-kind to TracingObject to enable quasi-polymorphism

This commit is contained in:
VegOwOtenks 2025-01-12 15:50:17 +01:00
parent 7120f59951
commit 3d6f7a2957
2 changed files with 49 additions and 16 deletions

View file

@ -28,8 +28,16 @@ int TracingHeap_Create(TracingHeap* self, allocator_t* allocator)
static void _TracingHeap_ForceDestroyObject(TracingHeap* self, TracingObject* object) static void _TracingHeap_ForceDestroyObject(TracingHeap* self, TracingObject* object)
{ {
size_t allocated_size = self->config.size_query(self->config.size_query_context, object->data); TracingHeapSizeQuery query_function = self->config.size_query[object->data_kind];
self->config.destructor(self->config.destructor_context, object->data); 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); Allocator_Free(self->allocator, object, allocated_size);
} }
@ -151,8 +159,10 @@ int TracingHeap_TraceNext(TracingHeap* self)
TracingObject* trace_object = _TracingHeap_PopColorList(self, TRACINGCOLOR_GREY); TracingObject* trace_object = _TracingHeap_PopColorList(self, TRACINGCOLOR_GREY);
int tracing_code = self->config.trace_data( TracingHeapTraceData trace_function = self->config.trace_data[trace_object->data_kind];
self->config.trace_context, void* trace_context = self->config.trace_context[trace_object->data_kind];
int tracing_code = trace_function(
trace_context,
trace_object->data, trace_object->data,
_TracingHeap_TraceReferenceCallback, _TracingHeap_TraceReferenceCallback,
self 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) 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) { if (destructor_code) {
return destructor_code; return destructor_code;
} }
@ -248,11 +262,14 @@ int TracingHeap_EndTrace(TracingHeap* self)
return EXIT_SUCCESS; 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) { if (self == NULL) {
return NULL; return NULL;
} }
if (data_kind > TRACINGHEAPDATAKIND_MAX) {
return NULL;
}
TracingObject* object = Allocator_Allocate(self->allocator, sizeof(TracingObject) + bytes); TracingObject* object = Allocator_Allocate(self->allocator, sizeof(TracingObject) + bytes);
if (object == NULL) { if (object == NULL) {
@ -260,6 +277,7 @@ void* TracingHeap_Allocate(TracingHeap* self, size_t bytes)
} }
object->color = self->reachable_color; object->color = self->reachable_color;
object->data_kind = data_kind;
TracingObject** reachable_list_start = _TracingHeap_ColorListStart(self, self->reachable_color); TracingObject** reachable_list_start = _TracingHeap_ColorListStart(self, self->reachable_color);
object->color_next = *reachable_list_start; object->color_next = *reachable_list_start;

View file

@ -5,6 +5,7 @@
#include <stdalign.h> #include <stdalign.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
enum TracingColor { enum TracingColor {
TRACINGCOLOR_BLACK, TRACINGCOLOR_BLACK,
@ -12,29 +13,43 @@ enum TracingColor {
TRACINGCOLOR_WHITE, TRACINGCOLOR_WHITE,
}; };
union TracingObjectDataAlignment {
double d;
void* p;
};
typedef struct TracingObject { typedef struct TracingObject {
// color linked list members
struct TracingObject* color_next; struct TracingObject* color_next;
struct TracingObject* color_prev; 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 // data member of the requested size
alignas(void*) char data[]; alignas(union TracingObjectDataAlignment) char data[];
} TracingObject; } TracingObject;
typedef int (*TracingHeapVisit) (void* context, void* reference); typedef int (*TracingHeapVisit) (void* context, void* reference);
typedef int (*TracingHeapTraceData) (void* context, void* data, TracingHeapVisit trace_callback, void* callback_context); typedef int (*TracingHeapTraceData) (void* context, void* data, TracingHeapVisit trace_callback, void* callback_context);
typedef int (*TracingHeapDataDestructor) (void* context, void* data); typedef int (*TracingHeapDataDestructor) (void* context, void* data);
typedef size_t (*TracingHeapSizeQuery) (void* context, void* data); typedef size_t (*TracingHeapSizeQuery) (void* context, void* data);
typedef struct TracingHeapConfig_s { typedef struct TracingHeapConfig_s {
TracingHeapTraceData trace_data; TracingHeapTraceData* trace_data;
void* trace_context; void** trace_context;
TracingHeapDataDestructor destructor; TracingHeapDataDestructor* destructor;
void* destructor_context; void** destructor_context;
TracingHeapSizeQuery size_query; TracingHeapSizeQuery* size_query;
void* size_query_context; void** size_query_context;
} TracingHeapConfig; } TracingHeapConfig;
typedef struct TracingHeap_s { typedef struct TracingHeap_s {
@ -52,7 +67,7 @@ typedef struct TracingHeap_s {
int TracingHeap_Create(TracingHeap* self, allocator_t* allocator); int TracingHeap_Create(TracingHeap* self, allocator_t* allocator);
void TracingHeap_Destroy(TracingHeap* self); 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); int TracingHeap_BeginTrace(TracingHeap* self);
bool TracingHeap_IsTraceFinished(TracingHeap* self); bool TracingHeap_IsTraceFinished(TracingHeap* self);