Skip to content

Avoid serializing ResolvedBCOs in InternalInterpreter mode

While working on !10841, I noticed that the GHCi.Message includes the following comment:

-- | Create a set of BCO objects, and return HValueRefs to them
-- Note: Each ByteString contains a Binary-encoded [ResolvedBCO], not
-- a ResolvedBCO. The list is to allow us to serialise the ResolvedBCOs
-- in parallel. See @createBCOs@ in compiler/GHC/Runtime/Interpreter.hs.
CreateBCOs :: [LB.ByteString] -> Message [HValueRef]

Indeed, GHC.Runtime.Interpreter.createBCOs includes a corresponding comment that says

-- Serializing ResolvedBCO is expensive, so we do it in parallel

and it uses some par-based parallelism to serialize the BCOs in chunks of 100 at a time.

Unfortunately, this is not really the right way to implement this parallelism. Since the serialization is baked into the type of CreateBCOs, it is always performed, even in InternalInterpreter mode. Since the comment says it is “expensive”, this seems like it might be introducing a lot of pointless overhead for no reason!

A better approach would be to implement this parallelism in putMessage and getMessage, as that’s where serialization logic actually belongs. The CreateBCOs constructor can be given the more useful type [ResolvedBCOs] -> Message [HValueRef], and the conversion to and from ByteString chunks can be handled entirely in the encoding.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information