diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 0862e3d3f5..1265d79e03 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -884,8 +884,8 @@ (begin #; (printf "~s\n~s\n" - (zo-parse (open-input-bytes t1)) - (zo-parse (open-input-bytes t2))) + (zo-parse (open-input-bytes t1)) + (zo-parse (open-input-bytes t2))) #f ))))) @@ -3036,6 +3036,17 @@ (letrec ([z (lambda () z)]) (f z) #f) (letrec ([z (lambda () z)]) (f z) #t)))) +(test-comp `(module m racket/base + (define f (random)) + (define g (random)) + (list (variable-reference-constant? (#%variable-reference f)) + (#%variable-reference g))) + `(module m racket/base + (define f (random)) + (define g (random)) + (list #t + (#%variable-reference g)))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check remotion of dead code after error (test-comp '(lambda () (random) (error 'error)) diff --git a/racket/collects/ffi/unsafe/alloc.rkt b/racket/collects/ffi/unsafe/alloc.rkt index 5ca44e88e0..943a365d12 100644 --- a/racket/collects/ffi/unsafe/alloc.rkt +++ b/racket/collects/ffi/unsafe/alloc.rkt @@ -7,6 +7,13 @@ (define allocated (make-late-weak-hasheq)) +;; A way to show all still-unfinalized values on exit: +#; +(plumber-add-flush! (current-plumber) + (lambda (v) + (for ([(k v) (in-hash allocated)]) + (printf "~s\n" k)))) + (define (deallocate v) ;; Called as a finalizer, we we assume that the ;; enclosing thread will not be interrupted. diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 7289a04cb2..43bcc4e670 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -4309,6 +4309,29 @@ ref_optimize(Scheme_Object *data, Optimize_Info *info, int context) int is_mutated = 0; optimize_info_mutated_lookup(info, SCHEME_LOCAL_POS(v), &is_mutated); SCHEME_PTR1_VAL(data) = (is_mutated ? scheme_false : scheme_true); + } else if (SAME_TYPE(SCHEME_TYPE(v), scheme_compiled_toplevel_type)) { + /* Knowing whether a top-level variable is fixed lets up optimize + uses of `variable-reference-constant?` */ + if (info->top_level_consts) { + int pos = SCHEME_TOPLEVEL_POS(v); + int fixed = 0; + + if (scheme_hash_get(info->top_level_consts, scheme_make_integer(pos))) + fixed = 1; + else { + GC_CAN_IGNORE Scheme_Object *t; + t = scheme_hash_get(info->top_level_consts, scheme_false); + if (t) { + if (scheme_hash_get((Scheme_Hash_Table *)t, scheme_make_integer(pos))) + fixed = 1; + } + } + + if (fixed) { + v = scheme_toplevel_to_flagged_toplevel(v, SCHEME_TOPLEVEL_FIXED); + SCHEME_PTR1_VAL(data) = v; + } + } } info->preserves_marks = 1;