The optimizer was able to use the type information gained outside
the let's to reduce expressions inside the lets. For example, in
(lambda (z) (car z) (let ([o (random)]) (pair? z)))
it reduces (pair? z) ==> #t.
This enable the propagation in the other direction so in
(lambda (z) (let ([o (random)]) (car z)) (pair? z))
it reduces (pair? z) ==> #t too.
Using `(thread-resume t1 t2)` would not prevent a GC of t1, but it
would create an intermediate record to make the link from t1 to t2,
and that intermediate record would leak due to a missing level of
indirection in a table-cleanup traveral. The leak not only accumulated
memory, it also caused ever slower traversals of the table in an
attempt to clean up.
(Since the leak is small and the leaking object is not directly
accessible, I don't have a good idea on how to test this repair
automatically, but see the program in the PR.)
Closes PR 15099.
Modern OS configurations likely use an even larger buffer size, and
making it small can have substantial negative performance effects
(e.g., with PostgreSQL over TCP).
When AC_PROG_CC picks GCC, move its selection of CFLAGS
into CPPFLAGS, so that preprocessing will have the same
optimization and debugging flags as compilation.
Arguably, AC_PROG_CC plus AC_PROG_CPP should do that
soemhow, but it's understandable that the autoconf
implementers didn't cover the possibility of
preprocessing that changes with the optimization level.
Closes#945
When `local-require` is used in a non-phase-0 position and it is
`expand`ed (as opposed to compiled directly), then the generated
`#%require` form had the wrong binding phase.
Merge to v6.2
In many use cases the length of the vector is fixed and know,
so we are sure that make-vector will not raise an error and
we can recognize these expressions as omittable and drop
them when the result is ignored.
The result of some procedures is a vector, but they are not omittable
because they may rise an error. With the recent changes of the
predicate reduction these cases are correctly handled.
The optimizer checks the type of the argument of some unary procedures and
uses the gathered information to replace them by the unsafe version, reduce
predicates and detect type errors. This extends the checks to more procedures
that have no unsafe version and procedures that have more than one argument.
Use the given readtable more consistently to parse
delimiters in the top-level form. This change particularly
addresses problems with trying to restore the original
`(` when parsing a hash table, but allowing nested
forms to still use a different `(` mapping.
When determing whether expressions can be reordered, a reference to a
module-defined variable was considered unreorderable when it is
known to have a value and no further mutation, but the value isn't
constant across all runs.
The optimizer had some reductions of predicates applications, like (pair? X),
only when X was very simple and the type of X was obvious.
Use expr_implies_predicate and make_discarding_sequence to allow
the reduction of more complex expressions.
Also, the reduction of procedure? and fixnum? were special cases in
optimize_application2. Move the checks to expr_implies_predicate
to take advantage of the reductions in more general cases.
Use `syntax-track-origin` and 'disappeared-use properties to
communicate `require` and `provide` form bindings to tools such as
Check Syntax.
Relevant to PR 13186
When a structure type has `prop:inpersonator-of`, follow it
when attemptng to access imperonator properties.
This change fixes a problem with `impersonate-procedure` as
reported by Scott Moore.
The compiler/expander attempted to clear out references in a namespace
used only during macro expansion, but it's possible for references to
be retained (via unusual macros), so get rid of the broken attempt to
help the GC.
Gustavo's tests in de3fa9a855 illustrate the problem. The solution
is simply passing 1 for `optimized_rator` to optimize_for_inline().
Additional changes generalize optimize_for_inline() a little (although
that generality doesn't seem to be useful at the moment) and collapse
some variables that represent the same value.
A new `--enable-ios=<sdk-path>` flag in combination with `--host=...`
sets up the right compiler options for compiling the Racket runtime
system as a framework to use in an iOS application.
I don't know whether the resulting framework actually works, but
compiling and linking is a step forward.
scheme_optimize_apply_values reduces (call-with-values gen proc)
to (#%apply-values proc gen) when recognizes proc as a procedure.
This extends the expressions that are recognized as procedures.
Instead of delaying the registration of some constants until a
group of expressions is re-optimized, add constant information as
it is discovered, which can expose some additional optimizations.
The old grouping was probably aimed at avoiding excessive code growth,
but I think that other and better controls are now in place. The
overall size of ".zo" files in an installation did not grow
significantly with this change.
Closes PR 14978
For detecting and debugging accidental dependencies on hash-table
order, it might be helpful to invert the order at the lowest level. To
do that, uncomment `#define REVERSE_HASH_TABLE_ORDER` in "hash.c".
The macro expander formerly put all lifted requires at the start of a
module, but that doesn't work with re-expansion if a module has
submodules and lifted requires that refer to submodules. Put lifted
submodules in the right place, instead: just before the form whose
expansion added the lifted require.
Racket wasn't reparsing correctly; the strategy worked ok
for links created by `mklink`, but not with other tools that
leave the "printed name" field blank.
A consequence of various fixes is that reparse points like
"My Documents" (in a typical configuration) correctly resolve
to actual paths like "Documents".
Finally, `directory-exists?` didn't handle root directories like
"C:/" correctly. The query would actually report properties of
the OS-level current working directory, and when junctions are
involved, the current directory can be a link instead of a directory.
Relevant to PR 14950 and PR 14912
Unlike `collapse-module-path`, it makes sense for
`collapse-module-path-index` to convert a relative module path index
to a plain module path. In other words, `collapse-module-path-index`
can convert a module path index to a module path.
Optimization can cause a `lambda` that was going to refer to a
top-level variable or syntax object to not refer to it after all.
Ideally, the prefix should be dropped from the closure, but
the change here is more conservative: it fixes the `lambda`s
annotation that's used by the GC to indicate that nothing will
be used from the prefix.
For GC purposes, if a "prefix" (a closure frame that caprues
top-level or module-level bindings) may refer to syntax objects
that are not used by any reachable closure, in which case the
syntax object can be dropped. This pruning of syntax objects
uses the infrastructure already in place to prune variables.
Syntax objects were not included in the original pruning
implementation, because they are unlikely to create
finalization cycles in the way that global-variable
references can. A syntax object can retain a namespace's
table of module imports, however, which can be substantial
and worth releasing of a closure is only held, say, for
a low-level finalization action.
Although names were cleared correctly, the trie used for
the mapping was not pruned correctly, so lots of empty
branches could accumulate (especially in 64-bit mode).
Even when `(variable-reference-constant? (#%variable-reference ....))`
cannot be optimized to a boolean, the expression should not retain a
reference to the enclosing namespace. That space guarantee is
important for the compilation of calls to keyword-accepting functions.
The handling of `for-template` imports by `namespace-attach-module`
didn't match the docs. The actual handling was to refrain from
attaching instances of a phase-0 module if the instance was reachable
only through a `for-template`. The rationale had to do with such
modules instances being created only through instantiation of
phase-1 modules, and phase-1 module instances aren't attached;
it doesn't work well that way, though, when different modules
are attached with intervening `namespace-require`s on the target
namespace.
The change includes a documentation correction. Previously and still,
only modules at the same phase as the attached module (as opposed to
the same phase or less) are instantiated in the target namespace.
Closes PR 14938
If a file or directory delete fails, try adjusting the file or directory
permissions to allow writes, then try deleting again. This process should
provide a more Unix-like experience and make programs behave more
consistently.
A new `current-force-delete-permissions` parameter provides access to
the raw native behavior.
Check for an empty path after dropping `"`s, instead of before.
Otherwise, a bad PATH setting interferes with functions like
`find-executable-path`, which in turn can prevent DrRacket from
starting up.
Closes PR 14930
If the slow path has to be taken because the number of
list elements is greater than the stack size, then the
old implementation would copy all the arguments --- which
still might be too much for the available stack space.
Avoid that copy.
Also, add pad word to the end of the stack to help detect
overflow.
For example, reduce (begin x (error 'e) y) ==> (begin x (error 'e)) and
(f (error 'e) y ) ==> (begin f (error 'e)).
Also, reduce (if (error 'e) x y) ==> (error 'e) and propagate the type information
and clocks when only one branch produce an error.
- Modify the features used by OpenBSD (not everything was
tested). Mostly copied from Linux, FreeBSD and NetBSD.
- Add support for Bitrig, a fork of OpenBSD. Eventually
they will differ more and more from OpenBSD.
- Typos and extra trailing spaces.
- Update config.guess and config.sub from GNU.
The implementation of caching stack-trace information in the
stack didn't work right in libunwind mode, with the result that
`(current-continuatiom-marks)` took O(N) time for a continuation
of size N, when it should be amortized constant time.
A value-printing truncation discovered after a stack-overflow handle
and return could go badly, because the truncation escape wasn't
reset correctly after overflow handling (in contrast to truncation
discovered during the overflow handling, which was handled correctly).
Closes PR 14870
Since `begin0` at the bytecode level always evaluates an initial
expression in non-tail position, we don't have to work so hard
to ensure that an extra expression sticks around.
Move begin0 inside begin, for example
(begin0 (begin X Y) Z) ==> (begin X (begin0 Y Z))
Try to replace more begin0 with begin when the first expression is movable
Drop the begin0 when it has only one non omitable expression that preserves
the continuation marks.
The source to the split packages is in repositories under the
`racket` organization on GitHub. The repositories are all named
according to the pkg name, except for multiple-package
repositories such as `racket/compiler` which is named based on the
old directory name without the `-pkgs` suffix. Thus
`pkgs/compiler-pkgs` -> https://github.com/racket/compiler
The Makefile has also been adjusted to pull packages from the
catalog when you type `make`. This currently relies on some tricks
that will break if you try to specify a particular set of `PKGS` on
the command line. We plan to improve this soon.
The packages in `pkgs/racket-pkgs` and `pkgs/base` are staying in
the repository, since they logically belong with the core code.
The `plt-services` package is still in the repository, but will
move out soon.
The optimizer converts (car (cons X Y)) to (begin0 X Y) and then reduces
it to (begin Y X) if X is movable.
Check that the movement is safe for space and for continuation captures.
When continuation C2 extends continuation C1, C2 shares the copy
of the internal stack with C1. It needs to skip the bit of
C1's stack that corresponds to arguments to `call/cc`, though.
That skipping assumed that `call/cc` takes 1 argument, but it can
take 2. The bug broke `racklog`, which captures continuations using
its own prompt. (It seems like there should be a simple test that
is independent of Racklog, but I couldn't construct it.)
Meanwhile, the continuation shouldn't retain the arguments to
`call/cc`, so clear them. (That was easy to test.) Sharing still
has to compensate for the locations of the arguments, though.
Fix the "self" argument propagation through an impersonator that has
no redirection function (but that probably has impersonator
properties).
Closes PR 14852
The new variants pass a "self" argument to the wrapper procedure in
the same way that `{impersonate,chaperone}-struct` provides a "self"
argument to redirection procedures.
A large message that hasn't been delivered can trigger a inter-place
GC. The intent is to force a GC to avoid messages piling up that can
never be delivered, but the GC didn't adjust to a state where messages
stay both undelivered and uncollected, and it would continuosly
trigger GCs. Trigger a GC only if the pending-message size has grown
relative to the previous GC.
Some expression movements are limited by the possibility of retaining
a value in a way that interacts with space safety, but primitives that
return immediately shouldn't get in the way of those movements.
When a variable X is bound to an expression that implies properties of
other bindings, and if X is used only once and can be replaced by
its value expression, then further optimization of that expression must
not assume the properties that are established by evaluating the
expression.
Also, don't move expressions past unsafe operations, since the expression
might implicitly guard against unsafety.
Closes PR 14819