Repository navigation
Auto Free GC
CoreTrace auto-free has two layers:
- compile-time feature enable (
--ct-autofree) - optional conservative runtime scanning (
CT_AUTOFREE_SCAN*)
Implementation: src/runtime/ct_runtime_autofree_scan.cpp, split out of the allocation runtime
so the scan is a translation unit of its own. The allocation table it walks lives in
ct_runtime_alloc.cpp and is mutex-guarded, so the periodic scan thread and the program's own
allocations do not race.
Auto-free is disabled by default in compile-time runtime config. Enable it when building instrumented binaries:
./build/cc --instrument --ct-alloc --ct-autofree main.c -o appTwo things happen at compile time:
- An allocation whose result the program provably never uses is rewritten to the
*_unreachableentry point (__ct_malloc_unreachable,__ct_new_unreachable, …), which lets the runtime release it at once. - An allocation proven unreachable at the end of a frame gets an
__ct_autofree*call at function exit (__ct_autofree,__ct_autofree_delete,__ct_autofree_delete_array,__ct_autofree_munmap,__ct_autofree_sbrk).
An address that escapes — stored into a scalar slot that outlives the frame, converted through
ptrtoint/inttoptr, selected into a value that leaves the function — is not auto-freed.
The fixtures under test/ name each of those shapes (ct_autofree_scalar_slot_escape.c,
ct_autofree_ptrtoint_escape.c, ct_autofree_select_escape.c, …).
Tracked allocation kinds include malloc, new, new[], mmap, sbrk and, on Apple targets,
Objective-C objects — see Objective-C Support.
Without scan variables, auto-free only uses compile-time reachability decisions. To enable conservative root scanning:
CT_AUTOFREE_SCAN=1 ./appTo enable periodic GC thread:
CT_AUTOFREE_SCAN=1 CT_AUTOFREE_SCAN_START=1 ./app| Variable | Default | Meaning |
|---|---|---|
CT_AUTOFREE_SCAN |
0 |
Enable conservative scan system |
CT_AUTOFREE_SCAN_START |
0 |
Start background periodic scan thread |
CT_AUTOFREE_SCAN_STACK |
1 |
Scan stack roots |
CT_AUTOFREE_SCAN_REGS |
1 |
Scan register roots |
CT_AUTOFREE_SCAN_GLOBALS |
1 |
Scan globals (__DATA/image data) |
CT_AUTOFREE_SCAN_INTERIOR |
1 |
Count interior pointers as roots |
CT_AUTOFREE_SCAN_PTR |
1 |
Run per-pointer check before auto-free |
CT_DEBUG_AUTOFREE_SCAN |
0 |
Debug level (0/1/2) |
Period precedence:
CT_AUTOFREE_SCAN_PERIOD_NSCT_AUTOFREE_SCAN_PERIOD_USCT_AUTOFREE_SCAN_PERIOD_MS- fallback
1000mswhenSTART=1and no period is set
Budget precedence:
CT_AUTOFREE_SCAN_BUDGET_NSCT_AUTOFREE_SCAN_BUDGET_US-
CT_AUTOFREE_SCAN_BUDGET_MS(default5.0)
Compatibility interval:
-
CT_AUTOFREE_SCAN_INTERVAL_MSsets a minimum interval for per-pointer scans.
CT_AUTOFREE_SCAN=1 \
CT_AUTOFREE_SCAN_START=1 \
CT_AUTOFREE_SCAN_PTR=1 \
CT_AUTOFREE_SCAN_GLOBALS=1 \
CT_AUTOFREE_SCAN_PERIOD_MS=1000 \
CT_AUTOFREE_SCAN_BUDGET_MS=20 \
./appCT_AUTOFREE_SCAN=1 \
CT_AUTOFREE_SCAN_START=1 \
CT_AUTOFREE_SCAN_GLOBALS=0 \
CT_AUTOFREE_SCAN_PTR=0 \
CT_AUTOFREE_SCAN_PERIOD_MS=5000 \
CT_AUTOFREE_SCAN_BUDGET_MS=5 \
./app-
CT_AUTOFREE_SCAN_BUDGET_MSdefaults to 5.0; the period has no default untilCT_AUTOFREE_SCAN_START=1, which sets it to 1000 ms when no period was given. - Within each pair, precedence is
NS>US>MS: setting a nanosecond value ignores the millisecond one.
- Conservative roots can keep dead allocations alive (false negatives). That is the safe direction: the scan never frees something it merely failed to see a root for.
- If the budget is exceeded, the scan frees nothing in that pass, rather than freeing the part it managed to prove.
- Pointer scanning and global scanning can be expensive on large processes;
CT_AUTOFREE_SCAN_PTR=0andCT_AUTOFREE_SCAN_GLOBALS=0are the two levers. - Stale values left on the stack, in registers or in globals can look like live pointers. This is conservative collection, not precise reachability.
bash test/run_autofree_tests.shThe auto-free fixtures cover each escape shape and each allocation kind; see Testing and Validation.
Start
Architecture
Instrumentation
Platforms
Developer