Skip to content

Commit

Permalink
[llvm-jitlink] Add a -slab-page-size option to override process page …
Browse files Browse the repository at this point in the history
…size.

The slab allocator is frequently used in -noexec tests where we want a
consistent memory layout. In this context we also want to set the effective
page size, rather than using the page size of the host process, since not all
systems use the same page size. The -slab-page-size option allows us to set
the page size for such tests.

The -slab-page-size option will also be honored in exec mode when using the
slab allocator, but will trigger an error if the requested size is not a
multiple of the actual process page size.

This option was motivated by test failures on a ppc64 bot that was returning
zero from sys::Process::getPageSize(), so it also contains a check for errors
and zero results from that function if the -slab-page-size option is absent.

Existing slab allocator tests will be updated to use this option in a follow-up
commit so that we can point the failing bot at this commit and observe errors
associated with sys::Process::getPageSize().
  • Loading branch information
lhames committed Sep 28, 2021
1 parent 9e7fdcb commit ab5e6e7
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion llvm/tools/llvm-jitlink/llvm-jitlink.cpp
Expand Up @@ -150,6 +150,11 @@ static cl::opt<uint64_t> SlabAddress(
cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
cl::init(~0ULL), cl::cat(JITLinkCategory));

static cl::opt<uint64_t> SlabPageSize(
"slab-page-size",
cl::desc("Set page size for slab (requires -slab-allocate and -noexec)"),
cl::init(0), cl::cat(JITLinkCategory));

static cl::opt<bool> ShowRelocatedSectionContents(
"show-relocated-section-contents",
cl::desc("show section contents after fixups have been applied"),
Expand Down Expand Up @@ -464,7 +469,21 @@ class JITLinkSlabAllocator final : public JITLinkMemoryManager {
JITLinkSlabAllocator(uint64_t SlabSize, Error &Err) {
ErrorAsOutParameter _(&Err);

PageSize = sys::Process::getPageSizeEstimate();
if (!SlabPageSize) {
if (auto PageSizeOrErr = sys::Process::getPageSize())
PageSize = *PageSizeOrErr;
else {
Err = PageSizeOrErr.takeError();
return;
}

if (PageSize == 0) {
Err = make_error<StringError>("Page size is zero",
inconvertibleErrorCode());
return;
}
} else
PageSize = SlabPageSize;

if (!isPowerOf2_64(PageSize)) {
Err = make_error<StringError>("Page size is not a power of 2",
Expand Down Expand Up @@ -1082,12 +1101,53 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
if (EntryPointName.empty())
EntryPointName = TT.getObjectFormat() == Triple::MachO ? "_main" : "main";

// If -slab-allocate is passed, check that we're not trying to use it in
// -oop-executor or -oop-executor-connect mode.
//
// FIXME: Remove once we enable remote slab allocation.
if (SlabAllocateSizeString != "") {
if (OutOfProcessExecutor.getNumOccurrences() ||
OutOfProcessExecutorConnect.getNumOccurrences())
return make_error<StringError>(
"-slab-allocate cannot be used with -oop-executor or "
"-oop-executor-connect",
inconvertibleErrorCode());
}

// If -slab-address is passed, require -slab-allocate and -noexec
if (SlabAddress != ~0ULL) {
if (SlabAllocateSizeString == "" || !NoExec)
return make_error<StringError>(
"-slab-address requires -slab-allocate and -noexec",
inconvertibleErrorCode());

errs() << "Warning: -slab-address used without -slab-page-size.\n";
}

if (SlabPageSize != 0) {
// -slab-page-size requires slab alloc.
if (SlabAllocateSizeString == "")
return make_error<StringError>("-slab-page-size requires -slab-allocate",
inconvertibleErrorCode());

// Check -slab-page-size / -noexec interactions.
if (!NoExec) {
if (auto RealPageSize = sys::Process::getPageSize()) {
if (SlabPageSize % *RealPageSize)
return make_error<StringError>(
"-slab-page-size must be a multiple of real page size for exec "
"tests (did you mean to use -noexec ?)\n",
inconvertibleErrorCode());
} else {
errs() << "Could not retrieve process page size:\n";
logAllUnhandledErrors(RealPageSize.takeError(), errs(), "");
errs() << "Executing with slab page size = "
<< formatv("{0:x}", SlabPageSize) << ".\n"
<< "Tool may crash if " << formatv("{0:x}", SlabPageSize)
<< " is not a multiple of the real process page size.\n"
<< "(did you mean to use -noexec ?)";
}
}
}

// Only one of -oop-executor and -oop-executor-connect can be used.
Expand Down

0 comments on commit ab5e6e7

Please sign in to comment.