Rodrigo Mesquita pushed to branch wip/romes/25636 at Glasgow Haskell Compiler / GHC
Commits:
-
696e1f80
by Rodrigo Mesquita at 2025-12-19T20:05:07+00:00
7 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/StgToByteCode.hs
Changes:
| ... | ... | @@ -95,13 +95,15 @@ bcoFreeNames bco |
| 95 | 95 | mkUniqDSet [ n | BCONPtrItbl n <- elemsFlatBag unlinkedBCOLits ] :
|
| 96 | 96 | map bco_refs [ bco | BCOPtrBCO bco <- elemsFlatBag unlinkedBCOPtrs ]
|
| 97 | 97 | ) `uniqDSetMinusUniqSet` mkNameSet [unlinkedBCOName]
|
| 98 | - bco_refs UnlinkedStaticCon{unlinkedStaticConName, unlinkedStaticConLits, unlinkedStaticConPtrs}
|
|
| 98 | + bco_refs UnlinkedStaticCon{ unlinkedStaticConName, unlinkedStaticConDataConName
|
|
| 99 | + , unlinkedStaticConLits, unlinkedStaticConPtrs }
|
|
| 99 | 100 | = unionManyUniqDSets (
|
| 101 | + mkUniqDSet [ unlinkedStaticConDataConName ] :
|
|
| 100 | 102 | mkUniqDSet [ n | BCOPtrName n <- elemsFlatBag unlinkedStaticConPtrs ] :
|
| 101 | 103 | mkUniqDSet [ n | BCONPtrItbl n <- elemsFlatBag unlinkedStaticConLits ] :
|
| 102 | 104 | map bco_refs [ bco | BCOPtrBCO bco <- elemsFlatBag unlinkedStaticConPtrs ]
|
| 103 | 105 | )
|
| 104 | - `uniqDSetMinusUniqSet` mkNameSet [unlinkedStaticConName]
|
|
| 106 | + `uniqDSetMinusUniqSet` mkNameSet [ unlinkedStaticConName ]
|
|
| 105 | 107 | |
| 106 | 108 | -- -----------------------------------------------------------------------------
|
| 107 | 109 | -- The bytecode assembler
|
| ... | ... | @@ -207,14 +209,17 @@ assembleInspectAsm p i = assembleI @InspectAsm p i |
| 207 | 209 | |
| 208 | 210 | assembleBCO :: Platform -> ProtoBCO -> IO UnlinkedBCO
|
| 209 | 211 | assembleBCO platform
|
| 210 | - (ProtoStaticCon { protoStaticCon = dc
|
|
| 212 | + (ProtoStaticCon { protoStaticConName
|
|
| 213 | + , protoStaticCon = dc
|
|
| 211 | 214 | , protoStaticConLits = lits
|
| 212 | 215 | , protoStaticConIds = ids
|
| 213 | 216 | }) = do
|
| 217 | + pprTraceM "assembleBCO: static con" (ppr dc <+> ppr lits <+> ppr ids)
|
|
| 214 | 218 | let ptrs = foldr mappendFlatBag emptyFlatBag (map idBCOArg ids)
|
| 215 | 219 | let nonptrs = foldr mappendFlatBag emptyFlatBag (map litBCOArg lits)
|
| 216 | 220 | pure UnlinkedStaticCon
|
| 217 | - { unlinkedStaticConName = dataConName dc
|
|
| 221 | + { unlinkedStaticConName = protoStaticConName
|
|
| 222 | + , unlinkedStaticConDataConName = dataConName dc
|
|
| 218 | 223 | , unlinkedStaticConLits = nonptrs
|
| 219 | 224 | , unlinkedStaticConPtrs = ptrs
|
| 220 | 225 | }
|
| ... | ... | @@ -52,6 +52,9 @@ data ProtoBCO |
| 52 | 52 | -- | A top-level static constructor application object
|
| 53 | 53 | -- See Note [Static constructors in Bytecode]
|
| 54 | 54 | | ProtoStaticCon {
|
| 55 | + protoStaticConName :: Name,
|
|
| 56 | + -- ^ The name to which this static constructor is bound,
|
|
| 57 | + -- not to be confused with the DataCon itself.
|
|
| 55 | 58 | protoStaticCon :: DataCon,
|
| 56 | 59 | protoStaticConLits :: [Literal],
|
| 57 | 60 | protoStaticConIds :: [Id],
|
| ... | ... | @@ -290,8 +293,8 @@ data BCInstr |
| 290 | 293 | -- Printing bytecode instructions
|
| 291 | 294 | |
| 292 | 295 | instance Outputable ProtoBCO where
|
| 293 | - ppr (ProtoStaticCon con lits ids origin)
|
|
| 294 | - = text "ProtoStaticCon" <+> ppr con <> colon
|
|
| 296 | + ppr (ProtoStaticCon nm con lits ids origin)
|
|
| 297 | + = text "ProtoStaticCon" <+> ppr nm <+> text "for constructor" <+> ppr con <> colon
|
|
| 295 | 298 | $$ nest 3 (pprStgRhsShort shortStgPprOpts origin)
|
| 296 | 299 | $$ nest 3 (text "lits: " <+> ppr lits)
|
| 297 | 300 | $$ nest 3 (text "ids: " <+> ppr ids)
|
| ... | ... | @@ -486,7 +489,8 @@ instance Outputable BCInstr where |
| 486 | 489 | -- stack high water mark, but it doesn't seem worth the hassle.
|
| 487 | 490 | |
| 488 | 491 | protoBCOStackUse :: ProtoBCO -> Word
|
| 489 | -protoBCOStackUse bco = sum (map bciStackUse (protoBCOInstrs bco))
|
|
| 492 | +protoBCOStackUse ProtoBCO{protoBCOInstrs} = sum (map bciStackUse protoBCOInstrs)
|
|
| 493 | +protoBCOStackUse ProtoStaticCon{} = 0
|
|
| 490 | 494 | |
| 491 | 495 | bciStackUse :: BCInstr -> Word
|
| 492 | 496 | bciStackUse STKCHECK{} = 0
|
| ... | ... | @@ -80,9 +80,13 @@ linkBCO interp pkgs_loaded bytecode_state bco_ix unl_bco = do |
| 80 | 80 | { unlinkedStaticConLits = lits0
|
| 81 | 81 | , unlinkedStaticConPtrs = ptrs0
|
| 82 | 82 | } -> do
|
| 83 | - Ptr itbl_ptr# <- lookupIE interp pkgs_loaded bytecode_state (unlinkedStaticConName unl_bco)
|
|
| 83 | + pprTraceM "linkBCO: linking static constructor" (ppr unl_bco)
|
|
| 84 | + Ptr itbl_ptr# <- lookupIE interp pkgs_loaded bytecode_state (unlinkedStaticConDataConName unl_bco)
|
|
| 85 | + pprTraceM "linkBCO: itbl_ptr#" (ppr (unlinkedStaticConDataConName unl_bco) <+> text (show (Ptr itbl_ptr#)))
|
|
| 84 | 86 | lits <- doLits lits0
|
| 87 | + pprTraceM "linkBCO: lits done" (empty)
|
|
| 85 | 88 | ptrs <- doPtrs ptrs0
|
| 89 | + pprTraceM "linkBCO: ptrs done" (empty)
|
|
| 86 | 90 | return ResolvedStaticCon
|
| 87 | 91 | { resolvedBCOIsLE = isLittleEndian
|
| 88 | 92 | , resolvedStaticConInfoPtr = W# (int2Word# (addr2Int# itbl_ptr#))
|
| ... | ... | @@ -99,7 +103,7 @@ linkBCO interp pkgs_loaded bytecode_state bco_ix unl_bco = do |
| 99 | 103 | mapM (resolvePtr interp pkgs_loaded bytecode_state bco_ix) (elemsFlatBag ptrs0)
|
| 100 | 104 | |
| 101 | 105 | lookupLiteral :: Interp -> PkgsLoaded -> BytecodeLoaderState -> BCONPtr -> IO Word
|
| 102 | -lookupLiteral interp pkgs_loaded bytecode_state ptr = case ptr of
|
|
| 106 | +lookupLiteral interp pkgs_loaded bytecode_state ptr = pprTrace "lookupLiteral" (ppr ptr) $ case ptr of
|
|
| 103 | 107 | BCONPtrWord lit -> return lit
|
| 104 | 108 | BCONPtrLbl sym -> do
|
| 105 | 109 | Ptr a# <- lookupStaticPtr interp sym
|
| ... | ... | @@ -183,20 +187,24 @@ resolvePtr |
| 183 | 187 | -> NameEnv (Int, Bool)
|
| 184 | 188 | -> BCOPtr
|
| 185 | 189 | -> IO ResolvedBCOPtr
|
| 186 | -resolvePtr interp pkgs_loaded bco_loader_state bco_ix ptr = case ptr of
|
|
| 190 | +resolvePtr interp pkgs_loaded bco_loader_state bco_ix ptr = pprTrace "resolvePtr" (ppr ptr) $ case ptr of
|
|
| 187 | 191 | BCOPtrName nm
|
| 188 | 192 | | Just (ix, b) <- lookupNameEnv bco_ix nm
|
| 189 | - -> if b then
|
|
| 193 | + -> if b then do
|
|
| 194 | + pprTraceM "resolvePtr: ResolvedBCORef" (ppr nm <+> ppr ix)
|
|
| 190 | 195 | return (ResolvedBCORef ix) -- ref to another BCO in this group
|
| 191 | - else
|
|
| 196 | + else do
|
|
| 197 | + pprTraceM "resolvePtr: StaticConRef" (ppr nm <+> ppr ix)
|
|
| 192 | 198 | return (ResolvedStaticConRef ix) -- ref to another StaticCon in this group
|
| 193 | 199 | |
| 194 | 200 | | Just (_, rhv) <- lookupNameBytecodeState bco_loader_state nm
|
| 195 | - -> return (ResolvedBCOPtr (unsafeForeignRefToRemoteRef rhv))
|
|
| 201 | + -> do
|
|
| 202 | + pprTraceM "resolvePtr: BCOPtr" (ppr nm)
|
|
| 203 | + return (ResolvedBCOPtr (unsafeForeignRefToRemoteRef rhv))
|
|
| 196 | 204 | |
| 197 | 205 | | otherwise
|
| 198 | 206 | -> assertPpr (isExternalName nm) (ppr nm) $
|
| 199 | - do
|
|
| 207 | + pprTrace "resolvePtr: OTHERWISE? ASSERTION FIALURE?" (ppr nm) $ do
|
|
| 200 | 208 | let sym_to_find = IClosureSymbol nm
|
| 201 | 209 | m <- lookupHsSymbol interp pkgs_loaded sym_to_find
|
| 202 | 210 | case m of
|
| ... | ... | @@ -327,6 +327,7 @@ instance Binary UnlinkedBCO where |
| 327 | 327 | <*> get bh
|
| 328 | 328 | 1 -> UnlinkedStaticCon
|
| 329 | 329 | <$> getViaBinName bh
|
| 330 | + <*> getViaBinName bh
|
|
| 330 | 331 | <*> get bh
|
| 331 | 332 | <*> get bh
|
| 332 | 333 | _ -> panic "Binary UnlinkedBCO: invalid byte"
|
| ... | ... | @@ -342,6 +343,7 @@ instance Binary UnlinkedBCO where |
| 342 | 343 | put_ bh UnlinkedStaticCon {..} = do
|
| 343 | 344 | putByte bh 1
|
| 344 | 345 | putViaBinName bh unlinkedStaticConName
|
| 346 | + putViaBinName bh unlinkedStaticConDataConName
|
|
| 345 | 347 | put_ bh unlinkedStaticConLits
|
| 346 | 348 | put_ bh unlinkedStaticConPtrs
|
| 347 | 349 |
| ... | ... | @@ -31,6 +31,7 @@ module GHC.ByteCode.Types |
| 31 | 31 | ) where
|
| 32 | 32 | |
| 33 | 33 | import GHC.Prelude
|
| 34 | +import qualified Data.ByteString.Char8 as BS8
|
|
| 34 | 35 | |
| 35 | 36 | import GHC.Data.FastString
|
| 36 | 37 | import GHC.Data.FlatBag
|
| ... | ... | @@ -259,6 +260,10 @@ data UnlinkedBCO |
| 259 | 260 | -- See Note [Static constructors in Bytecode]
|
| 260 | 261 | | UnlinkedStaticCon {
|
| 261 | 262 | unlinkedStaticConName :: !Name,
|
| 263 | + -- ^ The name to which this static constructor is bound, not to be
|
|
| 264 | + -- confused with the name of the static constructor itself
|
|
| 265 | + -- ('unlinkedStaticConDataConName')
|
|
| 266 | + unlinkedStaticConDataConName :: !Name,
|
|
| 262 | 267 | unlinkedStaticConLits :: !(FlatBag BCONPtr), -- non-ptrs
|
| 263 | 268 | unlinkedStaticConPtrs :: !(FlatBag BCOPtr) -- ptrs
|
| 264 | 269 | }
|
| ... | ... | @@ -282,6 +287,12 @@ instance NFData BCOPtr where |
| 282 | 287 | rnf (BCOPtrBCO bco) = rnf bco
|
| 283 | 288 | rnf x = x `seq` ()
|
| 284 | 289 | |
| 290 | +instance Outputable BCOPtr where
|
|
| 291 | + ppr (BCOPtrName nm) = text "BCOPtrName" <+> ppr nm
|
|
| 292 | + ppr (BCOPtrPrimOp op) = text "BCOPtrPrimOp" <+> ppr op
|
|
| 293 | + ppr (BCOPtrBCO bco) = text "BCOPtrBCO" <+> ppr bco
|
|
| 294 | + ppr (BCOPtrBreakArray mod) = text "<break array for" <+> ppr mod <> char '>'
|
|
| 295 | + |
|
| 285 | 296 | data BCONPtr
|
| 286 | 297 | = BCONPtrWord {-# UNPACK #-} !Word
|
| 287 | 298 | | BCONPtrLbl !FastString
|
| ... | ... | @@ -299,6 +310,16 @@ data BCONPtr |
| 299 | 310 | -- | A 'CostCentre' remote pointer array's respective 'BreakpointId'
|
| 300 | 311 | | BCONPtrCostCentre !InternalBreakpointId
|
| 301 | 312 | |
| 313 | +instance Outputable BCONPtr where
|
|
| 314 | + ppr (BCONPtrWord w) = integer (fromIntegral w)
|
|
| 315 | + ppr (BCONPtrLbl lbl) = text "<label:" <> ftext lbl <> char '>'
|
|
| 316 | + ppr (BCONPtrItbl nm) = text "<itbl:" <+> ppr nm <> char '>'
|
|
| 317 | + ppr (BCONPtrAddr nm) = text "<addr:" <+> ppr nm <> char '>'
|
|
| 318 | + ppr (BCONPtrStr bs) = text "<string literal: " <+> text (BS8.unpack bs) <> char '>'
|
|
| 319 | + ppr (BCONPtrFS fs) = text "<fast string literal:" <+> ftext fs <> char '>'
|
|
| 320 | + ppr (BCONPtrFFIInfo ffi) = text "<FFIInfo>"
|
|
| 321 | + ppr (BCONPtrCostCentre bid) = text "<CostCentre for BreakpointId:" <+> ppr bid <> char '>'
|
|
| 322 | + |
|
| 302 | 323 | instance NFData BCONPtr where
|
| 303 | 324 | rnf x = x `seq` ()
|
| 304 | 325 | |
| ... | ... | @@ -307,8 +328,9 @@ instance Outputable UnlinkedBCO where |
| 307 | 328 | = sep [text "BCO", ppr nm, text "with",
|
| 308 | 329 | ppr (sizeFlatBag lits), text "lits",
|
| 309 | 330 | ppr (sizeFlatBag ptrs), text "ptrs" ]
|
| 310 | - ppr (UnlinkedStaticCon nm lits ptrs)
|
|
| 311 | - = sep [text "StaticCon", ppr nm, text "with",
|
|
| 331 | + ppr (UnlinkedStaticCon nm dc_nm lits ptrs)
|
|
| 332 | + = sep [text "StaticCon", ppr nm, text "for",
|
|
| 333 | + ppr dc_nm, text "with",
|
|
| 312 | 334 | ppr (sizeFlatBag lits), text "lits",
|
| 313 | 335 | ppr (sizeFlatBag ptrs), text "ptrs" ]
|
| 314 | 336 |
| ... | ... | @@ -1048,6 +1048,13 @@ linkSomeBCOs interp pkgs_loaded bytecode_state mods = foldr fun do_link mods [] |
| 1048 | 1048 | UnlinkedStaticCon{unlinkedStaticConName} -> (unlinkedStaticConName, False)
|
| 1049 | 1049 | ) flat
|
| 1050 | 1050 | bco_ix = mkNameEnv (zipWith (\(n,isBCO) ix -> (n,(ix, isBCO))) names [0..])
|
| 1051 | + pprTraceM "linkSomeBCOs what" $ (ppr mods <+> ppr flat)
|
|
| 1052 | + pprTraceM "linkSomeBCOs" $
|
|
| 1053 | + vcat [ text "Linking BCOs:"
|
|
| 1054 | + , nest 2 (vcat (map (ppr . fst) names))
|
|
| 1055 | + , text "BCO index:"
|
|
| 1056 | + , nest 2 (ppr bco_ix)
|
|
| 1057 | + ]
|
|
| 1051 | 1058 | resolved <- sequence [ linkBCO interp pkgs_loaded bytecode_state bco_ix bco | bco <- flat ]
|
| 1052 | 1059 | hvrefs <- createBCOs interp resolved
|
| 1053 | 1060 | return (zipWith (\(n,_) hvr -> (n, hvr)) names hvrefs)
|
| ... | ... | @@ -305,15 +305,17 @@ argBits platform (rep : args) |
| 305 | 305 | -- Compile code for the right-hand side of a top-level binding
|
| 306 | 306 | |
| 307 | 307 | schemeTopBind :: (Id, CgStgRhs) -> BcM ProtoBCO
|
| 308 | -schemeTopBind (_, rhs@(StgRhsCon _ dc _ _ args _))
|
|
| 308 | +schemeTopBind (id, rhs@(StgRhsCon _ dc _ _ args _))
|
|
| 309 | 309 | = do
|
| 310 | + pprTraceM "schemeTopBind: static con" (ppr id <+> ppr dc <+> ppr args)
|
|
| 310 | 311 | profile <- getProfile
|
| 311 | 312 | let non_voids = addArgReps (assertNonVoidStgArgs args)
|
| 312 | 313 | (_, _, args_offsets)
|
| 313 | 314 | -- Compute the expected runtime ordering for the datacon fields
|
| 314 | 315 | = mkVirtConstrOffsets profile non_voids
|
| 315 | 316 | return ProtoStaticCon
|
| 316 | - { protoStaticCon = dc
|
|
| 317 | + { protoStaticConName = getName id
|
|
| 318 | + , protoStaticCon = dc
|
|
| 317 | 319 | , protoStaticConLits = [ lit | (NonVoid (StgLitArg lit), _) <- args_offsets ]
|
| 318 | 320 | , protoStaticConIds = [ i | (NonVoid (StgVarArg i), _) <- args_offsets {-, assert is never a local var -} ]
|
| 319 | 321 | , protoStaticConExpr = rhs
|