Index: llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h =================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -146,13 +146,13 @@ std::error_code EC; auto TrampolineBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( - sys::Process::getPageSize(), nullptr, + sys::Process::getPageSizeEstimate(), nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); if (EC) return errorCodeToError(EC); unsigned NumTrampolines = - (sys::Process::getPageSize() - ORCABI::PointerSize) / + (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) / ORCABI::TrampolineSize; uint8_t *TrampolineMem = static_cast(TrampolineBlock.base()); Index: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h =================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h @@ -299,13 +299,13 @@ std::error_code EC; auto TrampolineBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( - sys::Process::getPageSize(), nullptr, + sys::Process::getPageSizeEstimate(), nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); if (EC) return errorCodeToError(EC); uint32_t NumTrampolines = - (sys::Process::getPageSize() - TargetT::PointerSize) / + (sys::Process::getPageSizeEstimate() - TargetT::PointerSize) / TargetT::TrampolineSize; uint8_t *TrampolineMem = static_cast(TrampolineBlock.base()); @@ -335,7 +335,7 @@ handleGetRemoteInfo() { std::string ProcessTriple = sys::getProcessTriple(); uint32_t PointerSize = TargetT::PointerSize; - uint32_t PageSize = sys::Process::getPageSize(); + uint32_t PageSize = sys::Process::getPageSizeEstimate(); uint32_t TrampolineSize = TargetT::TrampolineSize; uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize; LLVM_DEBUG(dbgs() << " Remote info:\n" Index: llvm/trunk/include/llvm/Support/Process.h =================================================================== --- llvm/trunk/include/llvm/Support/Process.h +++ llvm/trunk/include/llvm/Support/Process.h @@ -28,6 +28,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Error.h" #include namespace llvm { @@ -41,7 +42,25 @@ /// current executing process. class Process { public: - static unsigned getPageSize(); + /// Get the process's page size. + /// This may fail if the underlying syscall returns an error. In most cases, + /// page size information is used for optimization, and this error can be + /// safely discarded by calling consumeError, and an estimated page size + /// substituted instead. + static Expected getPageSize(); + + /// Get the process's estimated page size. + /// This function always succeeds, but if the underlying syscall to determine + /// the page size fails then this will silently return an estimated page size. + /// The estimated page size is guaranteed to be a power of 2. + static unsigned getPageSizeEstimate() { + if (auto PageSize = getPageSize()) + return *PageSize; + else { + consumeError(PageSize.takeError()); + return 4096; + } + } /// Return process memory usage. /// This static function will return the total amount of memory allocated Index: llvm/trunk/lib/ExecutionEngine/JITLink/JITLink.cpp =================================================================== --- llvm/trunk/lib/ExecutionEngine/JITLink/JITLink.cpp +++ llvm/trunk/lib/ExecutionEngine/JITLink/JITLink.cpp @@ -194,12 +194,12 @@ for (auto &KV : Request) { auto &Seg = KV.second; - if (Seg.getContentAlignment() > sys::Process::getPageSize()) + if (Seg.getContentAlignment() > sys::Process::getPageSizeEstimate()) return make_error("Cannot request higher than page " "alignment", inconvertibleErrorCode()); - if (sys::Process::getPageSize() % Seg.getContentAlignment() != 0) + if (sys::Process::getPageSizeEstimate() % Seg.getContentAlignment() != 0) return make_error("Page size is not a multiple of " "alignment", inconvertibleErrorCode()); Index: llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp =================================================================== --- llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp +++ llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp @@ -147,7 +147,7 @@ const unsigned StubSize = IndirectStubsInfo::StubSize; // Emit at least MinStubs, rounded up to fill the pages allocated. - unsigned PageSize = sys::Process::getPageSize(); + static const unsigned PageSize = sys::Process::getPageSizeEstimate(); unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; unsigned NumStubs = (NumPages * PageSize) / StubSize; @@ -229,7 +229,7 @@ const unsigned StubSize = IndirectStubsInfo::StubSize; // Emit at least MinStubs, rounded up to fill the pages allocated. - unsigned PageSize = sys::Process::getPageSize(); + static const unsigned PageSize = sys::Process::getPageSizeEstimate(); unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; unsigned NumStubs = (NumPages * PageSize) / StubSize; @@ -497,7 +497,7 @@ const unsigned StubSize = IndirectStubsInfo::StubSize; // Emit at least MinStubs, rounded up to fill the pages allocated. - unsigned PageSize = sys::Process::getPageSize(); + static const unsigned PageSize = sys::Process::getPageSizeEstimate(); unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; unsigned NumStubs = (NumPages * PageSize) / StubSize; @@ -683,7 +683,7 @@ const unsigned StubSize = IndirectStubsInfo::StubSize; // Emit at least MinStubs, rounded up to fill the pages allocated. - unsigned PageSize = sys::Process::getPageSize(); + static const unsigned PageSize = sys::Process::getPageSizeEstimate(); unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; unsigned NumStubs = (NumPages * PageSize) / StubSize; @@ -929,7 +929,7 @@ const unsigned StubSize = IndirectStubsInfo::StubSize; // Emit at least MinStubs, rounded up to fill the pages allocated. - unsigned PageSize = sys::Process::getPageSize(); + static const unsigned PageSize = sys::Process::getPageSizeEstimate(); unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; unsigned NumStubs = (NumPages * PageSize) / StubSize; Index: llvm/trunk/lib/ExecutionEngine/SectionMemoryManager.cpp =================================================================== --- llvm/trunk/lib/ExecutionEngine/SectionMemoryManager.cpp +++ llvm/trunk/lib/ExecutionEngine/SectionMemoryManager.cpp @@ -172,7 +172,7 @@ } static sys::MemoryBlock trimBlockToPageSize(sys::MemoryBlock M) { - static const size_t PageSize = sys::Process::getPageSize(); + static const size_t PageSize = sys::Process::getPageSizeEstimate(); size_t StartOverlap = (PageSize - ((uintptr_t)M.base() % PageSize)) % PageSize; @@ -244,7 +244,7 @@ unsigned Flags, std::error_code &EC) override { // allocateMappedMemory calls mmap(2). We round up a request size // to page size to get extra space for free. - static const size_t PageSize = sys::Process::getPageSize(); + static const size_t PageSize = sys::Process::getPageSizeEstimate(); size_t ReqBytes = (NumBytes + PageSize - 1) & ~(PageSize - 1); return sys::Memory::allocateMappedMemory(ReqBytes, NearBlock, Flags, EC); } Index: llvm/trunk/lib/Support/MemoryBuffer.cpp =================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp +++ llvm/trunk/lib/Support/MemoryBuffer.cpp @@ -417,7 +417,7 @@ getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, bool IsVolatile) { - static int PageSize = sys::Process::getPageSize(); + static int PageSize = sys::Process::getPageSizeEstimate(); // Default is to map the full file. if (MapSize == uint64_t(-1)) { Index: llvm/trunk/lib/Support/Unix/Memory.inc =================================================================== --- llvm/trunk/lib/Support/Unix/Memory.inc +++ llvm/trunk/lib/Support/Unix/Memory.inc @@ -103,7 +103,7 @@ // Use any near hint and the page size to set a page-aligned starting address uintptr_t Start = NearBlock ? reinterpret_cast(NearBlock->base()) + NearBlock->size() : 0; - static const size_t PageSize = Process::getPageSize(); + static const size_t PageSize = Process::getPageSizeEstimate(); if (Start && Start % PageSize) Start += PageSize - Start % PageSize; @@ -149,7 +149,7 @@ std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { - static const size_t PageSize = Process::getPageSize(); + static const size_t PageSize = Process::getPageSizeEstimate(); if (M.Address == nullptr || M.Size == 0) return std::error_code(); Index: llvm/trunk/lib/Support/Unix/Path.inc =================================================================== --- llvm/trunk/lib/Support/Unix/Path.inc +++ llvm/trunk/lib/Support/Unix/Path.inc @@ -786,7 +786,7 @@ } int mapped_file_region::alignment() { - return Process::getPageSize(); + return Process::getPageSizeEstimate(); } std::error_code detail::directory_iterator_construct(detail::DirIterState &it, Index: llvm/trunk/lib/Support/Unix/Process.inc =================================================================== --- llvm/trunk/lib/Support/Unix/Process.inc +++ llvm/trunk/lib/Support/Unix/Process.inc @@ -69,7 +69,7 @@ // On Cygwin, getpagesize() returns 64k(AllocationGranularity) and // offset in mmap(3) should be aligned to the AllocationGranularity. -unsigned Process::getPageSize() { +Expected Process::getPageSize() { #if defined(HAVE_GETPAGESIZE) static const int page_size = ::getpagesize(); #elif defined(HAVE_SYSCONF) @@ -77,6 +77,9 @@ #else #error Cannot get the page size on this machine #endif + if (page_size == -1) + return errorCodeToError(std::error_code(errno, std::generic_category())); + return static_cast(page_size); } Index: llvm/trunk/lib/Support/Windows/Process.inc =================================================================== --- llvm/trunk/lib/Support/Windows/Process.inc +++ llvm/trunk/lib/Support/Windows/Process.inc @@ -56,7 +56,7 @@ return static_cast(info.dwPageSize); } -unsigned Process::getPageSize() { +Expected Process::getPageSize() { static unsigned Ret = computePageSize(); return Ret; } Index: llvm/trunk/unittests/Support/MemoryTest.cpp =================================================================== --- llvm/trunk/unittests/Support/MemoryTest.cpp +++ llvm/trunk/unittests/Support/MemoryTest.cpp @@ -50,7 +50,7 @@ public: MappedMemoryTest() { Flags = GetParam(); - PageSize = sys::Process::getPageSize(); + PageSize = sys::Process::getPageSizeEstimate(); } protected: