~ 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