~ chicken-core (chicken-5) 3cda4c56bf8abe1e1d76fd61474c9c397db26f04


commit 3cda4c56bf8abe1e1d76fd61474c9c397db26f04
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Tue Mar 8 20:47:19 2016 +1300
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Tue Mar 8 22:40:31 2016 +1300

    Include argvector size in C_demand() calculations.
    
    When generating code, we check all the callees and their argument sizes.
    The largest of these will be added to the C_demand() call to ensure we
    can allocate the argvector to call it.  If this is less than the current
    argument count, we don't add it because we won't need to allocate.
    
    Signed-off-by: Evan Hanson <evhan@foldling.org>

diff --git a/c-backend.scm b/c-backend.scm
index d8fe9297..cbe58953 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -729,6 +729,7 @@
 	 (let* ((n (lambda-literal-argument-count ll))
 		(rname (real-name id db))
 		(demand (lambda-literal-allocated ll))
+		(max-av (apply max 0 (lambda-literal-callee-signatures ll)))
 		(rest (lambda-literal-rest-argument ll))
 		(customizable (lambda-literal-customizable ll))
 		(empty-closure (and customizable (zero? (lambda-literal-closure-size ll))))
@@ -803,8 +804,8 @@
 			     #t "C_heap_size_is_fixed=1;"))
 		      (when target-stack-size
 			(gen #t "C_resize_stack(" target-stack-size ");") ) )
-		    (gen #t "C_check_nursery_minimum(" demand ");"
-			 #t "if(!C_demand(" demand ")){"
+		    (gen #t "C_check_nursery_minimum(C_calculate_demand(" demand ",c," max-av "));"
+			 #t "if(!C_demand(C_calculate_demand(" demand ",c," max-av "))){"
 			 #t "C_save_and_reclaim((void*)C_" topname ",c,av);}"
 			 #t "toplevel_initialized=1;"
 			 #t "if(!C_demand_2(" ldemand ")){"
@@ -822,7 +823,7 @@
 		  (when (and (not unsafe) (not no-argc-checks) (> n 2) (not empty-closure))
 		    (gen #t "if(c<" n ") C_bad_min_argc_2(c," n ",t0);") )
 		  (when insert-timer-checks (gen #t "C_check_for_interrupt;"))
-		  (gen #t "if(!C_demand((c-" n ")*C_SIZEOF_PAIR +" demand ")){") )
+		  (gen #t "if(!C_demand(C_calculate_demand((c-" n ")*C_SIZEOF_PAIR +" demand ",c," max-av "))){"))
 		 (else
 		  (unless direct (gen #t "C_word *a;"))
 		  (when (and direct (not unsafe) (not disable-stack-overflow-checking))
@@ -837,7 +838,10 @@
 			 ;; The interrupt handler may fill the stack, so we only
 			 ;; check for an interrupt when the procedure is restartable
 			 (when insert-timer-checks (gen #t "C_check_for_interrupt;"))
-			 (gen #t "if(!C_demand(" demand ")){"))
+			 (gen #t "if(!C_demand(C_calculate_demand("
+			      demand
+			      (if customizable ",0," ",c,")
+			      max-av "))){"))
 			(else
 			 (gen #\{)))))
 	   (cond ((and (not (eq? 'toplevel id)) (not direct))
diff --git a/chicken.h b/chicken.h
index ab365986..be5f308d 100644
--- a/chicken.h
+++ b/chicken.h
@@ -1023,6 +1023,7 @@ typedef void (C_ccall *C_proc)(C_word, C_word *) C_noret;
 #endif
 #define C_stack_pointer_test       ((C_word *)C_alloca(1))
 #define C_demand_2(n)              (((C_word *)C_fromspace_top + (n)) < (C_word *)C_fromspace_limit)
+#define C_calculate_demand(n,c,m)  ((n) + (((c) > (m)) ? 0 : (m)))
 #define C_fix(n)                   ((C_word)((C_uword)(n) << C_FIXNUM_SHIFT) | C_FIXNUM_BIT)
 #define C_unfix(x)                 C_CHECKp(x,C_fixnump(C_VAL1(x)),((C_VAL1(x)) >> C_FIXNUM_SHIFT))
 #define C_make_character(c)        (((((C_uword)(c)) & C_CHAR_BIT_MASK) << C_CHAR_SHIFT) | C_CHARACTER_BITS)
diff --git a/compiler.scm b/compiler.scm
index 301dcfef..c91e21c2 100644
--- a/compiler.scm
+++ b/compiler.scm
@@ -2689,7 +2689,7 @@
 		  (set! temporaries temps)
 		  (set! ubtemporaries ubtemps)
 		  (set! allocated alc)
-		  (set! signatures sigs)
+		  (set! signatures (lset-adjoin = sigs argc))
 		  (make-node '##core#proc (list (first params)) '()) ) ) ) ) )
 
 	  ((let)
Trap