Implement weak and ephemeron generic hashtables, and repair weak and
ephemeron `eqv?` hashtables to be weak on numbers.
Racket's implementation of weak `equal?`-based tables now uses weak
generic tables. Datum interning, which needs a weak `equal?`-based
table and was the bottleneck for unfasling literal data, is much
faster. DrRacket's footprint is 1% smaller.
Use the fixnum-mixing idea of dc82685ce0 on pointers, too.
This change provides a significant improvement on the "hash-mem.rkt"
benchmark, for example, because the allocated objects have a size that
triggers a repeating pattern in the low bits of the allocated address.
Use data instead of code to shrink ".zo" sizes by 10-30%.
When Racket code contains a literal that cannot be serialized directly
by Chez Scheme (such as a keyword or an immutable string that should
be datum-interned), the old approach was to generate Scheme code to
construct the literal through a lifted `let` binding. To handle paths
associated with procedures, however, Chez Scheme's `fasl-write` had
been extended to allow arbitrary values to be intercepted during fasl
and passed back in to `fasl-read`. Using that strategy for all Racket
literals simplifies the implementation and reduces compiled code. It
also makes closures smaller, while increases the number of
relocations. DrRacket's foorprint shrinks by about 1%, but the main
affect is on disk space for a Racket installation.
Show the machine code that constructs lifted constants for a linket.
Also, add a `--partial-fasl` option that shows fasl content in a rawer
form, which is useful for checking how content is presented and that
nothing is getting lost in other reconstructed views.
The 'os* mode is like 'os, but it provides a more specific result for
Unix variants, such as 'linux on Linux.
The 'os* and 'arch modes together are the information that we've
previously accessed indirectly via `(system-library-subpath #f)`.
Closes#3510
Mixing for sequences did not produce enough variety related to the
length of the sequence. For example, '(0 0) and '(0 0 0) and '(0 0 0
0) had the same hash code.
Allow cptypes to convert a `fx{+,-,*}/wraparound` call to unsafe if it
proves that the arguments are fixnums (unlike, say, `fx+`, where the
possibility of overflow remains).
Change hash-code calculations to use `fx+/wraparound` and
`fxsll/wraparound` instead of `#3%fx+` and `#3%fxsll`. The resulting
code should be the same in the default unsafe compilation mode for the
Racket core, but the `wraparound` versions can be checked in safe
mode.
Also, fill in missing tests in Chez Scheme, which exposed cp0 problems
with `fx-/wraparound`.
Expose machine-level operations that stay within the fixnum range,
which can be useful for things like hash-code computations where it's
ok to just lose bits. Operations like `unsafe-fx+` turn out to do that
already in the current implementation, but with no guarantee (and with
no checking of arguments).
For Racket BC, before this commit, JIT-inlined `fxlshift` incorrectly
handled a negative second argument like `arithmetic-shift` instead of
erroring.
When the thread-scheduler timer fires while a thread is in atomic
mode, the thread could check for breaks even when it shouldn't. Worse,
if the atomic region was to implement terminating a thread, the path
to check for a break could end up ressurecting the thread from the
persspective of `thread-dead?`.
A mutable hash table only uses the lower few bits of a hash code,
because it masks the hash code by [one less than] the power-of-two
size of the bucket array. That truncation interacts badly with the
hashing function for fixnums, which is the identity function; if the
the lower several bits of the fixnum stay the same for many keys and
the upper bits change, then there are many hash collisions --- and
that's a relatively likely distribution.
Fix the mutable hash-table implementations by mixing the hash code to
let higher bits influence the lower bits: xor the high half of the
bits with the lower half (which doesn't lose information, because
xoring again would recover the original number), then do the same for
the high one-fourth of bits in the low half, and then (on a 64-bit
platform) the high one-eighth of the low one-fourth of the bits.
Instead if blaming the way the mutable hash-table implementations only
use the lower bits of a hash code, we could blame the hash function on
fixnums for not performing this kind of mixing. In this patch, though,
we take the view that the hash function's job is to map variation in
its domain to variation in the fixnum hash code, and then the hash
table's job is to use that fixnum effectively. That separation of
responsibilities is now documented with `gen:equal+hash`.
There are also improvements here to the hashing function for bignums
in CS and to the secondary hashung function for fixnums and bignums in
BC.
Thanks to Alex Harsanyi for reporting the problem.