blob: 77e382ab5ff9f54f92683dfd1999e3127ac15781 [file] [log] [blame]
swissChili6d6525e2021-06-15 21:20:53 -07001#pragma once
2
swissChili9e57da42021-06-15 22:22:46 -07003#include "lisp.h"
4
5// I hate this
6extern value_t *gc_base;
swissChili80560312022-07-31 21:05:47 -07007extern struct gc_segment *gc_last_segment;
8
9struct gc_segment
10{
11 struct gc_segment *prev;
12
13 // The address of the first dword on the stack below the return
14 // pointer for this function (i.e. when the procedure is first
15 // `call`'d, this is esp+4)
16 void *seg_start;
17
18 // The address of the return pointer for the subsequently called
19 // function on the stack. When the lisp function is called,
20 // seg_end=esp.
21 void *seg_end;
22
23 // The number of arguments passed to the lisp function. These are
24 // stored in order on the stack, starting at seg_end+4, each
25 // taking 1 dword of memory.
26 int nargs;
27
28 // The value of ebp as it was when the function was first
29 // invoked. This denotes the caller's stack frame.
30 void *old_ebp;
31
32 // The number of lisp values which are retained by this C
33 // function.
34 int nretained;
35 value_t retained[];
36};
37
38#define gc_prepare_call(nargs) \
39 { \
40 void *__gc_segment_base; \
41 asm("movl %%esp, %0" : "=g"(__gc_segment_base)); \
42 gc_prepare_call_(__gc_segment_base, nargs); \
43 }
44void gc_push_segment(void *last_arg_addr, int nretained);
45void gc_pop_segment();
46void gc_prepare_call_(void *esp, int nargs);
47void gc_set_retained(int index, value_t retained);
swissChili9e57da42021-06-15 22:22:46 -070048
swissChilia890aed2022-07-30 17:13:07 -070049struct gc_stats
50{
51 // bytes currently used
52 unsigned long bytes_used;
53 // bytes ever freed by the GC
54 unsigned long bytes_freed;
55 // how many total allocations are currently alive
56 unsigned long total_allocs;
57 // how many times has the GC ever been run
58 unsigned long gc_runs;
59};
60
swissChili9e57da42021-06-15 22:22:46 -070061void gc_set_base_here();
62
swissChilie9fec8b2021-06-22 13:59:33 -070063value_t alloc_to_value(struct alloc *a);
swissChili6d6525e2021-06-15 21:20:53 -070064void _do_gc(unsigned int esp, unsigned int ebp);
swissChilie9fec8b2021-06-22 13:59:33 -070065void _mark(value_t value, unsigned int *marked);
swissChili6d6525e2021-06-15 21:20:53 -070066void _sweep();
swissChilib8fd4712021-06-23 15:32:04 -070067void free_all();
swissChilia890aed2022-07-30 17:13:07 -070068struct gc_stats gc_get_stats();