~ chicken-core (chicken-5) 137739038294e14dd290726fe0265b16e85a7ab7
commit 137739038294e14dd290726fe0265b16e85a7ab7 Author: Peter Bex <peter@more-magic.net> AuthorDate: Thu Mar 9 21:36:05 2017 +0100 Commit: Evan Hanson <evhan@foldling.org> CommitDate: Fri Mar 10 20:44:13 2017 +1300 Avoid allocating scratchspace when reading fixnums. The code that handles reading digit streams into an integer is written to be as straightforward as possible. Currently this means it always allocates a bignum, even if the number is small enough to fit a fixnum. That way, we don't need to distinguish between these cases in the actual stream converter (str_to_bignum). We can improve on this a little bit by pre-allocating enough for a small bignum in the nursery, much like the C_s_a_u_i_integer_plus and friends do. This avoids malloc()ing a scratchspace just for the one small number, which will be free()d again as soon as the stack is full, resulting in a lot of needless thrashing. Signed-off-by: Evan Hanson <evhan@foldling.org> diff --git a/library.scm b/library.scm index 14fc9e5d..284b6530 100644 --- a/library.scm +++ b/library.scm @@ -1800,7 +1800,7 @@ EOF (end (or hashes digits))) (and-let* ((end) (num (##core#inline_allocate - ("C_s_a_i_digits_to_integer" 2) + ("C_s_a_i_digits_to_integer" 5) str start (car end) radix neg?))) (when hashes ; Eeewww. Feeling dirty yet? (set! seen-hashes? #t) @@ -1815,7 +1815,7 @@ EOF (end (scan-digits start))) (go-inexact!) (cons (##core#inline_allocate - ("C_s_a_i_digits_to_integer" 2) + ("C_s_a_i_digits_to_integer" 5) str start (car end) radix (eq? sign 'neg)) (cdr end))))))) (scan-decimal-tail ; The part after the decimal dot diff --git a/runtime.c b/runtime.c index e996559d..af844df4 100644 --- a/runtime.c +++ b/runtime.c @@ -10903,8 +10903,15 @@ C_s_a_i_digits_to_integer(C_word **ptr, C_word n, C_word str, C_word start, C_wo assert((radix > 1) && C_fitsinbignumhalfdigitp(radix)); nbits = (end - start) * C_ilen(radix - 1); - size = C_fix(C_BIGNUM_BITS_TO_DIGITS(nbits)); - result = C_allocate_scratch_bignum(ptr, size, negp, C_SCHEME_FALSE); + size = C_BIGNUM_BITS_TO_DIGITS(nbits); + if (size == 1) { + result = C_bignum1(ptr, C_truep(negp), 0); + } else if (size == 2) { + result = C_bignum2(ptr, C_truep(negp), 0, 0); + } else { + size = C_fix(size); + result = C_allocate_scratch_bignum(ptr, size, negp, C_SCHEME_FALSE); + } return str_to_bignum(result, s + start, s + end, radix); }Trap