~ chicken-core (chicken-5) d04f591d023b4f091e82d530b791929b61e9bea5


commit d04f591d023b4f091e82d530b791929b61e9bea5
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Sun Aug 30 20:11:45 2015 +0200
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Fri Sep 25 08:01:43 2015 +0200

    Dynamically determine if we can re-use argvectors.
    
    This applies to CPS context procedures which call other procedures in
    CPS context only.  This replaces a few memcpy() calls with memmove()
    because in a few extreme situations, argvectors can remain in the
    temporary stack indefinitely (which is a good thing).
    
    Signed-off-by: Evan Hanson <evhan@foldling.org>

diff --git a/c-backend.scm b/c-backend.scm
index 41076027..08324755 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -461,8 +461,22 @@
 	 args) )
 
       (define (push-args args i selfarg)
-	(let ((n (length args)))
-	  (gen #t "C_word av2[" (+ n (if selfarg 1 0)) "];")
+	(let* ((n (length args))
+	       (avl (+ n (if selfarg 1 0)))
+	       (caller-has-av? (not (or (lambda-literal-customizable ll)
+					(lambda-literal-direct ll)))))
+	  ;; Try to re-use argvector from current function if it is
+	  ;; large enough.  push-args gets used only for functions in
+	  ;; CPS context, so callee never returns to current function.
+	  ;; And even so, av[] is already copied into temporaries.
+	  (cond (caller-has-av?
+		 (gen #t "C_word *av2;")
+		 (gen #t "if(c >= " avl ") {")
+		 (gen #t "  av2=av; /* Re-use our own argvector */")
+		 (gen #t "} else {")
+		 (gen #t "  av2=C_alloc(" avl ");")
+		 (gen #t "}"))
+		(else (gen #t "C_word av2[" avl "];")))
 	  (when selfarg (gen #t "av2[0]=" selfarg ";"))
 	  (do ((j (if selfarg 1 0) (add1 j))
 	       (args args (cdr args)))
diff --git a/runtime.c b/runtime.c
index ad62e4f2..ac4a84a8 100644
--- a/runtime.c
+++ b/runtime.c
@@ -2708,7 +2708,7 @@ void C_save_and_reclaim(void *trampoline, int n, C_word *av)
 {
   if(C_temporary_stack != av) { /* used in apply */
     C_temporary_stack = C_temporary_stack_bottom - n;
-    C_memcpy(C_temporary_stack, av, n * sizeof(C_word));
+    C_memmove(C_temporary_stack, av, n * sizeof(C_word));
   }
 
   C_reclaim(trampoline, n);
Trap