In make mode, GHC keeps a lot of in-memory data structures about modules it has built and interface files it has read. These data structures are long-lived and immutable (at least, per module/mutually recursive module group/package), so they may be candidates for storing in compact regions to reduce the work done by the GC.
Potential problem: if we rely heavily on lazy evaluation in these structures for the purpose of avoiding work that will never be needed, then we can't store them in a compact region (since the contents of a compact region must be fully evaluated).
Trac metadata
Trac field
Value
Version
8.0.1
Type
FeatureRequest
TypeOfFailure
OtherFailure
Priority
normal
Resolution
Unresolved
Component
Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
I actually tried using it for interface files, but it won't work (yet). We can't compact pinned memory, and FastString is implemented in terms of ByteString, which is backed by pinned memory. Perhaps we ought to special-case this somehow, because compacting things involving ByteString would be really useful - it would be possible but we have to adjust the address stored in the ByteString when we copy it. (or fix ByteString to use unpinned memory, which we want to do anyway, but that's harder).
Also I'm not 100% sure that there aren't functions buried somewhere in ModIface, which also can't be compacted.
I don't think there are any functions in ModIface as it's serialised anyway using Binary. Perhaps we should implement FastString using ShortByteString. If the ShortByteString are placed into the Compact then we can still use pointer equality for comparing them for equality.
... then we can still use pointer equality for comparing them for equality
There is an interesting question here. While this is technically true at the moment, I don't believe that this guarantee is stated explicitly anywhere. Moreover, it is possible that we want to leave open the possibility of moving compacts as this would allow explicit GC and defragmentation within a compact.
This suggests that we someday might want pinned and unpinned compacts.
I got a fair way towards trying to compact a ModIface building on !1675 (closed) but ultimately failed because ModIface contains Names contain references to TyThings. It doesn't seem possible to make any more progress without a lot of refactoring.
To check my understanding: compacting and sharing has roughly the same residency, which is the best we can hope for. One might expect the GC cpu time to be smaller as it doesn't work on the top bar of the last graph.
Was looking for a bindist to avoid building myself.
Using your commit 0b2b200d, I saw some panics building Cabal with -fno-code -j. I will have a look into fixing if I can find time(unlikely).
libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1: error: Duplicate type signatures for ‘$cPolyForm_Noncommercial_1_0_0_aENi’ at libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 |1 | -- This file is generated. See Makefile's spdx rule | ^libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1: error: Duplicate type signatures for ‘$cNaumen_aEMc’ at libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 |1 | -- This file is generated. See Makefile's spdx rule | ^libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1: error: Duplicate type signatures for ‘$cGFDL_1_3_or_later_aEKS’ at libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 |1 | -- This file is generated. See Makefile's spdx rule | ^libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1: error: Duplicate type signatures for ‘$cGFDL_1_3_invariants_only_aEKO’ at libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 |1 | -- This file is generated. See Makefile's spdx rule | ^libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1: error: Duplicate type signatures for ‘$cCPAL_1_0_aEK2’ at libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 libraries/Cabal/Cabal/src/Distribution/SPDX/LicenseId.hs:1:1 |1 | -- This file is generated. See Makefile's spdx rule | ^<no location info>: error: ghc: panic! (the 'impossible' happened) (GHC version 9.1.20210227: piResultTys1 * [x_aILT] Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:181:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Core/Type.hs:1257:5 in ghc:GHC.Core.Type
* [nix-shell:~/code/ghc]$ GHC=./_build-baseline/ghc-stage1 ./build-cabal.sh* 53,713,157,712 bytes allocated in the heap 4,808,928,568 bytes copied during GC 410,808,912 bytes maximum residency (19 sample(s)) 4,435,376 bytes maximum slop 391 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 1515 colls, 0 par 3.941s 3.937s 0.0026s 0.1147s Gen 1 19 colls, 0 par 1.661s 1.659s 0.0873s 0.3061s TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1) SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) INIT time 0.000s ( 0.000s elapsed) MUT time 26.942s ( 36.207s elapsed) GC time 5.602s ( 5.596s elapsed) EXIT time 0.001s ( 0.006s elapsed) Total time 32.545s ( 41.810s elapsed) Alloc rate 1,993,660,493 bytes per MUT second Productivity 82.8% of total user, 86.6% of total elapsed39.34user 2.54system 0:41.85elapsed 100%CPU (0avgtext+0avgdata 1008816maxresident)k100264inputs+141192outputs (9504major+1479146minor)pagefaults 0swaps* [nix-shell:~/code/ghc]$ GHC=./_build-compact-modiface/ghc-stage1 ./build-cabal.sh* 53,854,158,016 bytes allocated in the heap 4,518,317,632 bytes copied during GC 423,240,656 bytes maximum residency (18 sample(s)) 4,439,088 bytes maximum slop 403 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 1333 colls, 0 par 3.734s 3.730s 0.0028s 0.1158s Gen 1 18 colls, 0 par 1.621s 1.898s 0.1055s 0.3750s TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1) SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) INIT time 0.001s ( 0.003s elapsed) MUT time 27.229s ( 37.842s elapsed) GC time 5.355s ( 5.628s elapsed) EXIT time 0.000s ( 0.006s elapsed) Total time 32.585s ( 43.480s elapsed) Alloc rate 1,977,827,576 bytes per MUT second Productivity 83.6% of total user, 87.0% of total elapsed39.45user 2.74system 0:43.53elapsed 96%CPU (0avgtext+0avgdata 1051216maxresident)k250352inputs+141192outputs (10322major+1489939minor)pagefaults 0swaps