This effectively takes one-bit from the length field and uses it as the
sign bit. It reduces the size of an Int from 40 bits to 32 bits on a
64-bit arch.
This also reduces std.Rational from 80 bits to 64 bits.
A constant Int is one which has a value of null for its allocator field.
It cannot be resized or have its limbs written. Any attempt made to
write to it will be caught with a runtime panic.
Before, allocator implementations had to provide `allocFn`,
`reallocFn`, and `freeFn`.
Now, they must provide only `reallocFn` and `shrinkFn`.
Reallocating from a zero length slice is allocation, and
shrinking to a zero length slice is freeing.
When the new memory size is less than or equal to the
previous allocation size, `reallocFn` now has the option
to return `error.OutOfMemory` to indicate that the allocator
would not be able to take advantage of the new size.
For more details see #1306. This commit closes#1306.
This commit paves the way to solving #2009.
This commit also introduces a memory leak to all coroutines.
There is an issue where a coroutine calls the function and it
frees its own stack frame, but then the return value of `shrinkFn`
is a slice, which is implemented as an sret struct. Writing to
the return pointer causes invalid memory write. We could work
around it by having a global helper function which has a void
return type and calling that instead. But instead this hack will
suffice until I rework coroutines to be non-allocating. Basically
coroutines are not supported right now until they are reworked as
in #1194.
Previously, std.debug.assert would `@panic` in test builds,
if the assertion failed. Now, it's always `unreachable`.
This makes release mode test builds more accurately test
the actual code that will be run.
However this requires tests to call `std.testing.expect`
rather than `std.debug.assert` to make sure output is correct.
Here is the explanation of when to use either one, copied from
the assert doc comments:
Inside a test block, it is best to use the `std.testing` module
rather than assert, because assert may not detect a test failure
in ReleaseFast and ReleaseSafe mode. Outside of a test block, assert
is the correct function to use.
closes#1304
A few notes on the implementation:
- Any unsigned power of two integer type less than 64 bits in size is supported
as a Limb type.
- The algorithms used are kept simple for the moment. More complicated
algorithms are generally only more useful as integer sizes increase a
lot and I don't expect our current usage to be used for this purpose
just yet.
- All branches (practically) have been covered by tests.
See 986a2b3243/bench
for rough performance comparison numbers.
Closes#364.