diff --git a/c/globals.h b/c/globals.h index 4a10b7356e..b42e1c2176 100644 --- a/c/globals.h +++ b/c/globals.h @@ -118,6 +118,7 @@ EXTERN struct S_G_struct { ptr null_continuation_id; ptr collect_request_pending_id; ptr event_and_resume_id; + ptr event_and_resume_star_id; /* gc.c */ ptr guardians[static_generation+1]; diff --git a/c/schsig.c b/c/schsig.c index 9fe6235023..ac9303ed73 100644 --- a/c/schsig.c +++ b/c/schsig.c @@ -425,6 +425,7 @@ static void handle_call_error(tc, type, x) ptr tc; iptr type; ptr x; { void S_handle_docall_error() { ptr tc = get_thread_context(); + AC0(tc) = (ptr)0; handle_call_error(tc, ERROR_CALL_NONPROCEDURE, CP(tc)); } @@ -465,14 +466,28 @@ void S_handle_event_detour() { iptr argcnt, i; argcnt = (iptr)AC0(tc); - for (i = argcnt; i > 0; i--) { - resume_args = Scons(S_get_scheme_arg(tc, i), resume_args); - } - CP(tc) = S_symbol_value(S_G.event_and_resume_id); - S_put_scheme_arg(tc, 1, resume_proc); - S_put_scheme_arg(tc, 2, resume_args); - AC0(tc) = (ptr)2; + if (argcnt < asm_arg_reg_cnt) { + /* Avoid allocation by passing arguments directly; this case + should always happen if the right number of arguments are + passed to a function, because the compiler will only use + `detour-event` when the expected number is small enough. */ + for (i = argcnt; i > 0; i--) + S_put_scheme_arg(tc, i+1, S_get_scheme_arg(tc, i)); + S_put_scheme_arg(tc, 1, resume_proc); + CP(tc) = S_symbol_value(S_G.event_and_resume_id); + AC0(tc) = (ptr)(argcnt+1); + } else { + /* At least one argument can go in a register, otherwise the + compiler would not use `detour-event` for any functions. */ + for (i = argcnt; i > 0; i--) + resume_args = Scons(S_get_scheme_arg(tc, i), resume_args); + resume_args = Scons(resume_proc, resume_args); + + CP(tc) = S_symbol_value(S_G.event_and_resume_star_id); + S_put_scheme_arg(tc, 1, resume_args); + AC0(tc) = (ptr)2; + } } static void keyboard_interrupt(ptr tc) { @@ -712,6 +727,9 @@ void S_schsig_init() { S_protect(&S_G.event_and_resume_id); S_G.event_and_resume_id = S_intern((const unsigned char *)"$event-and-resume"); + + S_protect(&S_G.event_and_resume_star_id); + S_G.event_and_resume_star_id = S_intern((const unsigned char *)"$event-and-resume*"); } diff --git a/makefiles/Mf-install.in b/makefiles/Mf-install.in index 9ea19706b1..7d28a8c41a 100644 --- a/makefiles/Mf-install.in +++ b/makefiles/Mf-install.in @@ -62,7 +62,7 @@ InstallLZ4Target= # no changes should be needed below this point # ############################################################################### -Version=csv9.5.3.18 +Version=csv9.5.3.19 Include=boot/$m PetiteBoot=boot/$m/petite.boot SchemeBoot=boot/$m/scheme.boot diff --git a/s/cmacros.ss b/s/cmacros.ss index fb947c4a76..bbeedf0fb6 100644 --- a/s/cmacros.ss +++ b/s/cmacros.ss @@ -328,7 +328,7 @@ [(_ foo e1 e2) e1] ... [(_ bar e1 e2) e2]))))]))) -(define-constant scheme-version #x09050312) +(define-constant scheme-version #x09050313) (define-syntax define-machine-types (lambda (x) diff --git a/s/cpnanopass.ss b/s/cpnanopass.ss index 6b45a16c05..26f50e1943 100644 --- a/s/cpnanopass.ss +++ b/s/cpnanopass.ss @@ -9807,6 +9807,8 @@ `(seq (set! ,(ref-reg %trap) ,(build-unfix e)) ,t)))]) + (define-inline 3 $get-timer + [() (build-fix (ref-reg %trap))]) (define-inline 3 directory-separator? [(e) (if-feature windows (bind #t (e) @@ -10882,11 +10884,12 @@ (not (direct-call-label-referenced dcl)) (nanopass-case (L11 CaseLambdaClause) cl [(clause (,x* ...) (,local1* ...) ,mcp ,interface ,tlbody) - (let loop ([tlbody tlbody]) - (nanopass-case (L11 Tail) tlbody - [(seq (trap-check ,ioc) ,tlbody) #t] - [(seq (overflow-check) ,tlbody) (loop tlbody)] - [else #f]))]))) + (and (fx< -1 interface (constant asm-arg-reg-cnt)) + (let loop ([tlbody tlbody]) + (nanopass-case (L11 Tail) tlbody + [(seq (trap-check ,ioc) ,tlbody) #t] + [(seq (overflow-check) ,tlbody) (loop tlbody)] + [else #f])))]))) cl* (info-lambda-dcl* info)))]) (let-values ([(local* tlbody) (flatten-clauses info cl* (info-lambda-dcl* info) detour-trap-check?)]) (safe-assert (nodups local*)) diff --git a/s/primdata.ss b/s/primdata.ss index c0f256c220..8df09ec706 100644 --- a/s/primdata.ss +++ b/s/primdata.ss @@ -1875,6 +1875,7 @@ ($error-handling-mode? [sig [(ptr) -> (boolean)]] [flags pure unrestricted mifoldable]) ($event [flags single-valued]) ($event-and-resume [flags]) + ($event-and-resume* [flags]) ($exactnum? [sig [(ptr) -> (boolean)]] [flags pure unrestricted mifoldable]) ($exactnum-imag-part [flags single-valued]) ($exactnum-real-part [flags single-valued]) @@ -2081,6 +2082,7 @@ ($generation [flags single-valued]) ($gensym [sig [() (string) (string string) -> (gensym)]] [flags alloc]) ; needs immutable strings ($gensym->pretty-name [flags single-valued]) + ($get-timer [flags single-valued]) ($guard [flags]) ($hand-coded [flags single-valued]) ($hashtable-report [flags true]) diff --git a/s/prims.ss b/s/prims.ss index 6529c1ef74..b2494519aa 100644 --- a/s/prims.ss +++ b/s/prims.ss @@ -598,6 +598,10 @@ ($oops '$set-timer "~s is not a positive fixnum" ticks)) ($set-timer ticks))) +(define $get-timer + (lambda () + ($get-timer))) + (define $fx+? (lambda (x y) ($fx+? x y))) @@ -1558,9 +1562,37 @@ (define $event (lambda () ($event))) -(define $event-and-resume (lambda (proc args) - ($event) - (apply proc args))) +(let () + (define (inc) + ;; make up for decrement that will happen immediately on retry: + (let ([t ($get-timer)]) + (when (fx< t (most-positive-fixnum)) + ($set-timer (fx+ t 1))))) + + (set! $event-and-resume + (case-lambda + [(proc) + ($event) + (inc) + (proc)] + [(proc arg) + ($event) + (inc) + (proc arg)] + [(proc arg1 arg2) + ($event) + (inc) + (proc arg1 arg2)] + [(proc . args) + ($event) + (inc) + (apply proc args)])) + + (set! $event-and-resume* + (lambda (proc+args) + ($event) + (inc) + (apply (car proc+args) (cdr proc+args))))) (define $tc (lambda () ($tc))) (define $thread-list (lambda () ($thread-list)))