From 885484c97bb17bed42d3fcaeda60d1e0f2c52dab Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sat, 8 Feb 2020 11:32:22 +0100 Subject: Handle GMP allocations through libgc and remove bignum finalizers. This significantly speeds up loads that create lots of bignums, like (language cps slot-allocation) for files with many top-level definitions. Compiling such a file is typically 2.5 times faster. See . * libguile/numbers.c (custom_gmp_malloc): Use 'scm_gc_malloc_pointerless' instead of 'scm_malloc'. (custom_gmp_realloc): Use 'scm_gc_realloc'. (custom_gmp_free): Remove call to 'free'. (make_bignum): Use 'scm_gc_malloc' instead of 'scm_gc_malloc_pointerless'. Call 'scm_i_set_finalizer' only when SCM_INSTALL_GMP_MEMORY_FUNCTIONS is false. --- libguile/numbers.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/libguile/numbers.c b/libguile/numbers.c index 13223f8cb..37351e35f 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016, 2018, 2019 Free Software Foundation, Inc. +/* Copyright (C) 1995-2016, 2018, 2019, 2020 Free Software Foundation, Inc. * * Portions Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories * and Bellcore. See scm_divide. @@ -235,19 +235,20 @@ finalize_bignum (void *ptr, void *data) static void * custom_gmp_malloc (size_t alloc_size) { - return scm_malloc (alloc_size); + return scm_gc_malloc_pointerless (alloc_size, "GMP"); } static void * custom_gmp_realloc (void *old_ptr, size_t old_size, size_t new_size) { - return scm_realloc (old_ptr, new_size); + return scm_gc_realloc (old_ptr, old_size, new_size, "GMP"); } static void custom_gmp_free (void *ptr, size_t size) { - free (ptr); + /* Do nothing: all memory allocated by GMP is under GC control and + will be freed when needed. */ } @@ -258,11 +259,15 @@ make_bignum (void) scm_t_bits *p; /* Allocate one word for the type tag and enough room for an `mpz_t'. */ - p = scm_gc_malloc_pointerless (sizeof (scm_t_bits) + sizeof (mpz_t), - "bignum"); + p = scm_gc_malloc (sizeof (scm_t_bits) + sizeof (mpz_t), + "bignum"); p[0] = scm_tc16_big; - scm_i_set_finalizer (p, finalize_bignum, NULL); + /* When the 'custom_gmp_*' functions are in use, no need to set a + finalizer since allocated memory is under GC control. In other + cases, set a finalizer to call 'mpz_clear', which is expensive. */ + if (!scm_install_gmp_memory_functions) + scm_i_set_finalizer (p, finalize_bignum, NULL); return SCM_PACK (p); } -- cgit v1.2.3