From 9ab2c4bd12190f9fe24135126f46a93172ed4d42 Mon Sep 17 00:00:00 2001 From: Peter Bex
Date: Sun, 30 Aug 2015 20:11:45 +0200 Subject: [PATCH] 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). --- c-backend.scm | 18 ++++++++++++++++-- runtime.c | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/c-backend.scm b/c-backend.scm index c8d37d0..90c94b3 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 873b553..394b9c3 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); @@ -7805,7 +7805,7 @@ void C_ccall C_make_structure(C_word c, C_word *av) { if(!C_demand(c - 1)) { C_temporary_stack = C_temporary_stack_bottom - (c - 1); - C_memcpy(C_temporary_stack, av + 1, (c - 1) * sizeof(C_word)); + C_memmove(C_temporary_stack, av + 1, (c - 1) * sizeof(C_word)); C_reclaim((void *)make_structure_2, c - 1); } -- 2.1.4