This is the second edition of our new GHC activities report, which is intended to provide regular updates on the work on GHC and related projects that we are doing at Well-Typed. This edition covers roughly the months August and September 2020. The first update covered June and July 2020.
A bit of background: One aspect of our work at Well-Typed is to support GHC and the Haskell core infrastructure. Several companies, including IOHK and Facebook, are providing us with funding to do this work. We also recently announced a partnership with Hasura with a focus on working toward better debugging tools. We are very grateful on behalf of the whole Haskell community for the support these companies provide.
If you are interested in also contributing funding to ensure we can continue or even scale up this kind of work, please get in touch.
Of course, GHC is a large community effort, and Well-Typed’s contributions are just a small part of this. This report does not aim to give an exhaustive picture of all GHC work that is ongoing, and there are many fantastic features currently being worked on that are omitted here simply because none of us are currently involved in them in any way. Furthermore, the aspects we do mention are still the work of many people. In many cases, we have just been helping with the last few steps of integration. We are immensely grateful to everyone contributing to GHC. Please keep doing so (or start)!
Release management
The GHC 9.0 release is getting closer. We have been working on various aspects of release engineering, including the first alpha release in the GHC 9.0 series. (Ben)
Runtime performance and measurement
- Revisiting default value of
+RTS -A
(!3678) (Andreas). Over the past decade cache sizes have continued to grow and cache hierachies have deepened. To take advantage of these changes, we are examining the default allocation area size used by GHC’s storage manager. After a significant amount of benchmarking looking at a variety of configurations, we have settled on raising the default storage allocation area size from 1 MiB to 4 MiB. Not only will this improve out-of-the-box scalability of parallel programs but it also has a nice non-trivial impact on GHC compilation time of larger programs. - Revamping
nofib
build system (Andreas).nofib
is one of the three performance benchmarks we use to characterise GHC’s performance. However, its dated build system makes usage slower and more difficult than necessary. Andreas has been working on finishing a rewrite of this build system in Shake, enabling exploitation of parallelism (useful when running tests undercachegrind
), measurement of performance monitoring unit counters, and a significantly more convenient output format. - Bottom cost-center profiling (#18566) (Ben). While working on GHC performance issues in the past we have often encountered situations where it would be helpful to identify all call-sites of a particular function. This is enabled by a feature implemented by Ben, introducing a new compiler flag allowing users to request that cost-centers be automatically added to all call-sites of a specified function.
- There have been some improvements to the selection of baseline values for performance tests (#18484) (Ben).
Portability and infrastructure
- Ben has done some initial work bringing up GHC on MacOS on ARM in our Apple Developer Transition Kit environment.
- Fix GHC binary distribution support on Raspberry Pi OS / Raspbian (#17856) (Ben). This allows GHC binary distributions to work out of the box on the ubiquitous Raspbian Linux distribution.
- Rework of Docker images (Ben). As the number of configurations encompassed by GHC’s continuous integration infrastructure has grown, various inconsistencies have crept into the Docker environments in which these builds run. To eliminate these we have consolidated the Dockerfiles responsible for these environments, generating them via Dhall.
- Updating Windows toolchain (Ben). GHC provides its own patched
gcc
toolchain on Windows to work-around various platform limitations (e.g. theMAX_PATH
limit). Before every release we update this toolchain and fix the breakage (#18774) that often results. - Test Hadrian via Stack (Ben). As part of the preparation to switch over to Hadrian as GHC’s primary build system, we want to raise assurances that users will be able to compile the build system. As the Stack build has broken numerous times in the past (e.g. #18726), we now test this via CI.
- Ben has resolved the last failing tests on Windows, allowing Windows to be marked as a mandatory CI-green platform.
Bug fixes
- Debugging Windows stack corruption and refactoring of initializers (#18548) (Ben).
Fix GHC’s implementation of foreign function exports to avoid calls into
libc
during object loading. This fixes a stack corruption bug on Windows. - Refactoring of object merging (Ben). GHCi’s linker tends to be quite slow when loading objects compiled with function sections enabled. For this reason, GHC also produces “GHCi objects” where function sections have been merged. However, this feature has introduced a number of unfortunate toolchain interactions (e.g. #17962, #18550). To avoid these we have refactored GHC’s object merging logic to ensure that we only pass self-consistent flag-sets to the linker.
- Further refinement of simplification around
runRW#
(#15127, #18291) (Ben). - Refactoring of
RebindableSyntax
(#17582) (Alp).RebindableSyntax
is a source of significant implementation complexity within GHC and has consequently been a significant source of bugs. Alp has been working on refactoring much of this complexity away by introducing a way to typecheck some desugared code while reporting the original code in error message. There is a working reimplementation of “rebindable if” that uses the new mechanism, as well as an almost complete reimplementation of “rebindable monad operations”. - Implement unloading support for dynamic objects, fix unloading support for static objects (#16525) (Ben). GHCi has long supported unloading of static objects. However, there were known cases where such unloading could result in unsound garbage collection. Furthermore, dynamic object unloading was not supported at all. Ben has refactored the linker’s code unloading support, eliminating the potential for unsoundness and implementing unloading of dynamic objects.
- Diagnosing non-moving GC bug (#18587) (Ben). Currently, we are working with an issue reporter to
diagnose apparent unsoundness in a STM-heavy parallel application when run with the non-moving
garbage collector. This effort has already resulted in the fixing of a missing barrier in the
TVar
mutation codepath, although there is apparently more to be done here.
Debugging tools
Now that Well-Typed has partnered up with Hasura, we
(primarily David) have
started working toward better debugging tools. This effort is currently focused
on the ghc-debug library which allows
connecting to a remote Haskell process, pausing it, making queries to the remote
heap, then resuming it again. To achieve this, we first need support from the
runtime system. We’ve picked up work on GHC MR
!1435 to implement
the relevant API changes. So far we’ve made sure that the exposed API is simple,
thread safe, and that correct usage is documented. We’re also working on the
ghc-heap
part of the MR which enables decoding remote heap objects without
sending the garbage collector into a segfault.
GHC proposals
Decorate exceptions with backtrace information
We want to ensure that exceptions report provenance information by default without requiring action on the part of the thrower by leveraging the existing mechanisms for collecting backtraces (HasCallStack
, GHC.Stack.CCS
, and DWARF debug information). Furthermore, we want to ensure that this information is available for consumption in structured form by the user program, to allow use by logging libraries. (Ben, David)
Simplify DuplicateRecordFields
This proposal addresses an unsatisfactory aspect of DuplicateRecordFields
, namely the unclear rules around when a field selector or update will be accepted, by entirely removing the type-directed name resolution aspect. This proposal is more restrictive than a previous (dormant) simplification proposal, allowing fewer programs, but correspondingly simpler. (Adam)