From ab5e6e7434ebc67e89332d4401926978c8fb143b Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 28 Sep 2021 10:25:11 -0700 Subject: [PATCH] [llvm-jitlink] Add a -slab-page-size option to override process page 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(). --- llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 62 +++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index 127a214..8e678d3 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -150,6 +150,11 @@ static cl::opt SlabAddress( cl::desc("Set slab target address (requires -slab-allocate and -noexec)"), cl::init(~0ULL), cl::cat(JITLinkCategory)); +static cl::opt 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 ShowRelocatedSectionContents( "show-relocated-section-contents", cl::desc("show section contents after fixups have been applied"), @@ -464,7 +469,21 @@ private: 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("Page size is zero", + inconvertibleErrorCode()); + return; + } + } else + PageSize = SlabPageSize; if (!isPowerOf2_64(PageSize)) { Err = make_error("Page size is not a power of 2", @@ -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( + "-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( "-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("-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( + "-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. -- 2.7.4