~ chicken-core (chicken-5) a33fc6209f4f6f1c2e0baaf5092837e0a549adb7
commit a33fc6209f4f6f1c2e0baaf5092837e0a549adb7
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 12:21:49 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 04e2781e..0473797b 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -473,8 +473,22 @@
(loop (cdr xs)))))
(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 c9c9d944..a2da0db9 100644
--- a/runtime.c
+++ b/runtime.c
@@ -3107,7 +3107,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