@@ -11,12 +11,22 @@
1111 * of pointers coupled with their finalizers.
1212 */
1313
14+struct VM;
15+
16+#define C_HEAP_GC_TRIGGER_SIZE_INITIAL 4096
17+#define C_HEAP_GC_TRIGGER_SIZE(heap_size) (2 * heap_size)
18+
1419typedef void CDataFinalizer(void *);
1520
1621typedef struct CHeapItem {
1722 /// Payload.
1823 void * data;
1924
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.
28+ size_t size;
29+
2030 /// Finalizer that will be called on the payload pointer.
2131 /// Its job is to deallocate all associated resources,
2232 /// including the memory pointed to by `data` (if any).
@@ -36,6 +46,14 @@ typedef struct CHeapItem {
3646typedef struct CHeap {
3747 /// The first item in the heap. NULL if the heap is empty.
3848 CHeapItem * first;
49+
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.
53+ size_t size;
54+
55+ /// When heap reaches this size, GC will be triggered.
56+ size_t gc_trigger_size;
3957} CHeap;
4058
4159/// Create a C heap.
@@ -46,7 +64,8 @@ void c_heap_init(CHeap * c_heap);
4664void c_heap_destroy(CHeap * c_heap);
4765
4866/// Insert the given item into the heap if it's not there yet.
49−void c_heap_insert_if_needed(CHeap * c_heap, CHeapItem * item);
67+/// The VM pointer is needed because this operation may trigger GC.
68+void c_heap_insert_if_needed(struct VM * vm, CHeap * c_heap, CHeapItem * item);
5069
5170/// Mark the given item as used.
5271void c_heap_mark_item(CHeapItem * item);
@@ -54,8 +73,10 @@ void c_heap_mark_item(CHeapItem * item);
5473/// Sweep the C heap, finalizing and freeing unused blocks.
5574void c_heap_sweep(CHeap * c_heap);
5675
57−/// Create a C heap item from its payload and finalizer.
58−CHeapItem * c_heap_create_item(void * data, CDataFinalizer * 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.
79+CHeapItem * c_heap_create_item(void * data, size_t size, CDataFinalizer * finalizer);
5980
6081/* *** Idris heap **
6182 * Objects without finalizers. Cheney-collected.