-
8eea219f
by Zubin Duggal at 2026-08-25T14:52:54+05:30
linker: refactor loader so that object suffixes get passed through in a sane way
-
e1c8030b
by Zubin Duggal at 2026-08-25T14:52:54+05:30
Identify Linkable with fingerprints of their contents rather than modtimes
-
afdb51c2
by Zubin Duggal at 2026-08-25T14:52:54+05:30
Linker cleanup
delete a bunch of unused functions
-
c7f64e7d
by Zubin Duggal at 2026-08-25T14:52:54+05:30
Record constituent hashes for bytecode libraries
A bytecode library now records the combined hash of its constituents,
so relinking can be skipped when they haven't changed.
-
8c6f94c5
by Zubin Duggal at 2026-08-25T14:52:54+05:30
linker: Automatically reload stale linkables
Linked BCOs contain direct references to closures, so replacing only a
changed module can leave stale references in other modules. Take
-- A.hs
f = 1
-- B.hs
import A
g = f + 1
After loading A and B, change A so that f = 2 and recompile it. B does
not need to be recompiled, but its loaded BCO still refers to the old
closure for f. The next splice should see f = 2 and g = 3. To get the
correct result, we have to *reload* B, even though we didn't need to
recompile it.
The GHC driver calls unload before each upsweep, which unloads
everything, so this does not arise during an ordinary GHCi reload. API
clients such as HLS may instead want to keep the loader state while
recompiling individual modules. Forcing them to unload everything or
carefully keep track of what to unload is not ideal.
Now we automatically reload stale linkables, so that if we are asked
to link a module whose code has changed, the old code, and everything
that refers to it, is dropped and reloaded. See
Note [Automatically reloading stale linkables].
Dropped objects are now purged, not unloaded, so values built by the
old code and computations still using it keep working. The object
stays in memory, but new code will not be able to link against it.
This is a change in behaviour, objects were previously only ever
unloaded, all at once, in unload. See
Note [Unloading vs purging objects]
Fixes #27606
-
c500df06
by Zubin Duggal at 2026-08-25T14:52:54+05:30
linker: Add unloadModules
Drop the given modules and every loaded module that transitively
refers to them. Reloading stale code does not need this, it happens
automatically. This is for API clients dropping modules they no
longer need. Interactive modules are ignored.
See Note [Automatically reloading stale linkables] in GHC.Linker.Loader
See Note [Unloading vs purging objects] in GHC.Runtime.Interpreter
-
d2e4f73e
by Zubin Duggal at 2026-08-25T14:52:54+05:30
iserv: Add a PurgeObj message
purgeObj no longer falls back to unloading on external interpreters.
See Note [Unloading vs purging objects] in GHC.Runtime.Interpreter.
-
8dc9fe7d
by Zubin Duggal at 2026-08-25T14:52:54+05:30
linker: Remove static pointer table entries when dropping modules
Entries were added by bytecode modules, but never removed. This meant
that every reload of a module with static forms leaked its old entries
and kept the old code alive, including in GHCi with :reload.
loaded_spt_keys now records the keys each loaded bytecode module
inserted. dropModules and unload remove them. We also add a new
RemoveSptEntry message to support this operation with the external
interpreter.
Object code manages its own entries with initialisers and finalisers,
so it was not changed.
Fixes #27740
-
eabe067a
by Zubin Duggal at 2026-08-25T14:52:54+05:30
Introduce -funload-strategy
When unloading object code, we have a choice to make. Do we call
purgeObj or unloadObj?
purgeObj clears the symbol tables associated with an object, so that
future objects can't link against it, but the object stays in memory
unloadObj does the above, but it also marks the object as needing to be
unloaded, so at some point in a future GC, the RTS may notice that it is
no longer used, and if so, unload it entirely, freeing up the memory.
Ideally we would always unload, but a number of bugs with the
implementation of unloadObj mean that it is fragile on many platforms.
This is documented in Note [Unloading vs purging objects]. So on these
platforms we purge instead.
We introduce the -funload-strategy flag, so that users can opt into
purging/unloading on platforms where we make the other choice by
default.
The distinction is moot when we are using the dynamic RTS, we don't do
either then.
Fixes #27741