gc: make generational mode of Boehm-GC available (#9514)
parent
a3455b8433
commit
97f43d6a97
|
@ -71,10 +71,16 @@ see also `v help build`.
|
|||
more performant without autofree.
|
||||
|
||||
-gc <mode>
|
||||
Use and link an optional garbage collector.
|
||||
Only `-gc boehm` and `-gc boehm_leak` are supported currently.
|
||||
You need to install a `libgc-dev` package first, or install it manually
|
||||
from source:
|
||||
Use and link an optional garbage collector. Only tThe Boehm–Demers–Weiser
|
||||
garbage collector is supported currently with the following sub-options:
|
||||
|
||||
`-gc boehm` ........ selects the default mode for the architecture
|
||||
`-gc boehm_full` ... full garbage collection mode
|
||||
`-gc boehm_incr` ... incremental/generational garbage collection mode
|
||||
`-gc boehm_leak` ... leak detection mode
|
||||
|
||||
You need to install a `libgc-dev` package first, or install it manually from:
|
||||
|
||||
https://github.com/ivmai/bdwgc
|
||||
|
||||
Note, `-gc boehm` is complementary to -autofree. The Boehm garbage
|
||||
|
|
|
@ -423,7 +423,7 @@ pub fn (mut g Gen) init() {
|
|||
}
|
||||
g.comptime_defines.writeln('')
|
||||
}
|
||||
if g.pref.gc_mode in [.boehm, .boehm_leak] {
|
||||
if g.pref.gc_mode in [.boehm_full, .boehm_incr, .boehm, .boehm_leak] {
|
||||
g.comptime_defines.writeln('#define _VGCBOEHM (1)')
|
||||
}
|
||||
if g.pref.is_debug || 'debug' in g.pref.compile_defines {
|
||||
|
|
|
@ -67,12 +67,15 @@ fn (mut g Gen) gen_c_main_function_header() {
|
|||
|
||||
fn (mut g Gen) gen_c_main_header() {
|
||||
g.gen_c_main_function_header()
|
||||
if g.pref.gc_mode in [.boehm, .boehm_leak] {
|
||||
if g.pref.gc_mode in [.boehm_full, .boehm_incr, .boehm, .boehm_leak] {
|
||||
g.writeln('#if defined(_VGCBOEHM)')
|
||||
if g.pref.gc_mode == .boehm_leak {
|
||||
g.writeln('\tGC_set_find_leak(1);')
|
||||
}
|
||||
g.writeln('\tGC_INIT();')
|
||||
if g.pref.gc_mode == .boehm_incr {
|
||||
g.writeln('\tGC_enable_incremental();')
|
||||
}
|
||||
g.writeln('#endif')
|
||||
}
|
||||
g.writeln('\t_vinit(___argc, (voidptr)___argv);')
|
||||
|
@ -158,12 +161,15 @@ pub fn (mut g Gen) gen_c_main_for_tests() {
|
|||
main_fn_start_pos := g.out.len
|
||||
g.writeln('')
|
||||
g.gen_c_main_function_header()
|
||||
if g.pref.gc_mode in [.boehm, .boehm_leak] {
|
||||
if g.pref.gc_mode in [.boehm_full, .boehm_incr, .boehm, .boehm_leak] {
|
||||
g.writeln('#if defined(_VGCBOEHM)')
|
||||
if g.pref.gc_mode == .boehm_leak {
|
||||
g.writeln('\tGC_set_find_leak(1);')
|
||||
}
|
||||
g.writeln('\tGC_INIT();')
|
||||
if g.pref.gc_mode == .boehm_incr {
|
||||
g.writeln('\tGC_enable_incremental();')
|
||||
}
|
||||
g.writeln('#endif')
|
||||
}
|
||||
g.writeln('\t_vinit(___argc, (voidptr)___argv);')
|
||||
|
|
|
@ -19,8 +19,10 @@ pub enum BuildMode {
|
|||
|
||||
pub enum GarbageCollectionMode {
|
||||
no_gc
|
||||
boehm
|
||||
boehm_leak
|
||||
boehm_full // full garbage collection mode
|
||||
boehm_incr // incremental garbage colletion mode
|
||||
boehm // default Boehm-GC mode for architecture
|
||||
boehm_leak // leak detection mode (makes `gc_check_leaks()` work)
|
||||
}
|
||||
|
||||
pub enum OutputMode {
|
||||
|
@ -159,7 +161,7 @@ pub mut:
|
|||
build_options []string // list of options, that should be passed down to `build-module`, if needed for -usecache
|
||||
cache_manager vcache.CacheManager
|
||||
is_help bool // -h, -help or --help was passed
|
||||
gc_mode GarbageCollectionMode = .no_gc // .no_gc, .boehm, .boehm_leak
|
||||
gc_mode GarbageCollectionMode = .no_gc // .no_gc, .boehm, .boehm_leak, ...
|
||||
// checker settings:
|
||||
checker_match_exhaustive_cutoff_limit int = 10
|
||||
}
|
||||
|
@ -227,6 +229,16 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences
|
|||
'' {
|
||||
res.gc_mode = .no_gc
|
||||
}
|
||||
'boehm_full' {
|
||||
res.gc_mode = .boehm_full
|
||||
parse_define(mut res, 'gcboehm')
|
||||
parse_define(mut res, 'gcboehm_full')
|
||||
}
|
||||
'boehm_incr' {
|
||||
res.gc_mode = .boehm_incr
|
||||
parse_define(mut res, 'gcboehm')
|
||||
parse_define(mut res, 'gcboehm_incr')
|
||||
}
|
||||
'boehm' {
|
||||
res.gc_mode = .boehm
|
||||
parse_define(mut res, 'gcboehm')
|
||||
|
@ -237,7 +249,7 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences
|
|||
parse_define(mut res, 'gcboehm_leak')
|
||||
}
|
||||
else {
|
||||
eprintln('unknown garbage collection mode, only `-gc boehm` and `-gc boehm_leak` are supported')
|
||||
eprintln('unknown garbage collection mode, only `-gc boehm`, `-gc boehm_incr`, `-gc boehm_full` and `-gc boehm_leak` are supported')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/gnuplot -persist
|
||||
set title "Boehm-GC: Full vs. Incremental/Generational Mode"
|
||||
set xlabel "Interval #"
|
||||
set ylabel "Pause Time [ms]"
|
||||
set terminal pdfcairo transparent enhanced fontscale 0.5 size 5.00in, 3.00in
|
||||
set output "GC_bench.pdf"
|
||||
plot "boehm_full.txt" title "full GC" w i, "boehm_incr.txt" title "incr/generational GC" w i
|
||||
set output
|
||||
# EOF
|
|
@ -0,0 +1,46 @@
|
|||
import time
|
||||
import rand
|
||||
import math
|
||||
|
||||
struct MemObj {
|
||||
mut:
|
||||
nxt []&MemObj
|
||||
}
|
||||
|
||||
const (
|
||||
log2n = 10
|
||||
n = 1 << log2n
|
||||
n4 = f64(u64(1) << (4 * log2n))
|
||||
)
|
||||
|
||||
fn waste_mem() {
|
||||
mut objs := MemObj{
|
||||
nxt: []&MemObj{len: n}
|
||||
}
|
||||
for {
|
||||
sz := rand.int_in_range(10, 100000)
|
||||
mut new_obj := &MemObj{
|
||||
nxt: []&MemObj{len: sz}
|
||||
}
|
||||
sz2 := rand.int_in_range(10, 100000)
|
||||
new_obj2 := &MemObj{
|
||||
nxt: []&MemObj{len: sz2}
|
||||
}
|
||||
idx2 := rand.int_in_range(0, sz / 2)
|
||||
new_obj.nxt[idx2] = new_obj2
|
||||
// non-equally distributed random index
|
||||
idx := int(math.sqrt(math.sqrt(rand.f64n(n4))))
|
||||
objs.nxt[idx] = new_obj
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
go waste_mem()
|
||||
mut last := time.sys_mono_now()
|
||||
for _ in 0 .. 10_000_000 {
|
||||
now := time.sys_mono_now()
|
||||
interval := now - last
|
||||
println(f64(interval) / f64(time.millisecond))
|
||||
last = now
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
.PHONY: all
|
||||
|
||||
all: GC_bench.pdf
|
||||
|
||||
GC_bench.pdf: boehm_full.txt boehm_incr.txt
|
||||
gnuplot GC_bench.plt
|
||||
@echo "$@ created"
|
||||
|
||||
boehm_full.txt: GC_bench_full
|
||||
sync
|
||||
sleep 1
|
||||
./$< > $@
|
||||
|
||||
boehm_incr.txt: GC_bench_incr
|
||||
sync
|
||||
sleep 1
|
||||
./$< > $@
|
||||
|
||||
GC_bench_full: GC_bench.v
|
||||
v -prod -gc boehm_full -o $@ $<
|
||||
|
||||
GC_bench_incr: GC_bench.v
|
||||
v -prod -gc boehm_incr -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f boehm_full.txt boehm_incr.txt GC_bench.pdf GC_bench_full GC_bench_incr
|
Loading…
Reference in New Issue