Repair problems with asynchronous callbacks for futures and for
foreign callbacks. Asynchronous callbacks are used for future "sync"
operations, like `hash-set!`, that run must in a place's main thread
(as of commit f574583907).
Separately, synchronization to clean up future threads used a `ping?`
flag in a backwards sense, and it also treated a record as a box.
These problems could cause place termination to hang.
Related to #2725
The `math` library relies on this working right, since MPFR is
normally not compiled as thread-safe.
Also, fix some locking/interrupt/atomicity problems with async
callbacks generally.
When `sync` or `place-channel-get` is used on a place channel whose
other end has been GCed, then the blocking thread should also be
GCable. The `sync` case didn't work because the implementation uses
`replace-evt`. Change `sync` so that it can recognize asynchronous
`replace-evt`s in the same way as semaphores and channels (which is
more than traditional Racket offers).
When a place terminates, it was directly accessing its parent's
custodian. Prior support for cross-place uses of a hash table
probably helped hide this problem previously.
Although extremely unlikely, it was possible for multiple Racket
threads operating on the same scopes to race on a multi-scope's table
mapping phase levels to scopes.
Also, for some some mutable hash tables that will be shared across
places as read-only in Racket CS, make sure they are definitely set up
for iteration.
An `eq?`-based hash table in the implementation of custodians was
still shared across threads.
Also, taking the global lock at the Rumble level did not disable
interrupts. Since sometimes the lock is taken with interrupts
disabled, threads could potentially deadlock by not having an order.
Fix the problem by disabling interrupts before taking the lock.
Use the pseudo-random generator API that is now available from Chez
Scheme. While the generator can be written in Scheme, the lack of
unboxed floating-point arithmetic unfortunately makes it about 6 times
as slow as a built-in implementation. That difference is significant
when `sync` uses `random` for fair scheduling.
The `time-apply` function was measuring thread time instead of proecss
time. While thread time would be more useful in many cases, it's meant
to report process time.
Mutable `eq?`- and `eqv?`-based hash tables were formerly guarded by a
lock that made them safe for Scheme threads (i.e., OS-level threads).
In particular, that futures could concurrently access hash tables. But
the cost of that lock appears to be too high for such a rarely-used
capability.
Switching `eq?`- and `eqv?`-based hash tables so that they're safe
only for Racket threads means that the lock on a hash table can be
much cheaper. A lock is still needed to because the Rumble layer adds
extra fields for iteration. In the specific case of `hash-ref` on
`eq?`-based tables, however, the lock can be ignored, which makes one
of the most common `hash-ref`s much faster.
Overall, `hash-ref` on a mutable `eq?`-based hash table is now 4-5
times as fast, which makes it about twice as fast as traditional
Racket's `hash-ref`. A `hash-set!` operation is about twice as fast as
before, which puts it on par with traditional Rackets `hash-set!`. The
`hash-ref` improvement makes `send` about twice as fast as before in
Racket CS, making it a little faster than traditional Racket.
Since futures can no longer concurrently access `eq?`- and
`eqv?`-based hash tables, they have to synchronize with the main
thread for access. Racket CS had avoided the "sync" action on futures
that traditional Racket sometimes uses, but this change introduces
sync actions to Racket CS, since it's appropriate for accessing
mutable `eq?`- and `eqv?`-based hash tables.
Adjust the internal engine protocol to avoid a jump from a starting
engine (representing a thread) to a scheduler outside of an engine
to a target engine (for a swapped-ni thread); instead, jump from the
first engine to the target, effectively running the scheduler within
the starting engine's context.
In a file-stream output port or TCP output port, when flushing
encounters an error, consistently discard bytes in the buffer. This
isn't the obviously right choice, but otherwise a future flush attempt
(including one triggered by trying to close the port or one triggered
by a plumber) will likely just fail again, which is probably worse
than dropping bytes.
Also, fix related problems/inconsistencies.
Overall changes:
* For traditional Racket, discard bytes in a TCP port when flushing
fails.
* For Racket CS, discard bytes in file-stream and TCP output ports
when flushing fails.
* For traditional Racket, when a file-stream port flush is
interrupted by an asynchronous break, *don't* discard buffered
bytes.
* For Racket CS, don't register TCP ports with the current plumber.
When the original compiler handler is called with a true second
argument, then the resulting module is not serializable. Improve
detecting and reporting of the misuse.
The error is phrase in terms of linklets, which is not ideal, but
that's the level where the error can be detected. Abusing the original
compile handler in this way is not easy, though, so maybe this
improvement is enough.
Adds an additional line to the error message that is raised when a
required module provides a binding that is already provided by another
required module. The additional line displays the name of the first
module that provides the binding.
The error before this change:
tmp/c.rkt:4:9: module: identifier already required
at: x
in: "b.rkt"
location...:
tmp/c.rkt:4:9
and after:
tmp/c.rkt:4:9: module: identifier already required
at: x
in: "b.rkt"
also provided by: "a.rkt"
location...:
tmp/c.rkt:4:9
Add text of MIT and Apache v2 licenses.
Add initial CONTRIBUTING.md file which specifies contribution license.
Add COPYRIGHT.txt file which specifies the license and lists some
external components.
The LGPL license stays in its current location to avoid having to
modify the build right now.
The Mac OS 10.15 headers include a `#pragma` just before the closing
`;` of a `struct` declaration. That confuses poor xform. Handle this
special case by detecting it and swapping the order of the `#pragma`
and `;`.
If a source file name lacks an extension, then the pkg-step would get
confused trying to convert a ".zo" name back to a source name. The
original name is not really needed, anyway.
When a reference to a local variable is updated with the scopes of its
binding in a fully expanded program, remove the syntax-original
property if the original reference had macro-intrudction scopes.
Closes#2820
Trying to be more helpful about the thread running an `unsafe-poller`
callback gets in the way of making the process sleep when multiple
threads are blocked on unsafe pollers.
Closes#2833
Prune some `with-continuation-marks` forms that aren't observable
(because the body is simple enough that it won't inspect marks). More
significantly, specialize `with-continuation-marks` forms to indicate
when the current frame is known to have no marks and to indicate
when tthe key expression is known to produce a non-impersonator.
Since `#%app` (used where an applicable structure might show up)
injects its own `procedure?` test and makes sure that that a procedure
is returned to the function position of the application, use `#3%$app`
to make Chez Scheme suppress a redundant `procedure?` check for the
appliction.
It's not clear that a thread can be descheduled without the current
thread's work counting as progress, but a descheduled thread certainly
shouldn't coun as a no-progress scheduled thread.
Only one instance of each callback is needed. Allowing them to pile up
is inefficient, and possibly it can trigger a reaction that causes
even more to pile up.
(for ([x (in-value 1 2)]) x)
should raises a run time error, not a syntax error.
Fix similar error in other in-something macros.
Fix name of in-directory, when used as a function outside a for.
Unfortunately, MZ_NORETURN spec is causing a few problems - see #2808
It would be great to fix these but due to lack of time, this is a
workaround that should keep things working until all supported
configurations accept MZ_NORETURN properly.
Use `call-consuming-continuation-attachment` to implement
`with-continuation-marks`, because that avoids duplicating
a set of checks when in tail position.
Looking at `bytes-allocated` usually works, but sometimes lets
memory use spiral out of control. Looking at `current-memory-bytes`
is more reliable, but still makes peak memoy use too high.
Combining those values doesn't limit the peak well enough.
Try the more obvious (in retrospect) approach of comparing
`bytes-allocated` changes and `current-memory-bytes` changes
separately, and triggering a GC if either grows enough.
Commit 1811193285 caused Racket CS to have much higher peak memory
use. Adjust the heuristic again to trigger a major GC when the
`current-memory-bytes` value is the post-GC `bytes-allocated` plus the
post-GC `current-memory-bytes`, which means waiting until
another `bytes-allocated` bytes are allocated (instead of waiting
until the number of newly allocated bytes also catches up to overhead,
such as unserused pages due to locked objects).
Implement a parameter as a Chez Scheme wrapper procedure,
instead of an applicable record. A wrapper procedure can be
applied more directly, saving 10-20% of the time for some
parameter lookups.
The grammar for pregexps includes:
| \p{‹property›} Match (UTF-8 encoded) in ‹property›
| \P{‹property›} Match (UTF-8 encoded) not in ‹property›
and <property> is defined as:
‹property› ::= ‹category› Includes all characters in ‹category›
| ^‹category› Includes all characters not in ‹category›
That is to say, there are two independent ways to negate one of
these character classes. The Racket implementation of regexps
(as opposed to the C implementation) does not recognize negated
categories. This PR fixes that.
Some parts of the GC meant to traverse all objects on a page of
'atomic-interior or 'interior objects used "<" to detect the end of
the page, but "<=" was needed. As a result, things could sometimes go
wrong for the last object on a page for platform and size combinations
where the last object ends exactly at the end of the page.
This change consistenly computes the iteration end in a way that makes
both "<" and "<=" work.
Using MPFR bindings from the `math` library could trigger a problem
(but it's difficult to provoke the problem in a reasonably small
example --- difficult enough that I couldn't do it).
Use `current-memory-bytes` instead of `bytes-allocated` to determine
major GCs, because the latter doesn't include enough (perhaps missing
finalized values). For example, the repair avoids unbounded memory use
from
(let loop ([i 0])
(malloc 6400 'atomic-interior)
(loop))
due to finalizers that pile up faster than they are run.
When a linklet is too large to pass to Chez Scheme whole, then
names for the procedures that are individually compiled need to
be extracted from 'inferred-name for reference in the wrapper.
Closes#2787
Enables native dark mode UI elements in macOS 10.14 and above. Adds the
'NSRequiresAquaSystemAppearance' key with a value of 'false' to the
Info.plist file, while allows UI elements to match the system theme even
when not building against the latest SDK.
When opening the write end of a fifo that doesn't have a reader
already, the old implementation could allow writing bytes that are
discarded. This new implementation uses a blocking `open` in a
`pthread`, and that way the write routines know whether the stream is
ready for writing or not.
The difference is visible in the Racket API in a two places:
`subprocess` needs to wait until a fifo writer is connected before
attempting to dup the corresponding file descriotor, and more
generally a use of `unsafe-port->file-descriptor` needs to wait. The
former blocking operation is now build into `subprocess` (and
documented), but the burden is place on callers of
`unsafe-port->file-descriptor` to wait is necessary.
The new `port-waiting-peer?` predicate exposes the waiting state,
while `sync` is sufficient to wait for a peer.
Closes#2784
On platforms other than Windows and MacOS, locale encoding (inclduing
path <-> string conversion) opened a converter for each separate
operation. That can be slow on some OSes, so cache converters used for
locale conversions.
Relevant to #2781
Allowing #f as an allocator avoids problems composing `allocator` with
foreign-function lookup where failure is anticipated and implemented
as #f. For example, `g_settings_new` in the "gui-lib" package's
"mred/private/wx/gtk/gsettings.rkt" can be #f if the libgio libray is
too old, in which case there won't be an attempt to use
`g_settings_new`.
In some cases, (vector x 2 3 3 3) was pretty-printed as "(vector x 2 3)" when
print-vector-length was enabled.
Also print "(fxvector)" instead of "(fxvector )".
This repair affects DrRacket and xrepl after `enter` so that a
`require` in the context of a module namespace is resolved relative to
the module's path (as it did in the old expander, before v7.0).
Closesracket/drracket#276
Fix the default argument in `syntax/template`, where cons-proc-stx should be a
syntax object reflecting a procedure, not a procedure itself.
Fix test case for `syntax/template`, where restore-stx should be a syntax object
reflecting the restore procedure, not the proceure itself.
Closes#2745
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.
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.