-
f54472bf
by Sylvain Henry at 2026-11-04T08:08:10-05:00
ghc-internal: avoid unnecessary allocations in bignum division (#27231)
Avoid unnecessary allocations in bignum division in the Haskell (native)
backend. The long-division loop used to allocate a fresh BigNat for the
partial product on every iteration, plus one more per quotient-digit
correction; it now subtracts the partial product in place and
materializes nothing.
The quotient-digit estimate is also refined against the second-highest
divisor word, so the add-back correction runs at most once per
iteration.
bignat_quotrem_normalized now requires a divisor of at least 2 words, so
bignat_quotrem dispatches 1-word divisors to bignat_quotrem_word.
See Note [Knuth division loop] and Note [Fused multiply-subtract for
long division] in GHC.Internal.Bignum.Backend.Native.
Measured on the new T27231 perf test (10000 native-backend 8192/2048-bit
Integer quotRem calls): bytes allocated drops from 305 MB to 52 MB (-83%).
Improvement on CI (x86-64-linux-deb13-int_native):
space_leak_001(normal) run/alloc 12,492,185,536 9,073,055,928 -27.4% GOOD
Metric Decrease:
space_leak_001
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
-
31a73180
by ARATA Mizuki at 2026-11-04T08:08:15-05:00
testsuite: Mark T367_letnoescape fragile for the optllvm way
It was marked broken, but it is now unexpectedly passing on aarch64-linux-deb13-validate+llvm.
Marking it fragile for now.
See #7292
-
6196d206
by Sylvain Henry at 2026-11-04T08:08:21-05:00
rts: heap census counts every small pinned object
Blocks of small pinned objects carry BF_LARGE as well as BF_PINNED but
hold many objects. heapCensusChain treated every BF_LARGE block whose
first object is an ARR_WORDS as holding that single object, a workaround
for the slop left by shrinkMutableByteArray# (#11627). So every heap
profile mode under-reported pinned byte arrays, i.e. ByteString payloads.
Shrinking now writes a slop marker that skipSlop understands (#19048,
#27585), so the block walk is safe for large and pinned blocks alike.
The block that a capability fills with small pinned objects stays
attached to the capability until it is full (see allocatePinned), so it
is on no generation list and the census never saw its objects. heapCensus
now walks cap->pinned_object_block too.
A pinned block is kept or freed as a whole (#28005), so dead pinned
objects are counted until their block is freed. T7275 gains one sample in
which its dead small arrays still show. The user guide and changelog
document this.
Fixes #28000
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
-
96f1757c
by Sylvain Henry at 2026-11-04T08:08:26-05:00
Serialized: encode numbers with LEB128
serializeWithData used the Binary instances of Data.Binary for the
numbers in a ConstrRep. They have a fixed width: 8 bytes for the
constructor index (an Int) and 5 bytes for a small Integer. Each
element of a [Int] cost 15 bytes.
Now the constructor representation is one unsigned LEB128 number that
also contains the index of an algebraic constructor, and the payloads
(Integer, Rational, Char) are LEB128 encoded. Most constructors take
one byte, and small numbers two. See Note [Serialized encoding].
Sizes measured by the T16841 test:
[1..100] :: [Int] 1509 -> 338 bytes
"helloworld" 119 -> 31 bytes
2^100 :: Integer 24 -> 16 bytes
Just True 18 -> 2 bytes
3.25 :: Double 11 -> 3 bytes
42 :: Int 6 -> 2 bytes
A new test, SerializedRoundTrip, round-trips values at the boundaries
of the encoding (negative numbers, big Integers, Rationals, Chars).
Follow-up to !16841 (#28002).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
-
908ac7e9
by Rodrigo Mesquita at 2026-11-04T08:08:27-05:00
interp: Make resumeExec and ExecBreak use `Resume` directly
Previously, `Resume` contexts were just put directly in the global
interactive environment state, so they were only accessible through it.
However, in the context of multi-threaded debugging, in that many
threads may hit breakpoints, it no longer suffices to have a global
linear list of breakpoints hit. We need a per-breakpoint Resume context
and need to be able to wield it directly rather than going through a
global context.
The driving changes of this commit are:
- Put the Resume data in ExecBreak
- Make resumeExec receive a Resume as an argument
This also simplifies the interpreter in that we no longer necessarily
rely on the global interactive state to resume a thread. We can do it
directly from the ExecBreak.
The interactive context still maintains a stack of resumes, but
`resumeExec` can no longer pop the resume it resumes off of the
breakpoints stack, since it is no longer guaranteed to be resuming the
first in that list. Hence, callers of `resumeExec` must update ic_resume
on their own.
Fixes #28058
-
71144227
by Andrea Vezzosi at 2026-11-04T08:08:28-05:00
driver: Don't let -dynamic unset -fsplit-sections
`addWay' WayDyn` used to unset Opt_SplitSections, so -fsplit-sections was
ignored if it came before -dynamic, but worked if it came after.
The -fsplit-sections -dynamic combination has legitimate uses, e.g. an
executable can be linked dynamically against libraries and still have dead code
from its own sources to eliminate. Or the same objects could be used for both
static archives and shared objects.
The removal of Opt_SplitSections was also motivated by problems on Darwin.
It is now done in `makeDynFlagsConsistent` instead, see Note [Split sections are not
supported on Mach-O].
For consistency, we also keep Opt_SplitSections when `dynamicNow` is activated.
There is a cost of larger .dyn_o (but not .so) files and slower link times (esp.
with ld.bfd), but does not seem significant enough to warrant special casing.
Fixes #28061
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>