The bytecode compiler used to convert an expresison like
(<flonum-op> <simple-expr> <complex-expr>)
to
(let ([id <complex-expr>])
(<flonum-op> <simple-expr> id))
to help an older version of the JIT avoid boxing the result of
<simple-expr>, but that transformation isn't needed, since the JIT can
keep unboxed values on the stack.
The transformation was complex and apparently buggy.
The changes also include a repair to the JIT for code that the
bytecode compiler formerly wouldn't generate, but which is allowed
bytecode.
Closes PR 13052
Generalize splitting of `(let-values ([(x ...) (values e ...)]) ....)'
to `(let ([x e] ...) ....)' for any `e', since it's always equivalent.
Right?
(The old requirements on the `e's seem to be needed only for
`letrec-values' splitting and maybe mutable variables.)
Treat unsafe functional operations (which never raise an
exception) as omitable, which means that simple `let-values'
combinations can be split into `let' bindings, etc.
corner of the definitions window, based on the information that check
syntax computes
This commit contains two separate changes to make this work:
- adding a new renderer, based on the text renderer, that
pulls out the contents of the blue boxes and saves them
in the doc/ directories (specifically in the files named
contract-blueboxes.rktd)
- extend check syntax to use and display the information
build by the new renderer
Internally, there's a `prop:method-arity-error' property that is
used for keyword-accepting methods. The same thing could be
accomplished with `procedure->method', but the new property avoids
a wrapper. It might be nice to expose the property from `racket/base',
but that creates trouble for generating arity errors for keyword-
requiring procedures (i.e., when such a procedure is wrapped), so
keep it provate for now.
Closes PR 12982
A progress evt from a close input port must be initially ready,
and the primitive `peek-bytes-avail!' checks a progress evt
before checking whether the port is closed.
These changes resolve a race in `read-bytes-evt' and related evt
constructors.
Fix tchecking for a rest argument to a function that
is lifted by closure conversion so that one of its
arguments is a mutable local variable's location.
Also reject bytecode that would pass too many arguments
to a lifted function, since that would trigger an arity
error that might try to use a location as a value.
Merge to v5.3
When a `port-commit-peeked' succeeds, position information should
(appear to) be updated. This patch synchronizes commits and
position information for primitive ports, but synchronizing
them for user ports remains a problem.
When `guard-evt' or `nack-guard-evt' is used, `sync' didn't
account for the possibility that a channel or semaphore
action might complete during the call to the guard, in which
case it might fail to select the event that has already
completed.
Merge to v5.3
Convert
(hash-ref <hash> <key-expr> (lambda () <literal>))
to
(hash-ref <hash> <key-expr> <literal>)
which is useful for making the `case' expansion fit
Typed Racket.
The "simpliciation" of a syntax object's lexical context was dropping
module contexts that have no bindings, but those contexts now
contribute to the identifty of some bindings. Fix simplification
to replace the full rename rename with a simplified one, instead
of just dropping it.
Merge to v5.3
When a module is loaded from bytecode and then the value of
`use-compiled-file-paths' changes, an attempt to load a submodule
would fail, because source isn't used if the main module is
already declared, and the bytecode code is not used according to
`use-compiled-file-paths'. Make the bytecode path stick when it
is used once, so that submodule loads succeed, and make it work
even with `namespace-module-attach'.
The module-attach part of this protocol requires a change to the
API of a module name resolver: the notification mode gets two
arguments, instead of one, where the second argument is an
environment.
The lambda-lifting transformation needs to iterate to a fixpoint
where each lambda's added arguments and order are known. The
check for whether something changed was formerly just the number
of added arguments, but that's not good enough, because a binding
might get lifted away while another one acquires an extra argument.
The right test is to check the count and original bindings for the
added arguments.
Closes PR 12910
Since the optimizer can lambda-lift a function and adds box arguments
(i.e., locations of mutable variables instead of values), then
the validator must check that calls and declarations are consistent.
But declaration-side information wasn't registered properly.
This is an old bug, but it was exposed by recent improvements
in unboxing.
Also, fix JIT implementation of explicitly decremented fuel on
a 64-bit platform, plus some other code clean-up.
Each future thread has its own x87 flags, apparently reset to the
default (at least on Mac OS X) rather than inherited from the
creating thread, so reset the x87 configuration in each new future
thread.
To support module caching, module path indexes must be cloned
for each use of the cached module, so that path resolutions
don't collide. Cloning was previously implemented at the point
of shifting the modidx based on the module instantiation name,
but now its cloned at declaration time. This result in better
sharing of module-path resolutions, which in turn speeds up
compile-time instantiation of modules, which in turn speeds up
interactions & examples in documentation (as much as 10% for the
Guide, for example).
Furthermore, the reverse cache within a modidx may have been
used improperly during cloning, and that's not a problem in
the new implementation.
The JIT wants to detect calls to functions bound to module-level
variables that are always instantiated to a procedure of a particular
arity, in which case it can avoid some checks. The problem is that
bytecode and JITted code can be shared via the module cache across
namespaces that use different modules to implement a particular module
path or that enable the JIT differently. In particular, starting with
one that has a procedure binding and then using one (in a different
namespace) that has a non-procedure binding could lead to a crash.
Defend against this possibility by never treating imported variables
as constant in that sense. The JIT detects imported variables through
a new import map in the prefix.
This change may slow code. My guess is that it will have no
performance impact in practice, due to cross-module inlining,
although I can construct a microbenchmark that slows by 20%.
The optimizer can no longer reduce
(with-continuation-mark _id _v-expr _expr)
to just
_expr
when _v-expr and _expr are simple enough, because _id
might be bound to a continuation mark key with an
impersonator that checks the result of _v-expr.
The loss of an optimization can have a significant affect on
errortrace of microbenchmarks, such as
(for ([i (in-range 10000000)])
i)
A arity-reduced procedure-valued `prop:procedure' was not handled
correctly, for example.
A good candidate for random testing? I had the right kind of test in
place, but only for an arity of 1. It turns out that testing any other
arity would have exposed the problem, so now there are tests with
arity 0. If I had randomly generated procedures instead of manually
constructing `f0' through `f1:+' in "procs.rktl", then maybe I would
have more naturally generalized the arity testing, too. Then again,
I did already have relevant inputs, and it was the testing of inputs
that was too specific.
Closes PR 12870
For all currently supported platforms, the result was already
portable, despite the documentation's hedging.
Also fixed up the documentation in other ways, such as the fact
that `seconds->date' returns a `date*'.
Add extra intitial-message lines, use "..." on a field name
to indicate that it could reasonably be hidden by default,
and refine some existing messages.
Includes the addition of 'overflow and 'start-overflow-work
events, whcih are effectively specializations of 'sync and
'start-work to expose overflow handling.
Also, fix a bug related to a potential GC during mark-stack
restore from a lightweight continuation.
By itself, this change won't help anything, because tail-call
allocation is triggered for something that can't be called directly.
This change sets up part of an improvement for future-local recovery
from stack overflow, though.
(I had trouble constructing a test that would trigger the new code.
Fortunately, the existing tests trigger it.)
When a "synchronized" operation is handled for a future thread
during a `touch' on the future, then still report the handling
as "synchronized" insteda of "blocked".
Also, fix FFI procedures to preserve names: change `ptr-ref' with
`_fpointer' on an `ffi-obj' value to return the `ffi-obj'
value, so that the name in the `ffi-obj' value can be used
by `_cprocedure'.
Closes PR 12645