~ 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