There could be many more functions that produce immutable strings
directly, and we want the default functions to do that in some future
language. For now, these three rae the most immediately useful for
avoiding unnecessary allocation in Racket CS.
Mostly reverts ee4ceb7ae4 and tries a different approach. The prevoius
approach did not handle the case where the module begin instantiated
was tiggered by a module at a different (higher) phase.
Closes#2981
Eliminates another ~300 instantiations from `racket -cl racket/base`.
small-scheme.rkt is no longer used in `racket/private`.
c.rkt was an accidentally-committe file.
Maybe there's a problem in `rktio_poll_add_connect` that I just can't
see, or maybe it's a Mac OS bug, but `rktio_poll_add_connect` doesn't
seem to reliably wake up the process when the TCP connection becomes
ready. Traditional Racket happens to avoid the problem by registering
the connection file descriptor with the semaphore table; doing that
for Racket CS also avoids the problem there.
Take advantage of new guarantees/support for immutable strings within
a Chez Scheme symbol representation. Consistent use of immutable
strings at the boundary avoids potential non-determinism.
This simplifies the expander logging in some places and adds logging for arming/disarming and scope changes (eg syntax-local-introduce) so the macro stepper can better track term identity.
This relies on corresponding changes to the racket/macro-debugger repo.
This breaks existing packages; see https://github.com/greghendershott/aws/issues/64
for an example.
Unfortunately, we probably have to live with this limitation of the
interface because of existing code.
This reverts commit 966399dec6.
Source locations are attached to functions for backtraces. With
traditional Racket, those source locations are connected to the
machinery of `current-write-relative-directory` and
`current-load-relative-directory` to avoid absolute paths, but that
machinery is difficult to integrate into the Racket CS compilation
model. So, since they're "just" for stack traces, save only a couple
of elements of the path.
Although some of them probbably do not matter (while some certainly
do), avoid various possible problems by always using a locally
determinsitic replacement for `gensym`.
Use newly added support for uninterned symbols (as opposed to gensyms)
in the Chez Scheme layer. Using uninterned symbols reduces
non-determinsitsm in the build.
The change to use Chez Scheme uninterned symbols exposed problems with
the way that Racket-level uninterned symbols (formerly implemented
with gensym) are handled in ".zo" files. The problem is that some
uninterned symbols are marshaled with `racket/fasl`, which is not
consostent with those that are marshaled by Chez Scheme's `fasl`. This
patch fixes those problems by ensuring that uninterned symbols are
always lifted to the level of a Chez Scheme `fasl` for a complete
linklet bundle.
Change the way names are generated for pieces of the implementation of
a keyword-argument function. These functions are not accessible as
values, so the names don't matter for printing a function, but the
names can show up in stack traces.
Building with `--enable-embedfw` creates executables that link
statically to the Racket runtime system, instead of linking to a
Racket framework, and that embed boot files in the case of Racket CS.
Executables built this way are meant to cooperate better with code
signing.
Related to #2910
Allow 0 as the port number in `ssl-listen`, and fix
`ssl-addresses` to work on a listener. Update a test
to use these features so that it won't conflict with
other tests that listen on TCP addresses.
Where true places are not supported, `place` is simulated
using Racket threads, and `place-kill` did not kill off the
simulated place well enough.
Relevant to #2930
A sequence of definitions (or `define-values`) at the end of
a module could get reordered. That only matters for the order
of checks for attempting to assign to a constant, though.
Suppress the compiler's conversion of statically obvious arity errors
to an expression that reports a custom error with the an S-expression,
since that interferes with Rumble's normalization of error messages.
If `struct dirent` has `namlen` field, define `HAVE_DIRENT_NAMLEN`.
If the field is instead `namelen`, define `HAVE_DIRENT_NAMELEN` (case of QNX).
Use this checks in `rktio_fs.c` and simplify `platform.h`.
Fix many incorrect arity declarations and actual arities in Racket CS,
and fix several incorrect arities in traditional Racket. Building
Racket CS now checks the information in "racket/src/cs/primitives"
against both Racket variants to make sure that they're all consistent.
Closes#2924
Racket CS did not support the optional second argument for
`continuation-prompt-available?`. Traditional racket did not produce a
sensible result for the prompt tag that is used to delimit a
composable continuation or in some cases for the default continuation
prompt tag.
configure scripts look for and read a local configuration file given by the
environment variable CONFIG_SITE. This can set variables such as prefix.
Racket’s build system was assuming that prefix would be set to NONE unless a
--prefix command line argument was given. But it could be set by a
CONFIG_SITE configuration file instead.
Hence, for in-place build add an explicit --disable-useprefix option, to
cause any prefix setting to be ignored, and use that in the top-level
Makefile.
Regenerate the configure scripts to get the updated code.
Revert the part of 39a96dd699 that hides the provenance of these
accessors. Although exposing the fact that the predicates are for
structure properties constrains some internal representations, that
constraint seems unlikely to matter, and exposing the procedures as
property predicates is more consistent with the documentation and the
implementation (especially for Racket CS).
Closes#2904
Improve gcc detection in configure script
We have been detecting gcc by the CC variable but this fails under
ubuntu for example where you might specify CC='gcc-8' to ./configure.
Also consider clang impersonator to be gcc.
Related to #2890
Support continuation-mark inspection proportional to the amount that
needs to be inspected, instead of having to build a list of length
propotional to the size of a continuation.
In Racket CS, use iteration to improve exception-handling chaining.
Traditional Racket already used similar functonality internally.
Add a special case for a real divided by a complex, and remove
(probably) misguided special cases for inexact zero real and imaginary
parts. These changes bring complex `/` further in line for Racket and
Racket CS.
Related to racket/typed-racket#868
The check for whether a provided identifier is syntax or a variable
cuold incorrectly inspect a module that is not yet prepared for the
relevant phase.
Include the defined name (in addition to the provided name) in the
result of `module->exports` and `module-compiled-exports` --- but for
backward compatibility, only if the new optional `verbosity` argument
is 'defined-names.
* Fix gen:dict methods for alists with duplicate keys
This fixes https://github.com/racket/racket/issues/2803.
Note that while this works, the implementation is not particlarly fast.
Especially for iterators.
* Fix tabs
* Make code more efficient
* Fix function definition order
* Import set library
* Preserve order
* Use immutable hash sets
* Remove unused import and remove duplicate checks
* Fix syntax error
For a division c+di, when c is less than d, and when (/ d c) produces
infinity, then the sign on the imaginary part of the result was
backwards. For example, `(/ -1.0e-9-1.0e+300i)` produced `-0.0-0.0i`
instead of `-0.0+0.0i`.
Note: the traditional Racket executable continues to incorporate
LGPLv3 code and thus modifications to it must be released under
that license. However, all Racket code in this repository, as well
as the Racket-on-Chez excutable, are more permissively licensed.
Thanks in particular to @otherjoel and @zyrolasting for their work
on this project.
Commit 77023aeaba made the reference from a custodian-managed
value to the custodian weak, and that could cause a crash in
certain shutdown cases.
Relevant to #2867
Just bumping the version number here to make sure the improved
`call/cc` is used. The improvement saves about 10% on ctak by avoiding
a layer of closure allocation.
Refactor to move some composable-continuation support out of the
way of prompts, and add a shortcut for simple composition cases.
Also, fix stack traces with continuation barriers and composable
composition, which could show sections of a trace duplicated.
For Racket CS, weaken references from managed objects to managing
custodians. Otherwise, a custodian with any managed values cannot
be GCed. Also, fix `collect-garbage` call that is triggered by
a memory-limit shutdown to happen after the current thread
(likely shutdown) is swapped out.
For traditional Racket, fix custodian shutdown on a memory-limited
custodian so that it is unregistered as having a limit.
Lift and delay serialization for non-serializable literals when
using `compile`. Just `compile`ing such an expression is ok, but
it reports an error if there's an attempt to serialize (by printing)
the compiled value.
This improvment also brings Racket CS much more in line with
traditional Racket on the kinds of values that it is willing to
serialize. For example, non-prefab structures no longer serialize
(where deserializing in a new Racket run would produce an instance of
a distinct structure type). The exception type and error message also
now matches traditional Racket.
The improvement relies on a new argument to `s-exp->fasl` for handling
errors.
Also, adjust a memory-limit test that wasn't checking behavior as
intended and that wasn't consistent with a Racket CS improvement over
traditional Racket.
A base type of `_gcpointer` works ok for traditional Racket as a kind
of "maybe it's GCable, so treat it that way just in case". That
approach doesn't work for Racket CS, where `_gpointer` has to mean
"definitely GCable memory". Although the difference is unfortunate,
making Racket CS base `(_bytes o <n>)` on `_pointer` is consistent
with the way plain `_bytes` is like `_pointer` in Racket CS and like
`_gcpointer` in traditional Racket.
Some synchronization built into `close-output-port` seems unnecessary
on modern Windows (NT and up). An extra manager thread is needed for a
anonymous pipe for "write ready?" purposes, but not to buffer output.
The Windows documentation is not entirely clear on this point, but
experiments suggest that modern anonymous pipes behave in the obvious
way.
Meanwhile, adjust the io layer used by Racket CS with the
synchronization that would be needed for Windows 95. This adjustment
is questionable, because it doesn't seem likely that we'll ever go
back that far with Racket CS. But the rktio interface to support
flushing synchronization might somehow be needed in a future setting,
or mabe it will turn out that I'm wrong about pipe buffers.
Avoid a continuation frame and layer of thunks that was in place for
checking for breaks just after applying a continuation. Instead, we
install just the continuation marks and check for breaks before
actually jumping; the break checker can't tell the difference, since
marks are the only way for it to check the continuation. This
improvement cust about 40% of the time for simple continuation capture
and application.
A misplaced `wrap-evt` could allow the result from `sync` on
a log receiver to be an opaque event, instead of a vector.
In other cases, a differently misplaced `wrap-evt` could also cause an
internal instance of `control-state-evt` to not be unregistered
correctly.
The solution to both problems is to add a wrapper procedure to
`control-state-evt`.
Closes#2664
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 )".