feat: add data-kind to TracingObject to enable quasi-polymorphism
This commit is contained in:
parent
7120f59951
commit
3d6f7a2957
2 changed files with 49 additions and 16 deletions
|
@ -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;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <stdalign.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue