~ 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