Part of e7744efb7d triggered a test failure (that I missed by somehow
running tests incorrectly). It turns out that phase -1 transformer
bindings can be used in phase-0 code via shifting.
This change does not effect the repair for building with
machine-independent bytecode.
This change avoids the stair-step effect that is depicted in the
"current Racket -M" build plot from the January 2019 blog post about
Racket on Chez Scheme.
The stair step in that plot is a result of a combination of effects,
but one key part is that the `.set-transformer!` linklet import (to
support macro definitions) has a reference back to the namespace.
While `.set-transformer!` normally would not be captured in any
closure, `db/private/generic/prepared` creates a thread that causes
the "prefix" part of a closure to be moved to a thread's runstack
before it can be pruned by the GC. The stair-step problem happens only
when running directly from machine-independent form, because that form
is recompiled in a way that doesn't optimize away the unused
`.set-transformer!` import. The change in this commit avoids a
reference to the namespace in some cases where it will not be useful,
which turns out to be sufficient to address the build problem.
A more complete repair would be to change the compiler to pair a
closure prefix on the runstack with a liveness mask. An even more
complete repair is to switch to Racket CS. Racket CS is immune to the
problem, even when running from machine-independent bytecode, because
its closures do not keep extra references (with the tradeoff that
there's less sharing).
The `--recompile-only` flag makes sense if machine-independent
bytecode can be deterministically generated from all Racket builds.
While the current compiler is close, there are obstacles such as the
lack of support for single-precision floating-point literals in Racket
CS. We settle for using `--recompile-only` in the main bundle phase,
which is the part that most needs to go fast.
To make fasl writing as determinsitic and portable as possible, write
+nan.0 and +nan.f always with a specific bit pattern.
This choice risks losing information that is potentially useful, but
given the way that Racket treats all NaN encodings as equivalent, that
rick seems low.
For example, `#hasheq()` is `eq?` to `(hasheq)` and `(hash-remove
(hasheq 'x 2) 'x)`. Making empty hash table unique avoids some
potential and actual inconsistencies between traditional Racket and
Racket CS, such as in machine-independent bytecode.
Move different handling of serialized syntax data to the schemify
layer instead of te expander, so that the result of compiling in
machine-independent form is the same for traditional Racket and Racket
CS.
The `--recompile-only` flag is intended to help dectect build
problems, especially distribution builds where packages are
supposed to be in built form.
This allows it to cooperate better with Typed Racket, particularly
regarding the `Any` type. The guard and use of `#:authentic` also
check that it's still a singleton in all cases.
Avoid parsing cross-linklet optimization information until it is
needed. This change also avoids a problem with saving hash codes
that are platform-specific.
Insteda of just consulting `lib-search-dirs` in the host system's
config during cross-build mode, use `lib-dir` if set to arrive at
the expected default when `lib-search-dirs` is not set.
Handle not-this-platform paths that manage to evade the heuristics for
converting paths to and from relative form. Otherwise, building can go
wrong on on Windows when using machine-independent starting files
generated on Unix-like systems.
The `--error-out` and `--error-in` flags are meant to work together to
chain a sequence of `raco setup` steps where one of them might fail,
but other steps should proceed. The last step in that sequence should
use only `--error-in`, so that it exits with failure if any of the
steps failed.
The `both` target of the toplevel makefile uses `--error-out` and
`--error-in` to let a Racket CS build proceed as long as the
traditional Racket build made it to the last `raco setup` step, which
means that it survives package-build errors.