allocate executable memory area all at once to ensure it is contiguous, since immediate relative jumps on PowerPC can only cross 2^26 bytes of memory

This commit is contained in:
Joel Dice 2009-03-07 12:03:27 -07:00
parent fd7bef7db3
commit 0aaee96479

View File

@ -63,6 +63,8 @@ const unsigned VisitSignalIndex = 0;
const unsigned SegFaultSignalIndex = 1; const unsigned SegFaultSignalIndex = 1;
const unsigned InterruptSignalIndex = 2; const unsigned InterruptSignalIndex = 2;
const unsigned ExecutableAreaSizeInBytes = 16 * 1024 * 1024;
class MySystem; class MySystem;
MySystem* system; MySystem* system;
@ -514,7 +516,12 @@ class MySystem: public System {
System::Library* next_; System::Library* next_;
}; };
MySystem(): threadVisitor(0), visitTarget(0) { MySystem():
threadVisitor(0),
visitTarget(0),
executableArea(0),
executableOffset(0)
{
expect(this, system == 0); expect(this, system == 0);
system = this; system = this;
@ -552,29 +559,33 @@ class MySystem: public System {
} }
virtual void* tryAllocateExecutable(unsigned sizeInBytes) { virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
assert(this, sizeInBytes % LikelyPageSizeInBytes == 0); if (executableArea == 0) {
#ifdef __x86_64__ #ifdef __x86_64__
const unsigned Extra = MAP_32BIT; const unsigned Extra = MAP_32BIT;
#else #else
const unsigned Extra = 0; const unsigned Extra = 0;
#endif #endif
void* p = mmap(0, ExecutableAreaSizeInBytes, PROT_EXEC | PROT_READ
| PROT_WRITE, MAP_PRIVATE | MAP_ANON | Extra, -1, 0);
void* p = mmap(0, sizeInBytes, PROT_EXEC | PROT_READ | PROT_WRITE, if (p != MAP_FAILED) {
MAP_PRIVATE | MAP_ANON | Extra, -1, 0); executableArea = static_cast<uint8_t*>(p);
}
}
if (p == MAP_FAILED) { if (executableArea
return 0; and executableOffset + pad(sizeInBytes) < ExecutableAreaSizeInBytes)
{
void* r = executableArea + executableOffset;
executableOffset += pad(sizeInBytes);
return r;
} else { } else {
return p; return 0;
} }
} }
virtual void freeExecutable(const void* p, unsigned sizeInBytes) { virtual void freeExecutable(const void*, unsigned) {
assert(this, sizeInBytes % LikelyPageSizeInBytes == 0); // ignore
int r UNUSED = munmap(const_cast<void*>(p), sizeInBytes);
assert(this, r == 0);
} }
virtual bool success(Status s) { virtual bool success(Status s) {
@ -769,10 +780,14 @@ class MySystem: public System {
registerHandler(0, VisitSignalIndex); registerHandler(0, VisitSignalIndex);
system = 0; system = 0;
if (executableArea) {
int r UNUSED = munmap(executableArea, ExecutableAreaSizeInBytes);
assert(this, r == 0);
}
::free(this); ::free(this);
} }
class NullSignalHandler: public SignalHandler { class NullSignalHandler: public SignalHandler {
virtual bool handleSignal(void**, void**, void**, void**) { return false; } virtual bool handleSignal(void**, void**, void**, void**) { return false; }
} nullHandler; } nullHandler;
@ -783,6 +798,9 @@ class MySystem: public System {
ThreadVisitor* threadVisitor; ThreadVisitor* threadVisitor;
Thread* visitTarget; Thread* visitTarget;
System::Monitor* visitLock; System::Monitor* visitLock;
uint8_t* executableArea;
unsigned executableOffset;
}; };
void void