1 | module builtin |
2 | |
3 | #flag -DGC_THREADS=1 |
4 | |
5 | $if dynamic_boehm ? { |
6 | $if windows { |
7 | $if tinyc { |
8 | #flag -I @VEXEROOT/thirdparty/libgc/include |
9 | #flag -L @VEXEROOT/thirdparty/tcc/lib |
10 | #flag -lgc |
11 | } $else $if msvc { |
12 | #flag -DGC_BUILTIN_ATOMIC=1 |
13 | #flag -I @VEXEROOT/thirdparty/libgc/include |
14 | } $else { |
15 | #flag -DGC_WIN32_THREADS=1 |
16 | #flag -DGC_BUILTIN_ATOMIC=1 |
17 | #flag -I @VEXEROOT/thirdparty/libgc |
18 | #flag @VEXEROOT/thirdparty/libgc/gc.o |
19 | } |
20 | } $else { |
21 | $if $pkgconfig('bdw-gc') { |
22 | #pkgconfig bdw-gc |
23 | } $else { |
24 | $if openbsd || freebsd { |
25 | #flag -I/usr/local/include |
26 | #flag -L/usr/local/lib |
27 | } |
28 | $if freebsd { |
29 | #flag -lgc-threaded |
30 | } $else { |
31 | #flag -lgc |
32 | } |
33 | } |
34 | } |
35 | } $else { |
36 | $if macos || linux { |
37 | #flag -DGC_BUILTIN_ATOMIC=1 |
38 | #flag -I @VEXEROOT/thirdparty/libgc/include |
39 | $if (prod && !tinyc && !debug) || !(amd64 || arm64 || i386 || arm32) { |
40 | // TODO: replace the architecture check with a `!$exists("@VEXEROOT/thirdparty/tcc/lib/libgc.a")` comptime call |
41 | #flag @VEXEROOT/thirdparty/libgc/gc.o |
42 | } $else { |
43 | #flag @VEXEROOT/thirdparty/tcc/lib/libgc.a |
44 | } |
45 | $if macos { |
46 | #flag -DMPROTECT_VDB=1 |
47 | } |
48 | #flag -ldl |
49 | #flag -lpthread |
50 | } $else $if freebsd { |
51 | // Tested on FreeBSD 13.0-RELEASE-p3, with clang, gcc and tcc: |
52 | #flag -DGC_BUILTIN_ATOMIC=1 |
53 | #flag -DBUS_PAGE_FAULT=T_PAGEFLT |
54 | $if !tinyc { |
55 | #flag -I @VEXEROOT/thirdparty/libgc/include |
56 | #flag @VEXEROOT/thirdparty/libgc/gc.o |
57 | } |
58 | $if tinyc { |
59 | #flag -I/usr/local/include |
60 | #flag $first_existing("/usr/local/lib/libgc-threaded.a", "/usr/lib/libgc-threaded.a") |
61 | #flag -lgc-threaded |
62 | } |
63 | #flag -lpthread |
64 | } $else $if openbsd { |
65 | #flag -DGC_BUILTIN_ATOMIC=1 |
66 | #flag -I/usr/local/include |
67 | #flag $first_existing("/usr/local/lib/libgc.a", "/usr/lib/libgc.a") |
68 | #flag -lpthread |
69 | } $else $if windows { |
70 | #flag -DGC_NOT_DLL=1 |
71 | #flag -DGC_WIN32_THREADS=1 |
72 | $if tinyc { |
73 | #flag -DGC_BUILTIN_ATOMIC=1 |
74 | #flag -I @VEXEROOT/thirdparty/libgc/include |
75 | #flag @VEXEROOT/thirdparty/tcc/lib/libgc.a |
76 | #flag -luser32 |
77 | } $else $if msvc { |
78 | // Build libatomic_ops |
79 | #flag @VEXEROOT/thirdparty/libatomic_ops/atomic_ops.o |
80 | #flag -I @VEXEROOT/thirdparty/libatomic_ops |
81 | |
82 | #flag -I @VEXEROOT/thirdparty/libgc/include |
83 | #flag @VEXEROOT/thirdparty/libgc/gc.o |
84 | } $else { |
85 | #flag -DGC_BUILTIN_ATOMIC=1 |
86 | #flag -I @VEXEROOT/thirdparty/libgc/include |
87 | #flag @VEXEROOT/thirdparty/libgc/gc.o |
88 | } |
89 | } $else $if $pkgconfig('bdw-gc') { |
90 | #flag -DGC_BUILTIN_ATOMIC=1 |
91 | #pkgconfig bdw-gc |
92 | } $else { |
93 | #flag -DGC_BUILTIN_ATOMIC=1 |
94 | #flag -lgc |
95 | } |
96 | } |
97 | |
98 | $if gcboehm_leak ? { |
99 | #flag -DGC_DEBUG=1 |
100 | } |
101 | |
102 | #include <gc.h> |
103 | |
104 | // replacements for `malloc()/calloc()`, `realloc()` and `free()` |
105 | // for use with Boehm-GC |
106 | // Do not use them manually. They are automatically chosen when |
107 | // compiled with `-gc boehm` or `-gc boehm_leak`. |
108 | fn C.GC_MALLOC(n usize) voidptr |
109 | |
110 | fn C.GC_MALLOC_ATOMIC(n usize) voidptr |
111 | |
112 | fn C.GC_MALLOC_UNCOLLECTABLE(n usize) voidptr |
113 | |
114 | fn C.GC_REALLOC(ptr voidptr, n usize) voidptr |
115 | |
116 | fn C.GC_FREE(ptr voidptr) |
117 | |
118 | // explicitly perform garbage collection now! Garbage collections |
119 | // are done automatically when needed, so this function is hardly needed |
120 | fn C.GC_gcollect() |
121 | |
122 | // functions to temporarily suspend/resume garbage collection |
123 | fn C.GC_disable() |
124 | |
125 | fn C.GC_enable() |
126 | |
127 | // returns non-zero if GC is disabled |
128 | fn C.GC_is_disabled() int |
129 | |
130 | // protect memory block from being freed before this call |
131 | fn C.GC_reachable_here(voidptr) |
132 | |
133 | // for leak detection it is advisable to do explicit garbage collections |
134 | pub fn gc_check_leaks() { |
135 | $if gcboehm_leak ? { |
136 | C.GC_gcollect() |
137 | } |
138 | } |
139 | |
140 | fn C.GC_get_heap_usage_safe(pheap_size &usize, pfree_bytes &usize, punmapped_bytes &usize, pbytes_since_gc &usize, ptotal_bytes &usize) |
141 | fn C.GC_get_memory_use() usize |