Skip to main content

IOG GHC Update #6

ยท 3 min read

Biweekly update from the GHC DevX team at IOG.

Previous updates can be found here.

JavaScript backendโ€‹

Port of GHCJS's Callback featureโ€‹

Josh: opened an MR for porting GHCJS's GHCJS.Foreign.Callback module into the JavaScript backend. The Callback type allows for passing Haskell functions into the FFI using standard JavaScript-styled function arguments - where compiled functions usually use global variables as registers to pass arguments. By passing functions into FFI imports and storing references to the functions, we can enable a form of FFI "exports" - since the passed functions allow JavaScript code to call back into Haskell code.

This MR additionally adds user guide documentation for both callbacks, and general JavaScript FFI usage.

We're currently awaiting the results of a CLC proposal before the merge can be completed.

See the following links for more information:

Pipeline refactoring and new IRโ€‹

Jeff: Began to lay the foundation for splitting the DSL in the JavaScript backend by segregating code generation to a new, basically identical DSL. The motivation is that by splitting the existing DSL, we can now replace the old DSL while still providing working builds. This is the first step in a multistep plan that eventually ends with GHCJS's optimizer and a typed sunroof based DSL. MR is up

Faster weak references implementation?โ€‹

Luite: investigated replacing heap traversal with newer JS feature.

ES2021 has new functionality for weak references and finalization. These do not directly map to Haskell weak references and finalizers, but it's probably possible to use them to avoid a lot of the expensive heap scanning that we currently do.

It's not yet clear whether we can completely remove the heap scanning while exactly preserving the current semantics for weak references.

Testsuite and cleanupโ€‹

Sylvain: removed dead code in the JS RTS !10102

Sylvain: did some triage of tests in GHC's testsuite failing with the JS backend. See tickets #22370, #22374, #22576, and merge requests !10148, !10150.

Code generator and performanceโ€‹

Jeff: tested changing the code generator to generate let instead of var. This led to a large performance regression (~20%), which was not isolated to any single function (via a ticky profile in node). The working hypothesis is that let requires more work when allocating closures because the JavaScript engine needs to ensure all variables are lexically scoped. We have not confirmed that this is the cause yet, but we did find that we generate closures that are allocated at runtime in the code generated for base. So after review we decided to leave the vars and not generate lets. Unless we begin to observe issues around scoping, using the safer construct seems to be too much of a performance hit.


Jeff: Revived Data structure work in GHC.Unit.State resulting in -1.7% reduction in allocations (by geometric average) and -9% in some cases. MR is here and ready to land, just needs to upstream a single-line patch to haddock.