Continue to build the bundled-with-Chez zlib and lz4 by default, but
support `--enable-libz` and `--enable-liblz4`, and turn those on when
the Chez Scheme directory doesn't have bundled versions. That should
make things build right for distributions where repackaging
dependencies is disallowed or discouraged.
The Chez Scheme build process now create an archive instead of linking
"kernel.o". Adjust the Racket CS build to use archives instead of
"kernel.o".
Also, modernize the Racket build's use of `ar`. Using the flags `rc` by
default (instead of `ruv`) should avoid the need for `nicear`.
If GUN ar is configured for deterministic mode by default, then
ar: `u' modifier ignored since `D' is the default (see `U')
prints. Suppress that to avoid stderr output.
Checking for directories when searching for a collection can be
especially slow with the Windows filesystem, but Windows also supports
filesystem-change events. So, cache information about the existence of
paths, relying on filesystem-change events to detect with the cache is
out of date.
Related to racket/drracket#281
The prompt installed for an escape continuation or continuation
barrier is never used to delimit a captured continuation, so the
return from the continuatiton can be streamlined slightly.
The benefit is very small (but detectable in the macro expander's use
of barriers). There's an opportunity to use `call/1cc` instead of
`call/cc`, but that change does seem to help --- neither Chez Scheme's
current `call/1cc` nor the opportunistic variant of `call/cc` use to
implement continuation attachments.
Reducing external-event polling exposed a problem with fd semaphore
checking, where the check before sleeping didn't abandon the sleep if
an fd semaphore was posted.
Also, fix a bug with interrupted network address lookup.
Improvements include:
- less scattered handling of constant templates
- better recognition of constant templates, like (1 (... 2)), where
the template syntax is not identical to its value
- better code for (x ... ...), where x is trusted
When reading from an input fd blocks, instead of creating a general
event that creates a semaphore, use the semaphore directly (when
available). Also, treat a semaphore internally as an event that
always produces 0.
This change speeds up the "echo" shootout benchmark.
This change speeds up the "echo" shootout benchmark.
When the schemify pass cannot determine that a call is to a primitive
procedure, it generates an `#%app` form that expands to
((extract-procedure rator) rand ...)
Force `extract-procedure` to be inlined (by making it a macro), so the
expansion is
(let ([tmp rator])
((if (#%procedure? tmp) tmp (slow-extract-procedure tmp)) rand ...))
which is usefully faster in the common case that `rator` turns out to
be a primitive procedure.
Chez Scheme doesn't provide `eq-hash-code`, so it's implemented with a
weak `eq?`-based hash table that maps values to fixnums (except for
numbers, symbols, and characters). The table had a lock to support
concurrent use in multiple places, and that became a major source of
contention in parallel builds. Change the implementation to use a new
`eq-hashtable-try-atomic-cell` operation, which effectively moves
contention from the hash table to individual buckets (where it should
be much rarer).
Commit fe708871bd broke cross-module inlining for modules that are
compiled in different Racket processes. The problem is that
cross-module information is represented by prefab structures, and the
change caused Chez Scheme's fasl for prefabs to generate a different
structure type on different runs.
To solve the problem, use `racket/fasl` for cross-module information,
instead. But cross-module information also has inlining information as
correlated objects, so make those supported by `racket/fasl`, too.
The first time a struct is provided through `(contract-out (struct id ....))`,
save `id` to access its transformer binding later.
On reprovides:
- hang on to the original `id`
- use its transformer to recover the original predicate/accessor/mutator names
Also, fix a bug where the order of the mutator ids reported by the
struct info was getting reversed
Probably, nobody noticed that bug. They'd have to work around the renaming
issue in #2572 first.
The default module name resolver uses a cache to map module names to
resolved-path information. The cache was weak in a way that turns out
to be much weaker on Racket CS, essentially because Chez Scheme is
tuned to fire a minor GC more frequently.
The new cache cuts 45 minutes(!) from a 2h15m single-process
distribution build of Racket CS on Linux. That brings it under a factor
of 1.5 of the non-CS build time, instead of over a factor of 2.
Thanks to Caner and Sam for pointing out LONG ago (maybe a year ago)
that the cache works badly for Pycket. Since the cache doesn't make a
big difference for `racketcs -cl racket`, though, it took me this long
to understand that it can be such a big deal for Racket CS when
performing a distribution build.
Help avoid problems with serialization by making the generation of
embedded module symbolic names deterministic and relatively
insensitive to module order. The generated name is based on a
combination of `path->module-path` and paths relative to the
main module of the executable.
Related to #2693
The total time of module name resolver calls is more useful, because
each one takes longer, there should be many fewer, and there are
tasks that end up resolving module paths.
When support for machine-independent bytecode was added, the bootstrap
implementation of linklets ended up being slightly uncooperative.
Source terms from the bootstrap became wrapped as machine-independent
form. For various reasons, things worked anyway, except that
`--linklets` mode prints bytecode instead of S-expressions. Fix the
bootstrap implementation to cooperate correctly.
Related to #2688
Don't discard expressions that will fail due to trying to make a
prefab struct type from a parent that isn't a prefab. Similarly, don't
discard a `make-struct-type` with a built-in property that has a
guard. Don't discard a `make-struct-type-property` with a literal
guard procedure that has the wrong arity.
Related to #2685
Adjust the makefile that ends up in <builddir> with `--enable-cs` or
`--enable-csdefault` (as opposed to `--enable-csonly`) so that `make
racketcs` doesn't imply `make racket3m` if `--enable-racket` has
supplied an existing Racket.
Also fix `make install-cs` related to GRacket for the case that Racket
3m/CGC isn't built.
Relevant to #2683
While a continuation is set up to avoid retaining runstacks, partly by
storing a prompt ID instead of a prompt record, prompt records can
remain on the C stack and get captured anyway. Mitigate that problem
by making the runstack link weak in some prompt record.
Racket CS doesn't have this problem, of course.
Relevant to jeapostrophe/lux#10
Add `single-flonum-available?` and `read-single-flonum`, where the
latter controls whether numbers that have an "s" or "f" exponent
marker are parsed as single-flonums are normal flonums. The parameter
is disabled by default, which changes the meaning of most existing
code that has a literal number with "s" or "f", including `+inf.f`,
`inf.f`, and `+nan.f`.
The compiler constant-folds `single-flonum-available?` and
`real->single-flonum` on a literal number, so use a combination of
those to replace most uses of a single-flonum literal. Single-flonums
within quoted data are less convenient.
After the change that makes printing of struct ignore print-pair-curly-braces
it is possible to simplify the code in io/print and the associated tests.
For traditional Racket, fix `bytes-utf-8-index` to accept 5 arguments
as documented. For Racket CS, fix `bytes-utf-8-index` to return an
index relative to the byte string's start.
Closes#2670
When `print-pair-curly-braces` is true, change the built-in printer to
not use curly braces to group a constructor with its argument.
Restrict its effect to quoted lists, which is more what you expect and
more consistent with `pretty-print`.
Also, change `pretty-print` to not use `{` when using the `list`,
`list*`, `cons`, or `mcons` constructors.
Closes#2662
On case-sensitive filesystems on macOS, these are
distinct (leads to a file not found error). On
case-insensitive systems, the change should not matter.
These changes are intended to address "input port is closed" errors
that have been showing up with Racket CS, possibly because its
scheduler exposed missing synchronization.
Instead of having schemify generate `letrec*` and convert as needed
through a Chez Scheme macro, have schemify perform any necessary
conversion to get the right use-before-definition error messages and
`call/cc` interaction.
This change improves the conversion, since schemify has more
information about bindings, but it also avoids sending Racket terms
through a macro-generating macro at the Chez Scheme level. Avoiding
the macro-generating macro avoids a kind of leak in Chez Scheme, where
a gensym used in a template may become ineligible for GC due to the
way `free-id=?` may both reify the gensym's unique name and attach a
property to the gensym.
Using a will executor to turn a reference from weak to strong still
seems like an ok idea, but it needs to be a regular will executor,
because a custodian-registered value is likely to involve have a
nested self-reference.
More generally, repair the internal `exe-relative-path->complete-path`
function to work when the current directory is not the original
current directory and `racket` is started with a relative path.
Currently, it happens that `exe-relative-path->complete-path` is
called with a potentially different directory only by
`get-lib-search-dirs`.
When the compression format changed to LZ4, which is much faster to
decompress than zlib, the configure script changed to enable
compression by default. Bytecode tends to benefit all around from
compression, but the boot files take 20ms or so longer to load --- not
a lot of time when loading typical amounts of code, but a signficiant
cost for a minimal startup. This commit allows compression to be
controlled separately for boot files, and it configures them as
uncompressed by default.
* Remove irrelevant #ifdefs MZ_USE_JIT
Bonus points - fixes a compiler warning on aarch64 and a typo.
* Fixes a compiler warning on aarch64 for unused current_linklet_native_lambdas
* Simplify conditionals after removing dead store of has_space
The conditional simplification looks good to me. The biggest issue
here was to understand if when `pipe_quote` is true, we can and should
go to the else clause. Actually the more I look at it the more I think
this uncovers and earlier bug where if pipe_quote is true, result and
total_length are left at NULL and 0 respectively after the block.
Change `datum->syntax` so that it limits the transfer of a code
inspector from a source syntax object; the code inspector is kept only
if a macro is being expanded and the macro has the same code inspector
(or, more generally, the weaker of the two code inspectors is
preserved).
This change is a kind of defense-in-depth to prevent the use of
unarmed syntax with `datum->syntax` to access unexported bindings from
the module where a syntax object originates.
The general approach is Ryan's idea. This particular implementation is
a simplification of the general idea, and we'll see whether it's
worakble and sufficient.
The changes in aab63ad3 introduced a dependency on
racket/private/promise, which the analysis was not capable of dropping
due to the use of the `prop:force` property. This caused trouble for the
thread layer, since it introduced a reference to `error`, which is
defined in the io layer. This change adds some additional detection for
struct type properties with guards that accept procedures of particular
arities, which allows `prop:force` to be marked as pure.
Also, a typo in the thread layer’s Makefile meant globals weren’t
actually getting tracked, so this fixes that, too.
`for/fold` is a left fold, which is normally what you want in a
call-by-value language such as Racket, but it makes efficient lazy
iteration difficult. This commit adds a new `for/foldr` iteration form
(along with `for*/` and `/derived` variants) that provides a right fold
operation that offers complete control over precisely how lazy the
iteration ought to be.
In simple microbenchmarks, reimplementing `for/stream` to use
`for/foldr` instead of `for` plus a generator can be almost 40x faster
on large streams.
When `read/recursive` is used, do not inherit parameter values
recorded by an enclosing `read`, and instead look them up again.
This change restores behavior of the old reader.
Closes#2661
When ">" appears in a procedure name, or when other characters appear
that would normally need to be escaped in a symbol, don't add escapes
since `#<....>` isn't readable anyway. This change makes renamed
procedures print in a consistent way with primitive procedures.
Similarly adjust the printing of structure type names.
Closes#2646
Closes#2659 by both recognizing `lib64` as a default path and by
having `--enable-origtree` override inference and specified when
running `configure` through the root makefile.
Swapping the blame before adding #:important context associates the
important party with the negative party for the purposes of picking
“contract violation” versus “broke its own contract” messages in error
reporting. Therefore, only swap after adding the context.
fixes#2531
Instead of limiting the nursery size and performing a full GC every
time a small nursery is full, allow the nursery to be proportional
to the total heap size if generational GC is disabled.
This option allows the user to enable or disable (with
--disable-generations or --enable-generations=no) generations in
3m. Disabling generational collection is, in most cases, a bad
idea, but it may be necessary on a platform where signal handling
doesn't work well enough to support a write barrier that is
implemented with page protection.
Ignore new autoconf variable added in 2.70.
The interesting thing is that debian decided to backport this variable
to their 2.69 release so in some 2.69 autoconf this variable does not
exist but in debian ports 2.69 generates this variable. It is
nonetheless not useful for Racket, so add to ignore list.
When using a built-for-bootstrapping Racket to build Racket CS, the
intermediate module loading module mode should be `--boot` instead of
`--chain`. The repo's top-level makefile takes care of that already,
but not `configure`-generated makefiles as may happen in a build from
a source distribution.
Allows an inaccessible custodian to be GCed, promoting any values that
it manages to its parent custodian. Also repair memory accounting for
custodian boxes.
For values referenced by a custodian, the nature of the custodian's
weak references is slightly different on Racket CS. The reference is
weak enough that the value can be finalized via will (e.g., to close
an unused port), but it's not weak enough to allow weak boxes, weak
hash table keys, or ephemeron keys to be cleared. That's a consequence
of using ordered finalization instead of finalization/weakness levels.
This difference could be avoided at the cost of an extra wrapper for
any finalized value and a discipline of using such wrappers as the
user-visible reference for all custodian-managed values, but semi-weak
references so far appear to be practical and a better compromise.
The use of a will executor for a custodian is a bit of a hack, and it
doesn't want the "keep live until executed" constraint. So, add an
optional internally.
If a late will executor has pending will, then it needs to stay
live until the enclosing place has terminated (and post-custodian
callbacks are run). Otherwise, `ffi/unsafe/alloc` can lose values
that it expects to finalize, and it reports an "internal error".
The late will executor for `register-finalizer` from `ffi/unsafe`
was kept live in traditional Racket, but only as an accident of
custodian shutdown in a terminating place: the shutdown process skips
threads, since that work is technically not necessary. Relying on that
coincidence is asking for trouble, though, so implement retention more
deliberately.
Recognize `(ptr-ref <ptr> _uint8)`, etc., and turn it into a more
direct `(ptr-ref/uint8 <ptr>)`, etc. This improvement speeds PNG
loading by a factor of 10 to 20, for example, because the
implementation expects the pattern to be recognized.
When the number of places approaches the number of available
processing cores, then a spin lock isn't good enough for a small
number of contended hash tables (maybe just one of them). When
contention is discovered, fall back to a mutex-based lock.
When spawning a new subprocess, it's possible that one or more of the
new process's standard input, output, or error descriptors use file
descriptor 0, 1, or 2, even if they don't correspond to any of the
parent process's original standard input, output, or error descriptors.
This can happen if the parent process closes one of its standard
descriptors, and the operating system reuses the file descriptor number
for a new descriptor.
Therefore, be more careful about closing and copying file descriptors in
the child process before calling `exec`. Specifically, move file
descriptors out of the way as needed so they aren't clobbered, and
accommodate cases where multiple standard streams may share the same
file descriptor in the parent process.
fixes#2634
A subcustodian was incorrectly registered as weak for its parent,
which means that an unreferenced custodian could get lost when
shutting down an ancestor.
Register the port, not the file descriptor, especially since a TCP
connection can have ports that share a file descriptor. Also, I think
a weak reference in the custodian doesn't work as intended (visible
through finalization) if the file descriptor is referenced with a
callback that closes over the port.
No `syntax-protect` is needed for `define/private`, etc., because no
new identifiers or expressions are introduced. Adding extra dye packs
can interfere with other macros that pull apart syntax (although maybe
the macros shouldn't do that without using `syntax-disarm`).
A custodian doesn't provide any order on shutting down the objects
that it manages (I was confused about some past experiments), so
avoid that assumption.
Getting the current CPU time is relatively expensive, so get it only
on thread swaps where a thread used its full quantum or 1/100 swaps
otherwise. This approximation should work because thread-specific CPU
times are rarely requested, and they make the most sense for threads
that don't constantly swap out due to synchronization.
Formerly, an expression like `(arity-at-least-value 7)` could crash,
because the `arity-at-least-value` accessor is created in unsafe mode,
and the slow path to accessor errors attempted to use the accessor to
provoke an error message. Instead of using a potentially unsafe
accessor, have the slow path raise an error explicitly with
`raise-argument-arror`. That change has the added benefit of making
error messages mach traditional Racket (at least for structure types
that are not declared as "authentic").
The problem was exposed by tests added in 55dcdf5538.
Instead of a separate hash table mapping continuations to
linklet-instance names, use a continuation mark. That's faster,
because capturing a continuation means copying part of it on continue.
Currently, Check Syntax has trouble correlating `require` forms and
references to imports that go through a macro-introduced rename
transformer. For example, there's no binding arrow from the final
`starting` to the `racket/list` in
#lang racket/base
(require (for-syntax racket/base))
(define-syntax-rule (define-as-first mod starting)
(begin
(require (only-in mod
[first initial]))
(define-syntax starting (make-rename-transformer #'initial))
starting))
(define-as-first racket/list starting)
starting
But change the last two `starting`s to `initial`, and the binding
arrows work.
Until a general repair is in place for Check Syntax, this commit
adjusts 38d612dba6 to use the original export name for an immediate
binding, which acts as a hint to the current Check Syntax
implemenration.
Note that the source-distribution client must have a
"build/ChezScheme" checkout created, maybe by building as a 'cs
variant. A pruned version of that checkout is then included with other
sources. The resulting source distributon then works for building
either Racket variant.
Adapt the configure scripts and makefiles to use a "ChezScheme"
directory that is bundled with sources.
Some expressions like (date-day) gave usually an arity error, but when they
were inlined by the JIT the arity check was wrong, so they produce a segfault
or a nonsensical result.
Provide a way to build Chez Scheme from source using Racket. In the
short run, this lets us distribute source that ultimately depends only
on a C compiler (since a variant of Racket can be built from source
using just a C compiler).
- change an 'an' to 'a'
- remove 'immutable' where expecting either mutable or immutable (don't
bother to specify which, because `vector-common.rkt` doesn't bother)
- remove extra ','
The `poll` system call doesn't work right for fifos, so switch
back to `select`, but use a new strategy to size fd_set buffers
instead of trying to use `getdtablesize` (because the result
of `getdtablesize` can change dynamically on Mac OS).
Also, add a check for input at the rktio level when trying to read
from devices other than regular files. Otherwise, Racket CS (which
doesn't have some redundant polling that is in traditional Racket)
sees spurious EOFs for unconnected fifos.
Closes#2577
* Remove value store in ready_pos but unread
* Move declaration of ready_pos to where it is used
* Make discard of return value of tcp_check_accept explicit
* Split declaration and var assignment to comply with xform
Making `equal?` do the right thing on classes turned out to be easy---it
just involved adding a straightforward `prop:equal+hash` property to the
`class` struct—but making it work properly for *objects* was the tricky
part. The trouble is that `equal?` on objects that don’t implement the
`equal<%>` interface is just ordinary structure equality, which can be
relevant if objects are inspectable. Writing `(inspect #f)` in a class
body is like making a struct `#:transparent`, and it has all the same
ramifications for equality.
The trouble is that `class/c` creates new wrapper classes, and every
class has its own struct type. Since the default behavior of `equal?` on
structs is to *never* be equal to structs of different types, even
subtypes, an object created from a contracted class can never be
`equal?` to an object created from the same class without contracts.
The solution is to add a `prop:equal+hash` property to `object%` itself
that emulates the default behavior of `equal?`, but sees through class
contract wrappers. Since struct type properties are inherited by
subtypes, this property will be present on all objects, and it only
needs to be attached once.
fixes#2279
Mainly, this improves `make-keyword-procedure`: when applied to a single
argument, it now uses `procedure-rename` to ensure the resulting
procedure has the appropriate name. A couple other changes also guard
against the case where a lambda expression has no inferred name and no
source locations information, which would lead to the source locations
in the implementation being used, instead.