For each signal handler that is changed, save its state, and restore
the state in a child process after a `fork` and before an `execve`.
Also save and restore the signal mask.
This change requires cooperation from various subsystems, which often
takes the form of a callback registered with the subsystem to be
called before adjusts a signal handler.
Closes#3609
Forbidden set operations on weak sets produced slightly confusing error
messages:
> (define s (weak-set))
> (set-add s 42)
; set-add:
; expected: (not/c set-mutable?)
; given mutable set: (weak-set)
; argument position: 1st
> (set-mutable? s)
#f
Invoking an operation that required an immutable set gave a message
saying that a `(not/c set-mutable?)` was expected, but a `weak-set` is
not recognized by `set-mutable?`, which only recognizes mutable sets
with strongly-held keys. Changing `set-mutable?` to recognize weak sets
seems undesirable.
This patch changes the error message so that the above example produces
the following error:
> (define s (weak-set))
> (set-add s 42)
; set-add:
; expected: (not/c (or/c set-mutable? set-weak?))
; given mutable set: (weak-set)
; argument position: 1st
Instead of keeping a rectord type's ancestry in a vector ordered from
subtype to supertype, keep the vector the other way around, and
include a record type at the end of its own vector. This order makes a
more direct test possible when checking for a known record type,
especially one without a supertype, and it's generally easier to
reason about.
The revised compilation of record predicates trades some speed in one
case for smaller generated code and speed in other cases. The case
that becomes slower is when a predicate succeeds because the record is
an immediate instance of the record type. The cases that go faster are
when a predicate fails for a non-instance record or when a predicate
succeeds for a non-immediate instance. It's possible that an
immediate-instance shortcut is worthwhile on the grounds that it's a
common case for a predicate used as contract, but we opt for simpler
and less code for now, because the difference is small.
Also, add `record-instance?`, which in unsafe mode can skip the check
that its first argument is a record, and cptypes can substitute
`record-instance?` for `record?` in some cases. This change was worked
out independently and earlier by @yjqww6, especially the cptypes part.
Related to #3679
On an Apple M1, an example like
(let ([v (make-vector 1000000)])
(for* ([_ (in-range 100)]
[i (in-range 1000000)])
(vector-set! v i (+ 1 i))))
would generate tightly interleaved fence and store operations, which
seems to make the processor unhappy so that the code run 40x slower
than it should.
A key part of the example is that `(+ 1 i)` defeats cp0-level
inference that the result will be a fixnum. A dynamic fixnum test
avoids adding the update to a remembered set as part of the write
barrier, but the memory fence needed for ARM must be before the store,
while the fixnum test was after the store. This change bundles the
write fence and remember-set update under a `fixnum?` guard, so they
happen to gether or not at all --- at the small cost of generating the
store instruction(s) in two branches. In the example above, neither
the fence nor remember-set update happen, but changing `(+ 1 i)` to
`(quote x)` triggers both, and performance is still ok.
Remove a `with-continuation-mark` that is redundant because its both
is another `with-continuation-mark` with the same key. That's useful
for reducing a pattern that appears after some `if`-removing
optimizations on code with errortrace-generated annotations.
Use a comment trick to make `nmake` see a different default target
than `make`, which will save a small amount of hassle from forgetting
to type `nmake win`.
This change allows a query that is run in an OS thread to succeed even
when the connection is custodian-disconnected. Previously, the part in
the OS thread would complete, and then the operations needed to
package the result would fail. This fix moves some of those operations
to the OS thread and makes read-tx-status work when disconnected.
Clean up the implementation. For example predicate-union was
calling predicate-implies? like 20 times. With the new
implementation this can be done in a single pass.
Also, this changes the results of the functions for 'bottom and
#f so they behave like sets. So this removes some special cases
and makes the functions more consistent.
Relative-path handling for `fasl->s-exp` was meant to be like code
unmarshaling, but it did not fall back to `(current-directory)` when
`(current-load-relative-directory)` is #f. There's some risk to
changing the behavior of `fasl->s-exp`, but better matching the intent
seems at least as likely to fix problems as create them. One problem
it fixes is in CS code marshaling.
Closesracket/drracket#421 (again)
As described in #3635, there isn’t currently any good way to use
first-class definition contexts without evaluating define-syntaxes RHSs
multiple times. For macros like `class` and `unit`, it’s unclear if that
can be avoided, but for `block`, the first-class definition context
turns out to not be necessary.
This commit changes the implementation strategy used by `block` to a
trampolining macro rather than a first-class definition context. This
has the nice side-effect of avoiding the issue described in #3198, too.
Visual Studio 2015 duplicates the "Replace me for EXE hack" string in
the GRacket executable, which breaks the hack. Adding the /GF compiler
flag counteracts that duplication, and it's consistent with
`<StringPooling>true</StringPooling>` in the BC projects.
For CS, the default error display handler was not using `prop:exn:srcloc`.
For BC, a bad `prop:exn:srcloc` that returned a value other than a
list of srclocs coudl cause a crash.
Related to #3645
On AArch{32,64}, compiling `call-setting-continuation-attachment` in a
non-tail position could run out of registers for saving/restoring
around th intrinsic to reify the continuation.
Closes#3646
After pulling in patches that change the Chez Scheme version to 9.5.5
(with not much changing besides the version, since we've pulled other
patches), update the Racket version number to reflect the change to
compiled files.
Includes new `force-host-out?' arg to `compile-to-file'.
When the host and target machines match during
"cross"-compilation (eg. M1 Mac to iOS), we still need to generate
host .so files so that the build works out.
Includes documentation notes about cross-compiling CS for iOS
and makefile improvements.
The changes also include improvements to `raco exe`.
Racket CS cannot currently read fasl files for platforms other than
the host, but `compiler/embed` has to be able to read compiled code in
order to figure out what code needs to be embedded into an output
image and which runtime paths need to be included. This change makes
it so that host code is used to figure all of that information out,
but that code is then replaced by target machine code before it is
written to the output image. The new logic only applies when the
right cross-compilation flags are set (per `cross-multi-compile?`).
A `semaphore-wait` or `semaphore-post` has a shortcut that uses a CAS
operation, which means that a future could affect a semaphore if it's
allowed to take that shortcut. But futures aren't supposed to succeed
in that way, because thread-level synchronization should generally
suspend a future. Disallow the shortcut when in a future.
When recompiling from machine-independent form to an VM- and
platform-specific form, cross-module inlining could fail due to an
module path index being resolved in the wrong mode (loading versus
non-loading).
As a concrete example, "racket/draw/private/bitmap.rkt" tended to be
recompiled in a way that did not inline `_ubyte` as `_uint8`, which in
turn made `ptr-set!` and `ptr-ref` operations much slower, which would
make certain bitmap operations drastically slower.
Related to racket/drracket#350
Although compiling modules really should not write output, one problem
is that `parser-tools/yacc` has long reported shift/reduce conflicts
to stderr.
Only parallel mode was treating stdout/stderr output as failure, which
made `raco setup` inconsistent. Make parallel mode allow output, like
sequential mode does.
Related to #3457
In other words, follow a note on line 77 of "atomic.rkt":
;; There's a small chance that `end-atomic-callback`
;; was set by the scheduler after the check and
;; before we exit atomic mode. Make sure that rare
;; possibility remains ok.
That note was originally written in the context of changes for
futures, but it also applies to plain old thread scheduling, where
`engine-timeout` can be installed as a callback, but it's not allowed
if an engine isn't running.
This PR in a sense reverts f83cec1b04 and attempts to directly fix
the bug that the commit tries to address with an approach similar to the
original one.
The problem with the aforementioned commit is that, Gosper's hack
only works efficiently when the length of `l` is small enough that
the number representation can fit into a fixnum
(so that all bit operations take constant time).
When the length of `l` is large, the number representation could
become a bignum with length proportional to the length of `l`.
This is not ideal because it causes the time complexity of the algorithm
to be `O({|l| choose k} |l|)` instead of `O({|l| choose k} k)`, which
would be a significant performance degradation when `|l|` is much
larger than `k`.
Currently, in Racket BC, the following program:
```
(srcloc->string (make-srcloc "x.rkt" #f #f 90 #f))
(srcloc->string (make-srcloc "x.rkt" #f 80 #f #f))
(srcloc->string (make-srcloc "x.rkt" #f #f #f #f))
(srcloc->string (make-srcloc "x.rkt" #f 80 90 #f))
(srcloc->string (make-srcloc "x.rkt" 70 #f 90 #f))
(srcloc->string (make-srcloc "x.rkt" 70 80 #f #f))
(srcloc->string (make-srcloc "x.rkt" 70 80 90 #f))
```
results in:
```
"x.rkt::90"
"x.rkt::80"
"x.rkt::-1"
"x.rkt::80"
"x.rkt:70:90"
"x.rkt:70:80"
"x.rkt:70:80"
```
This output is very confusing and inconsistent.
When we see "x.rkt::90", we can never be sure if it's a srcloc
whose position is 90, or a srcloc whose column is 90.
The same applies for "x.rkt:70:90".
Moreover, the srloc "x.rkt::-1" is weird and is arguably incorrect
(see #1371).
For CS, the output would sometimes contain `#f`, and that is fixed
here by not trying to add position information when it's not available.
Non-atomic mode is questionable at best with BC, and more so with CS.
With BC, a thread swap at least copies the fragment of the C stack
that is between a foreign call and a callback; that can work with some
C libraries, but it goes wrong often enough that it really shouldn't
be relied on. On the plus side, if it's going to go wrong, at least it
tends to go wrong right away (i.e., something in the C frame tends to
get broken in normal runs).
With CS, the C stack is not captured as part of a thread, and so
non-atomic mode 's even more broken. Non-atomic mode could work if you
know that no other thread is running that can involve foreign calls
and callbacks, but that assumption is usually not a good one. Worse,
when things finally go wrong, it's likely several scheduling steps and
thread interleavings away from the problem (e.g., #3459).
There's a chance that this change will stop some existing programs
from working ok on CS. It's more likely to make existing programs work
as intended on CS; the common case is that atomic mode is technically
needed even though non-atomic mode happened to work in practice with
BC.
I think that in general, `null-terminated?` should admit all patterns
that _could_ match a list, instead of just the ones that _only_ match
a list. That means that `(app f)` patterns and many others should also
be valid, though those are harder to implement, so I haven't tried
those yet.
This change is mostly for making CS consistent with BC, but in the
case of `(object-name #'x)`, it also makes BC consistent with BC
before the macro-expander rewrite.
Closesracket/pconvert#9
Commit 9a3eb15d8b broke atomic-timeout handling. As aresult, for
example, using the scroll thumb on Mac OS could freeze DrRacket as
long as something is running for a canvas refresh.
Change the representation of records to keep an ancestor vector
instead of just a parent, so a record-type predicate (for a non-sealed
type) can be constant-time.
Reluctantly, with intentionally oxymoronic names, and with the key
caveat: using these requires making correct assumptions about Racket's
implementation.
With BC, a related assumption was that `unsafe-set-mcar!` and
`unsafe-set-mcdr!` mutate pairs, but that's not the case with CS. So,
adding these functions supports a kind of portability between BC and
CS.
The UTF-8-ish decoder incorrectly allowed a surrogate pair encoded as
two unpaired surrogates, and it treated an unpaired surrogate at the
of a stream as complete instead of a potential error.
Related to #3578
Related to #1500.
This improves the following aspects of the CI config:
* The config now tracks the current stable version of Racket so
package authors don't have to remember to upgrade the config on new
releases. This is a double-edged sword, because it makes it easy to
use features of new Racket version and potentially break
backwards-compatibility by accident. Running CI against a set of
static Racket versions doesn't have this problem since any such change
would end up failing. Maybe a better change here would be to
interpolate the current `(version)` into the CI file instead.
* The job is now set to fail on the first error it encounters on the
assumption that most packages fail due to internal issues and not due
to mismatches between Racket versions. The intent with this change is
to use fewer resources overall when possible. Additionally, the
packages' dependencies are now validated during the setup step.
* Lastly, the install step now avoids building documentation for
dependencies, which can shave off significant amounts of time.
Calling `rationalize` with `+nan.0` as the second argument was causing
a "no exact representation error." This commit changes it to produce
`+nan.0`.
There was an unexercised set of tests for `rationalize` in the test
suite which, once called, demonstrate the bug.
Those tests also specify that `rationalize` should produce an exact
result when the first argument is exact and the second is an infinity.
That's not what the implementation does; it coerces the result to
inexact. I changed the test cases to match the implementation, which
is consistent with other Schemes (Chez, MIT) and standards (R6RS).
When a {u,s}16vector points to memory that's not bytes (e.g. from ffi)
then referencing or setting the memory results in a Chez error:
```
foreign-set!: unrecognized type 'int16
```
The fix is to change the type argument to `'integer-16` and
`'unsigned-16`.