From 8793aebe65f8162e8a2919326587b8554d5e53ab Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 11 Feb 2024 16:07:36 +0200 Subject: [PATCH] builtin: add gc_collect/0, gc_get_warn_proc/0, gc_set_warn_proc/1. Use them to turn off GC warnings by default. (#20788) --- vlib/builtin/builtin_d_gcboehm.c.v | 26 ++++++++++++++++++++++++++ vlib/builtin/builtin_nix.c.v | 2 +- vlib/builtin/builtin_notd_gcboehm.c.v | 27 ++++++++++++++++++++++++--- vlib/builtin/builtin_windows.c.v | 1 + 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/vlib/builtin/builtin_d_gcboehm.c.v b/vlib/builtin/builtin_d_gcboehm.c.v index 3d4b5a14918e5c..5f3188c01f3999 100644 --- a/vlib/builtin/builtin_d_gcboehm.c.v +++ b/vlib/builtin/builtin_d_gcboehm.c.v @@ -134,6 +134,13 @@ fn C.GC_is_disabled() int // protect memory block from being freed before this call fn C.GC_reachable_here(voidptr) +// gc_collect explicitly performs a garbage collection run. +// Note, that garbage collections are done automatically when needed in most cases, +// so usually you should need to call that function often. +pub fn gc_collect() { + C.GC_gcollect() +} + // for leak detection it is advisable to do explicit garbage collections pub fn gc_check_leaks() { $if gcboehm_leak ? { @@ -165,3 +172,22 @@ fn C.GC_remove_roots(voidptr, voidptr) fn C.GC_get_sp_corrector() fn (voidptr, voidptr) fn C.GC_set_sp_corrector(fn (voidptr, voidptr)) + +// GC warnings are silenced by default, but can be redirected to a custom cb function by programs too: +type FnGC_WarnCB = fn (msg &char, arg usize) + +fn C.GC_get_warn_proc() FnGC_WarnCB +fn C.GC_set_warn_proc(cb FnGC_WarnCB) + +// gc_get_warn_proc returns the current callback fn, that will be used for printing GC warnings +pub fn gc_get_warn_proc() FnGC_WarnCB { + return C.GC_get_warn_proc() +} + +// gc_set_warn_proc sets the callback fn, that will be used for printing GC warnings +pub fn gc_set_warn_proc(cb FnGC_WarnCB) { + C.GC_set_warn_proc(cb) +} + +// used by builtin_init: +fn internal_gc_warn_proc_none(msg &char, arg usize) {} diff --git a/vlib/builtin/builtin_nix.c.v b/vlib/builtin/builtin_nix.c.v index 12611f5a9cee41..26063b74d4c86e 100644 --- a/vlib/builtin/builtin_nix.c.v +++ b/vlib/builtin/builtin_nix.c.v @@ -4,7 +4,7 @@ module builtin fn builtin_init() { - // Do nothing + gc_set_warn_proc(internal_gc_warn_proc_none) } fn break_if_debugger_attached() { diff --git a/vlib/builtin/builtin_notd_gcboehm.c.v b/vlib/builtin/builtin_notd_gcboehm.c.v index 56002ff54abe3f..5f9eb189a38939 100644 --- a/vlib/builtin/builtin_notd_gcboehm.c.v +++ b/vlib/builtin/builtin_notd_gcboehm.c.v @@ -18,7 +18,28 @@ fn C.GC_get_heap_usage_safe(pheap_size &usize, pfree_bytes &usize, punmapped_byt fn C.GC_get_memory_use() usize -// provide an empty function when manual memory management is used -// to simplify leak detection -// +fn C.GC_gcollect() + +// gc_check_leaks is useful for detecting leaks, but it needs the GC to run. +// When GC is not used, it is a NOP. pub fn gc_check_leaks() {} + +// gc_collect explicitly performs a garbage collection. +// When the GC is not on, it is a NOP. +pub fn gc_collect() {} + +type FnGC_WarnCB = fn (msg &char, arg usize) + +fn C.GC_get_warn_proc() FnGC_WarnCB +fn C.GC_set_warn_proc(cb FnGC_WarnCB) + +// gc_get_warn_proc returns the current callback fn, that will be used for printing GC warnings. +// When the GC is not on, it is a NOP. +pub fn gc_get_warn_proc() {} + +// gc_set_warn_proc sets the callback fn, that will be used for printing GC warnings. +// When the GC is not on, it is a NOP. +pub fn gc_set_warn_proc(cb FnGC_WarnCB) {} + +// used by builtin_init +fn internal_gc_warn_proc_none(msg &char, arg usize) {} diff --git a/vlib/builtin/builtin_windows.c.v b/vlib/builtin/builtin_windows.c.v index 0c8749429073ed..d538c5c91dd161 100644 --- a/vlib/builtin/builtin_windows.c.v +++ b/vlib/builtin/builtin_windows.c.v @@ -48,6 +48,7 @@ const enable_wrap_at_eol_output = 2 const evable_virtual_terminal_processing = 4 fn builtin_init() { + gc_set_warn_proc(internal_gc_warn_proc_none) g_original_codepage = C.GetConsoleOutputCP() C.SetConsoleOutputCP(cp_utf8) C.atexit(restore_codepage)