From c9910c604279f438728cd268272e1839cbc53835 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 13 Mar 2017 15:47:51 +0100 Subject: Fix finalizer resuscitation causing excessive GC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * libguile/finalizers.c (async_gc_finalizer): (scm_i_register_async_gc_callback): Replace "weak gc callback" mechanism with "async gc callback" mechanism. Very similar but the new API is designed to be called a bounded number of times, to avoid running afoul of libgc heuristics. * libguile/weak-list.h: New internal header. * libguile/Makefile.am (noinst_HEADERS): Add weak-list.h. * libguile/weak-set.c (vacuum_all_weak_sets): (scm_c_make_weak_set, scm_init_weak_set): * libguile/weak-table.c (vacuum_all_weak_tables): (scm_c_make_weak_table, scm_init_weak_table): Arrange to vacuum all weak sets from a single async GC callback, and likewise for weak tables. Thanks to Ludovic Courtès for tracking this bug down! --- libguile/weak-list.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 libguile/weak-list.h (limited to 'libguile/weak-list.h') diff --git a/libguile/weak-list.h b/libguile/weak-list.h new file mode 100644 index 000000000..989cb7f0a --- /dev/null +++ b/libguile/weak-list.h @@ -0,0 +1,73 @@ +/* classes: h_files */ + +#ifndef SCM_WEAK_LIST_H +#define SCM_WEAK_LIST_H + +/* Copyright (C) 2016 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + + +#include "libguile/__scm.h" +#include "libguile/weak-vector.h" + + + +static inline SCM +scm_i_weak_cons (SCM car, SCM cdr) +{ + return scm_cons (scm_c_make_weak_vector (1, car), cdr); +} + +static inline SCM +scm_i_weak_car (SCM pair) +{ + return scm_c_weak_vector_ref (scm_car (pair), 0); +} + +static inline void +scm_i_visit_weak_list (SCM *list_loc, void (*visit) (SCM)) +{ + SCM in = *list_loc, out = SCM_EOL; + + while (scm_is_pair (in)) + { + SCM car = scm_i_weak_car (in); + SCM cdr = scm_cdr (in); + + if (!scm_is_eq (car, SCM_BOOL_F)) + { + scm_set_cdr_x (in, out); + out = in; + visit (car); + } + + in = cdr; + } + + *list_loc = out; +} + + +#endif /* SCM_WEAK_LIST_H */ + +/* + Local Variables: + c-file-style: "gnu" + End: +*/ -- cgit v1.2.3