Skip to content
Snippets Groups Projects
Forked from Glasgow Haskell Compiler / GHC
408 commits behind the upstream repository.
  • Ben Gamari's avatar
    a104508d
    rts: Allow ExecPage to allocate anywhere in address space · a104508d
    Ben Gamari authored and Marge Bot's avatar Marge Bot committed
    Currently the ExecPage facility has two users:
    
     * GHCi, for constructing info tables, and
     * the adjustor allocation path
    
    Despite neither of these have any spatial locality constraints ExecPage
    was using the linker's `mmapAnonForLinker`, which tries hard to ensure
    that mappings end up nearby the executable image. This makes adjustor
    allocation needlessly subject to fragmentation concerns.
    
    We now instead return less constrained mappings, improving the
    robustness of the mechanism.
    
    Addresses #25503.
    a104508d
    History
    rts: Allow ExecPage to allocate anywhere in address space
    Ben Gamari authored and Marge Bot's avatar Marge Bot committed
    Currently the ExecPage facility has two users:
    
     * GHCi, for constructing info tables, and
     * the adjustor allocation path
    
    Despite neither of these have any spatial locality constraints ExecPage
    was using the linker's `mmapAnonForLinker`, which tries hard to ensure
    that mappings end up nearby the executable image. This makes adjustor
    allocation needlessly subject to fragmentation concerns.
    
    We now instead return less constrained mappings, improving the
    robustness of the mechanism.
    
    Addresses #25503.
ExecPage.c 597 B
/*
 * Utilities for managing dynamically-allocated executable pages.
 *
 * These are primarily used to back the adjustor code produced by the native
 * adjustor implementations.
 */

#include "Rts.h"
#include "sm/OSMem.h"
#include "linker/MMap.h"

ExecPage *allocateExecPage(void) {
    ExecPage *page = (ExecPage *) mmapAnon(getPageSize());
    return page;
}

void freezeExecPage(ExecPage *page) {
    mprotectForLinker(page, getPageSize(), MEM_READ_EXECUTE);
    flushExec(getPageSize(), page);
}

void freeExecPage(ExecPage *page) {
    munmapForLinker(page, getPageSize(), "freeExecPage");
}