For now, the operation is implemented on mutable tables in Chez
using a combination of hashtable-contains? and hashtable-cell.
A more efficient version will require modifying Chez.
Compute the list (at compile time), instead of using a literal copy of
the output at one point.
Also, adjust the documentation to explain extra guarantees provided by
`make-known-char-range-list`.
Closes#2757
Using GC_free() on runstacks was a way of reducing leaks with
conservative GC, but the implementation of prompts for delimited
continuations evolved in a way that is incompatible with using
GC_free(). The recent change to make certain runstack links weak
particularly exposed the mismatch.
Fixes#2748
Steps to create this certificate:
openssl genrsa -out key.pem 2048
openssl req -new -sha256 -key key.pem -out csr.csr
openssl req -x509 -sha256 -key key.pem -days 3650 -in csr.csr -out certificate.pem
cat key.pem certificate.pem > test.pem
When filling out the information for the certificate, keep the same
details - some tests depend on it.
Bring CGC and 3m in line by breaking weak links in CGC only after
ready level-1 finalizations (which correspond to will executors) have
been queued. The chage delays clearing of the weak link until after
the finalizer is run.
by `contract-out` instead of `->`
This seems to save about a second of startup time in (non-cs) DrRacket
and about .1 seconds in drracketcs.
The code is also theoretically more easily inlined. Still not easy enough, however.
In a pattern like
(let loop ([l l])
(define v (syntax-e l))
(cond
[(null? v) 'done]
[else
(loop (datum->syntax #f (cdr v)))]))
the running time was O(N^2) for a list of syntax objects of length N.
That pattern is relevant for traversals that use `syntax-case` like
(let loop ([l l])
(syntax-case l ()
[(a . b) (loop #'b)]
[() 'done]))
Avoid bad behavior by recording in an weak hash table certain pairs
that were previously been produced by `datum->syntax` internally so
that they can be used as-is.
Mainly for cross-compilation with a Windows target, the Racket CS
build process may need to run `lz4` as an external program. In that
case, complain when `lz4` isn't found, instead of letting `system*`
complain about getting `#f`.
Change the condition for filtering leaf contracts via `eq?`.
Before, we looked for flat or chaperone contracts.
After, look for flat or trusted contracts. So:
1. untrusted chaperones with side effects that are unsafe to drop are not
dropped, and
2. impersonator contracts can now be dropped (object/c, recursive-contract)
When compiling with -Werror (./configure CFLAGS="-Werror" ...),
the test to see if mbsrtowcs exists
failed with pointer type of incompatible type, is char **, should be
const char **. It would proceed to assume mbsrtowcs didn't exist.
Ensures proper noreturn annotations for error functions. Implemented
cross-platform unreachable annotation. No warnings in tested clang or
gcc with default flags. Tested as well on MacOS and Windows.
The schemify pass collects known-value information as the first step
of processing a linklet body, but the main pass to process the linklet
body may simplify it in a way that exposes new information. For
example, in
(define (call) (values 1 2))
(define-values (x y) (call))
the main pass will inline `call` and expose the fact that `x` and `y`
are always 1 and 2, respectively.
Adjust schemify to inspect the simplified form of a definition and
potentially add new information to known-value information, which is
useful later in the ame linklet body and also as cross-module
information.
Like other optimizations that schemify duplicates, constant folding
helps support cross-module optimization. Related "no-prompt"
declarations for primitives can reduce `call-with-module-prompt`s in
schemified output, too, which can interfere with Chez Scheme's
optimizer.
This is probably related to #2712.
It's the only occurrence of SCHEME_NO_EXN pointing to the fact that
this is an historical artifact that can be removed.
Recognize `(define-values (id ...) (values rhs ...))` and split to
multiple `define`s after simplifying the right-hand side of
`define-values`. Also, don't split if a define variable is referenced
too early.
Adding return statement where it doesn't exist, causes problems with
functions marked no return so it should be avoided.
Related to #2709 - with this PR, clang won't complain any longer
about issues with xform generated sources about functions marked
no return that do indeed return.
When `set!` is used to tie a recursove knot in a flattened linklet,
the expander can recognize that pattern and not complain that a
mutable variable might be shared across places. Improving that
inference means fewer `++global-ok` flags in Makefiles.
This commit also avoids single-quote as an escaping form in a
makefile, which doesn't work with nmake on Windows.
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.