Skip to content

RTS: Pooled adjustor allocation

Ben Gamari requested to merge wip/adjustor-pool into master

Adjustors are small bits of code produced by the runtime to facilitate calls from C into Haskell, principally to implement foreign exports. As adjustors are executable code, we currently use a rather simplistic allocation strategy, allocating one page per adjustor.

However, in #20349 (closed) I noticed that some packages (e.g. terminfo, used by GHCi) allocate considerable quantities of adjustors, making this design somewhat painful. Moreover, when working on the linker changes associated with #21019 (closed) I noticed that on Windows the situation is even worse: Windows can only map memory in units of the allocation granularity, which is 64kBytes on most machines. Consequently, each adjustor, which consists of only a handful of bytes of machine code, can end up consuming 64kByte of memory. In !7448 (closed) this manifested as the failure of T10296a, which allocates 65000 adjustors (and therefore over 4GB of memory on Windows).

This MR resolves this by refactoring the allocation and construction of adjustors. We introduce a new allocator abstraction, AdjustorPool (described in Note [Adjustor pools]), which is responsible for allocating and constructing adjustors. We then refactor the AMD64 adjustor logic (for both Windows and POSIX platforms) to use this new infrastructure.

Edited by Ben Gamari

Merge request reports