This commit adds an (unused) implementation of immutable hash tables
for Racket CS that trades some run-time performance for an especially
compact representation --- similar to the traditional Racket
implementation of immutable hash tables. It uses a new "stencil
vector" datatype at the Chez Scheme level, which overlays the bitmap
needed for a HAMT node with the Chez-object type tag (and also
provides an update operation that avoids unnecessary memory work).
Compared to the current Racket CS implementation, the stencil-vector
HAMT implementation of an immutable hash table takes only about 1/3
the space on avergae, which translates to a overall 5% savings in
DrRacket's initial heap. It also makes a full Racket build slightly
faster by reducing avergage memory use by 5-10%.
But the run-time performance difference is significant, especially for
the `hash-keys-subset?` operation (at least in microbenchmarks), and
also for addition and iteration. Maybe there's an overall better point
that reduces memory use of the current Patricia trie implementation
without sacrificing as much performance.
Besides the benchmarks and stencil-vector HAMT implementaiton, there
are small changes to the way hash tables cooperate with `equal?`,
which makes it a little easier to plug in different implementations.
Building with shared libraries is not currently supported, because the
Chez Scheme build is not set up to work in that mode, and because
"stand alone" executable handling at the Racket level does not support
Racket CS shared libraries.
Also, there's no benefit to shared libraries. Racket executables get
the benefit of sharing because they all run through the same
executable. Meanwhile, there's not (yet?) a supported C API to make
something like "libracketcs.so" useful.
Related to #2993
Adjust part of the internal scheduling protocol to make a retry
callback generated by another callback that sets up the retry. This
helps clarify the protocol and avoids allocating a closure that is
rarely used.
Make Racket CS consistent with traditional Racket in the way
`chaperone-evt` on a thread hides threadness, etc.
Hiding properties like threadness is not ideal and does not seem
entirely consistent with `chaperone-of`, but allowing things like
threads and semaphores to be chaperoned creates non-trivial expense
internally. It would have been better to have event constructors for
threads and such to (and then the consyructed events could be
chaperoned without imposing a cost on the original data structure).
Force inlining of value and key accessors. Keeping the `define` with a
loop body --- that is, not making the individual function a macro ---
allows the Rumble `define` to avoid a closure allocation for the loop.
Hash iteration can fail if a GC collects a key in between
`hash-iterate-next` and `hash-iterate-key` (and similar). Use the
optional extra argument internally to detect and handle that case.
THe internal `assoc?` predicate is relatively expensive, so remove
redundant uses. Also, uses a cache to make it a little cheaper for
muliple uses of dictionary functions on a moderately sized list.
We have also removed ubsan flags from CPPFLAGS - since these are
compile flags, not preprocessing flags.
To pass the flags to rktio, we split the use of CFLAGS and CPPFLAGS
in rktio and ensure that flags in rktio do not update flags if make
is called in sub-make form (in a standard racket build, the rktio make
is called as a sub-make from the main racket make).
Fixes#2984
* Avoid export on variables in Makefiles
Instead pass the variables explicitly to the make call.
* Fix variable syntax
* Double quote variables
* Put ubsan back in CPPFLAGS
* Remove conditional assignment
This is not necessary if passing variables straight into sub-make