@@ -11,12 +11,22 @@
11 * of pointers coupled with their finalizers.
11 * of pointers coupled with their finalizers.
16+#define C_HEAP_GC_TRIGGER_SIZE_INITIAL 4096
17+#define C_HEAP_GC_TRIGGER_SIZE(heap_size) (2 * heap_size)
14typedef void CDataFinalizer(void *);
19typedef void CDataFinalizer(void *);
16typedef struct CHeapItem {
21typedef struct CHeapItem {
17 /// Payload.
22 /// Payload.
18 void * data;
23 void * data;
25+ /// Size of the item, in bytes.
26+ /// This does not have to be a precise size. It is used to assess
27+ /// whether the heap needs garbage collection.
20 /// Finalizer that will be called on the payload pointer.
30 /// Finalizer that will be called on the payload pointer.
21 /// Its job is to deallocate all associated resources,
31 /// Its job is to deallocate all associated resources,
22 /// including the memory pointed to by `data` (if any).
32 /// including the memory pointed to by `data` (if any).
@@ -36,6 +46,14 @@ typedef struct CHeapItem {
36typedef struct CHeap {
46typedef struct CHeap {
37 /// The first item in the heap. NULL if the heap is empty.
47 /// The first item in the heap. NULL if the heap is empty.
38 CHeapItem * first;
48 CHeapItem * first;
50+ /// Total size of the heap. (Sum of sizes of items.)
51+ /// This may not be a precise size since individual items'
52+ /// sizes may be just estimates.
55+ /// When heap reaches this size, GC will be triggered.
56+ size_t gc_trigger_size;
41/// Create a C heap.
59/// Create a C heap.
@@ -46,7 +64,8 @@ void c_heap_init(CHeap * c_heap);
46void c_heap_destroy(CHeap * c_heap);
64void c_heap_destroy(CHeap * c_heap);
48/// Insert the given item into the heap if it's not there yet.
66/// Insert the given item into the heap if it's not there yet.
67+/// The VM pointer is needed because this operation may trigger GC.
49−void c_heap_insert_if_needed(CHeap * c_heap, CHeapItem * item);
68+void c_heap_insert_if_needed(struct VM * vm, CHeap * c_heap, CHeapItem * item);
51/// Mark the given item as used.
70/// Mark the given item as used.
52void c_heap_mark_item(CHeapItem * item);
71void c_heap_mark_item(CHeapItem * item);
@@ -54,8 +73,10 @@ void c_heap_mark_item(CHeapItem * item);
54/// Sweep the C heap, finalizing and freeing unused blocks.
73/// Sweep the C heap, finalizing and freeing unused blocks.
55void c_heap_sweep(CHeap * c_heap);
74void c_heap_sweep(CHeap * c_heap);
57−/// Create a C heap item from its payload and finalizer.
76+/// Create a C heap item from its payload, size estimate, and finalizer.
77+/// The size does not have to be precise but it should roughly reflect
78+/// how big the item is for GC to work effectively.
58−CHeapItem * c_heap_create_item(void * data, CDataFinalizer * finalizer);
79+CHeapItem * c_heap_create_item(void * data, size_t size, CDataFinalizer * finalizer);
60/* *** Idris heap **
81/* *** Idris heap **
61 * Objects without finalizers. Cheney-collected.
82 * Objects without finalizers. Cheney-collected.