[JIT] Towards a working small memory model.

This commit introduces an option, --preallocate, so that we can get memory
upfront and use it in small memory model tests (in order to get
reliable results).

Differential Revision:	http://reviews.llvm.org/D13630


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250956 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Davide Italiano 2015-10-21 22:12:03 +00:00
parent 110f55db52
commit 8c651fbc41

View File

@ -93,6 +93,11 @@ CheckFiles("check",
cl::desc("File containing RuntimeDyld verifier checks."),
cl::ZeroOrMore);
static cl::opt<uint64_t>
PreallocMemory("preallocate",
cl::desc("Allocate memory upfront rather than on-demand"),
cl::init(0));
static cl::opt<uint64_t>
TargetAddrStart("target-addr-start",
cl::desc("For -verify only: start of phony target address "
@ -173,14 +178,48 @@ public:
size_t Size) override {}
void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) override {}
void preallocateSlab(uint64_t Size) {
std::string Err;
sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err);
if (!MB.base())
report_fatal_error("Can't allocate enough memory: " + Err);
PreallocSlab = MB;
UsePreallocation = true;
SlabSize = Size;
}
uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode) {
Size = RoundUpToAlignment(Size, Alignment);
if (CurrentSlabOffset + Size > SlabSize)
report_fatal_error("Can't allocate enough memory. Tune --preallocate");
uintptr_t OldSlabOffset = CurrentSlabOffset;
sys::MemoryBlock MB((void *)OldSlabOffset, Size);
if (isCode)
FunctionMemory.push_back(MB);
else
DataMemory.push_back(MB);
CurrentSlabOffset += Size;
return (uint8_t*)OldSlabOffset;
}
private:
std::map<std::string, uint64_t> DummyExterns;
sys::MemoryBlock PreallocSlab;
bool UsePreallocation = false;
uintptr_t SlabSize = 0;
uintptr_t CurrentSlabOffset = 0;
};
uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
unsigned Alignment,
unsigned SectionID,
StringRef SectionName) {
if (UsePreallocation)
return allocateFromSlab(Size, Alignment, true /* isCode */);
std::string Err;
sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err);
if (!MB.base())
@ -194,6 +233,9 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
unsigned SectionID,
StringRef SectionName,
bool IsReadOnly) {
if (UsePreallocation)
return allocateFromSlab(Size, Alignment, false /* isCode */);
std::string Err;
sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err);
if (!MB.base())
@ -332,12 +374,24 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
return 0;
}
static void doPreallocation(TrivialMemoryManager &MemMgr) {
// Allocate a slab of memory upfront, if required. This is used if
// we want to test small code models.
if (static_cast<intptr_t>(PreallocMemory) < 0)
report_fatal_error("Pre-allocated bytes of memory must be a positive integer.");
// FIXME: Limit the amount of memory that can be preallocated?
if (PreallocMemory != 0)
MemMgr.preallocateSlab(PreallocMemory);
}
static int executeInput() {
// Load any dylibs requested on the command line.
loadDylibs();
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
doPreallocation(MemMgr);
RuntimeDyld Dyld(MemMgr, MemMgr);
// FIXME: Preserve buffers until resolveRelocations time to work around a bug
@ -613,6 +667,7 @@ static int linkAndVerify() {
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
doPreallocation(MemMgr);
RuntimeDyld Dyld(MemMgr, MemMgr);
Dyld.setProcessAllSections(true);
RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(),