From 4ed9780b803565e47e401f24bc1cd9732aaf645c Mon Sep 17 00:00:00 2001 From: spaceface Date: Wed, 8 Jun 2022 23:44:29 +0200 Subject: [PATCH] all: enable `-gc boehm` by default (#14577) --- .github/workflows/ci_cross.yml | 4 ++-- .github/workflows/ci_sanitized.yml | 2 +- .github/workflows/containers_ci.yml | 4 ++-- .github/workflows/vab_ci.yml | 1 + .github/workflows/vinix-kernel.yml | 2 ++ GNUmakefile | 5 ++++- vlib/builtin/builtin_d_gcboehm.c.v | 16 ++++++++-------- vlib/v/builder/cc.v | 7 +++++++ vlib/v/cflag/cflags.v | 6 +++++- vlib/v/pref/default.v | 12 ++++++++++++ vlib/v/pref/pref.v | 17 +++++++++-------- vlib/v/tests/valgrind/valgrind_test.v | 2 +- vlib/v/vcache/vcache.v | 9 ++++++++- 13 files changed, 62 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci_cross.yml b/.github/workflows/ci_cross.yml index 6e9a36c94c..59af9b2a8e 100644 --- a/.github/workflows/ci_cross.yml +++ b/.github/workflows/ci_cross.yml @@ -45,7 +45,7 @@ jobs: - name: Compile to raw Android (non-graphic) compatible run: | # Test that V can compile non-graphic app to Android compatible code *without* using the -apk flag - ./v -os android examples/toml.v + ./v -os android -gc none examples/toml.v linux-cross: runs-on: ubuntu-20.04 @@ -98,7 +98,7 @@ jobs: - name: toml.v can be compiled to raw Android C run: | # Test that V can compile non-graphic app to Android compatible code *without* using the -apk flag - ./v -os android examples/toml.v + ./v -os android -gc none examples/toml.v windows-cross: diff --git a/.github/workflows/ci_sanitized.yml b/.github/workflows/ci_sanitized.yml index 7b616c53e4..4784ae24a0 100644 --- a/.github/workflows/ci_sanitized.yml +++ b/.github/workflows/ci_sanitized.yml @@ -228,7 +228,7 @@ jobs: if: github.event_name != 'push' || github.event.ref == 'refs/heads/master' || github.event.repository.full_name != 'vlang/v' timeout-minutes: 180 env: - VFLAGS: -cc clang + VFLAGS: -cc clang -gc none VJOBS: 1 VTEST_SHOW_START: 1 steps: diff --git a/.github/workflows/containers_ci.yml b/.github/workflows/containers_ci.yml index b132e03ac9..5522d93f58 100644 --- a/.github/workflows/containers_ci.yml +++ b/.github/workflows/containers_ci.yml @@ -17,7 +17,7 @@ jobs: alpine-docker-musl-gcc: runs-on: ubuntu-20.04 if: github.event_name != 'push' || github.event.ref == 'refs/heads/master' || github.event.repository.full_name != 'vlang/v' - timeout-minutes: 121 + timeout-minutes: 181 container: # Alpine docker pre-built container image: thevlang/vlang:alpine-build @@ -58,7 +58,7 @@ jobs: env: V_CI_MUSL: 1 V_CI_UBUNTU_MUSL: 1 - VFLAGS: -cc musl-gcc + VFLAGS: -cc musl-gcc -gc none volumes: - ${{github.workspace}}:/opt/vlang diff --git a/.github/workflows/vab_ci.yml b/.github/workflows/vab_ci.yml index 190ff8aec5..48df212d24 100644 --- a/.github/workflows/vab_ci.yml +++ b/.github/workflows/vab_ci.yml @@ -14,6 +14,7 @@ jobs: if: github.event_name != 'push' || github.event.ref == 'refs/heads/master' || github.event.repository.full_name != 'vlang/v' timeout-minutes: 121 env: + VFLAGS: -gc none VAB_FLAGS: --api 30 --build-tools 29.0.0 -v 3 steps: - uses: actions/setup-java@v2 diff --git a/.github/workflows/vinix-kernel.yml b/.github/workflows/vinix-kernel.yml index e328d57be0..1b6f86d93a 100644 --- a/.github/workflows/vinix-kernel.yml +++ b/.github/workflows/vinix-kernel.yml @@ -14,6 +14,8 @@ jobs: vinix-build: runs-on: ubuntu-20.04 if: github.event_name != 'push' || github.event.ref == 'refs/heads/master' || github.event.repository.full_name != 'vlang/v' + env: + VFLAGS: -gc none steps: - uses: actions/checkout@v2 diff --git a/GNUmakefile b/GNUmakefile index aab552aa19..9b97c64e4c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -28,6 +28,9 @@ endif ifeq ($(_SYS),Linux) LINUX := 1 TCCOS := linux +ifneq ($(shell ldd /bin/ls | grep musl),) +TCCOS := linuxmusl +endif endif ifeq ($(_SYS),Darwin) @@ -113,7 +116,7 @@ endif check_for_working_tcc: @$(TMPTCC)/tcc.exe --version > /dev/null 2> /dev/null || echo "The executable '$(TMPTCC)/tcc.exe' does not work." - + fresh_vc: rm -rf $(VC) $(GITFASTCLONE) $(VCREPO) $(VC) diff --git a/vlib/builtin/builtin_d_gcboehm.c.v b/vlib/builtin/builtin_d_gcboehm.c.v index cab113019f..328565333b 100644 --- a/vlib/builtin/builtin_d_gcboehm.c.v +++ b/vlib/builtin/builtin_d_gcboehm.c.v @@ -3,16 +3,16 @@ module builtin $if dynamic_boehm ? { $if windows { $if tinyc { - #flag -I@VEXEROOT/thirdparty/libgc/include - #flag -L@VEXEROOT/thirdparty/tcc/lib + #flag -I @VEXEROOT/thirdparty/libgc/include + #flag -L @VEXEROOT/thirdparty/tcc/lib #flag -lgc } $else $if msvc { #flag -DGC_BUILTIN_ATOMIC=1 - #flag -I@VEXEROOT/thirdparty/libgc/include + #flag -I @VEXEROOT/thirdparty/libgc/include } $else { #flag -DGC_WIN32_THREADS=1 #flag -DGC_BUILTIN_ATOMIC=1 - #flag -I@VEXEROOT/thirdparty/libgc + #flag -I @VEXEROOT/thirdparty/libgc #flag @VEXEROOT/thirdparty/libgc/gc.o } } $else { @@ -31,7 +31,7 @@ $if dynamic_boehm ? { #flag -DGC_BUILTIN_ATOMIC=1 $if macos || linux { #flag -DGC_PTHREADS=1 - #flag -I@VEXEROOT/thirdparty/libgc/include + #flag -I @VEXEROOT/thirdparty/libgc/include $if (prod && !tinyc && !debug) || !(amd64 || arm64 || i386 || arm32) { // TODO: replace the architecture check with a `!$exists("@VEXEROOT/thirdparty/tcc/lib/libgc.a")` comptime call #flag @VEXEROOT/thirdparty/libgc/gc.o @@ -45,7 +45,7 @@ $if dynamic_boehm ? { #flag -DBUS_PAGE_FAULT=T_PAGEFLT #flag -DGC_PTHREADS=1 $if !tinyc { - #flag -I@VEXEROOT/thirdparty/libgc/include + #flag -I @VEXEROOT/thirdparty/libgc/include #flag @VEXEROOT/thirdparty/libgc/gc.o } $if tinyc { @@ -62,11 +62,11 @@ $if dynamic_boehm ? { #flag -DGC_NOT_DLL=1 #flag -DGC_WIN32_THREADS=1 $if tinyc { - #flag -I@VEXEROOT/thirdparty/libgc/include + #flag -I @VEXEROOT/thirdparty/libgc/include #flag @VEXEROOT/thirdparty/tcc/lib/libgc.a #flag -luser32 } $else { - #flag -I@VEXEROOT/thirdparty/libgc/include + #flag -I @VEXEROOT/thirdparty/libgc/include #flag @VEXEROOT/thirdparty/libgc/gc.o } } $else $if $pkgconfig('bdw-gc') { diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index a2c49adb97..cfca2f2e6d 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -93,6 +93,13 @@ fn (mut v Builder) post_process_c_compiler_output(res os.Result) { } return } + if res.exit_code != 0 && v.pref.gc_mode != .no_gc && res.output.contains('libgc.a') { + $if windows { + verror(r'Your V installation may be out-of-date. Try removing `thirdparty\tcc\` and running `.\make.bat`') + } $else { + verror('Your V installation may be out-of-date. Try removing `thirdparty/tcc/` and running `make`') + } + } for emsg_marker in [builder.c_verror_message_marker, 'error: include file '] { if res.output.contains(emsg_marker) { emessage := res.output.all_after(emsg_marker).all_before('\n').all_before('\r').trim_right('\r\n') diff --git a/vlib/v/cflag/cflags.v b/vlib/v/cflag/cflags.v index c42b1b7023..ef4f9746b4 100644 --- a/vlib/v/cflag/cflags.v +++ b/vlib/v/cflag/cflags.v @@ -117,10 +117,14 @@ pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) { mut others := []string{} mut libs := []string{} for copt in copts_without_obj_files { - if copt.starts_with('-l') || copt.ends_with('.a') { + if copt.starts_with('-l') { libs << copt continue } + if copt.ends_with('.a') { + libs << '"$copt"' + continue + } if copt.starts_with('-D') { defines << copt continue diff --git a/vlib/v/pref/default.v b/vlib/v/pref/default.v index 0b7f8b737a..03fa934a4f 100644 --- a/vlib/v/pref/default.v +++ b/vlib/v/pref/default.v @@ -85,6 +85,18 @@ pub fn (mut p Preferences) fill_with_defaults() { } rpath_name := os.file_name(rpath) p.building_v = !p.is_repl && (rpath_name == 'v' || rpath_name == 'vfmt.v') + if p.gc_mode == .unknown { + if p.backend != .c || p.building_v || p.is_bare || p.ccompiler == 'msvc' { + p.gc_mode = .no_gc + p.build_options << ['-gc', 'none'] + } else { + // enable the GC by default + p.gc_mode = .boehm_full_opt + p.parse_define('gcboehm') + p.parse_define('gcboehm_full') + p.parse_define('gcboehm_opt') + } + } if p.os == ._auto { // No OS specifed? Use current system p.os = get_host_os() diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 4818467287..5adbfca353 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -24,6 +24,7 @@ pub enum AssertFailureMode { } pub enum GarbageCollectionMode { + unknown no_gc boehm_full // full garbage collection mode boehm_incr // incremental garbage colletion mode @@ -204,7 +205,7 @@ pub mut: cleanup_files []string // list of temporary *.tmp.c and *.tmp.c.rsp files. Cleaned up on successfull builds. build_options []string // list of options, that should be passed down to `build-module`, if needed for -usecache cache_manager vcache.CacheManager - gc_mode GarbageCollectionMode = .no_gc // .no_gc, .boehm, .boehm_leak, ... + gc_mode GarbageCollectionMode = .unknown // .no_gc, .boehm, .boehm_leak, ... assert_failure_mode AssertFailureMode // whether to call abort() or print_backtrace() after an assertion failure message_limit int = 100 // the maximum amount of warnings/errors/notices that will be accumulated nofloat bool // for low level code, like kernels: replaces f32 with u32 and f64 with u64 @@ -327,9 +328,15 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin '-gc' { gc_mode := cmdline.option(current_args, '-gc', '') match gc_mode { - '', 'none' { + 'none' { res.gc_mode = .no_gc } + '', 'boehm' { + res.gc_mode = .boehm_full_opt // default mode + res.parse_define('gcboehm') + res.parse_define('gcboehm_full') + res.parse_define('gcboehm_opt') + } 'boehm_full' { res.gc_mode = .boehm_full res.parse_define('gcboehm') @@ -352,12 +359,6 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin res.parse_define('gcboehm_incr') res.parse_define('gcboehm_opt') } - 'boehm' { - res.gc_mode = .boehm_full_opt // default mode - res.parse_define('gcboehm') - res.parse_define('gcboehm_full') - res.parse_define('gcboehm_opt') - } 'boehm_leak' { res.gc_mode = .boehm_leak res.parse_define('gcboehm') diff --git a/vlib/v/tests/valgrind/valgrind_test.v b/vlib/v/tests/valgrind/valgrind_test.v index d5ac7fdf4a..c31300a43f 100644 --- a/vlib/v/tests/valgrind/valgrind_test.v +++ b/vlib/v/tests/valgrind/valgrind_test.v @@ -86,7 +86,7 @@ fn test_all() { base_filename := os.file_name(test).replace('.v', '') exe_filename := '$wrkdir/$base_filename' full_path_to_source_file := os.join_path(vroot, test) - compile_cmd := '${os.quoted_path(vexe)} -o ${os.quoted_path(exe_filename)} -cg -cflags "-w" -experimental -autofree ${os.quoted_path(full_path_to_source_file)}' + compile_cmd := '${os.quoted_path(vexe)} -o ${os.quoted_path(exe_filename)} -cg -cflags "-w" -experimental -gc none -autofree ${os.quoted_path(full_path_to_source_file)}' vprintln('compile cmd: ${bold(compile_cmd)}') res := os.execute(compile_cmd) if res.exit_code != 0 { diff --git a/vlib/v/vcache/vcache.v b/vlib/v/vcache/vcache.v index 4777897eba..c5927c38fb 100644 --- a/vlib/v/vcache/vcache.v +++ b/vlib/v/vcache/vcache.v @@ -55,7 +55,14 @@ pub fn new_cache_manager(opts []string) CacheManager { os.write_file(readme_file, readme_content) or { panic(err) } dlog(@FN, 'created readme_file:\n $readme_file') } - original_vopts := opts.join('|') + mut deduped_opts := map[string]bool{} + for o in opts { + deduped_opts[o] = true + } + deduped_opts_keys := deduped_opts.keys().filter(it != '' && !it.starts_with("['gcboehm', ")) + // TODO: do not filter the gcboehm options here, instead just start `v build-module vlib/builtin` without the -d gcboehm etc. + // Note: the current approach of filtering the gcboehm keys may interfere with (potential) other gc modes. + original_vopts := deduped_opts_keys.join('|') return CacheManager{ basepath: vcache_basepath vopts: original_vopts