// Allocate the GOT.
GOTBase = NULL;
- if (useGOT) GOTBase = (unsigned char*)malloc(sizeof(void*) * 8192);
+ if (useGOT) GOTBase = new unsigned char[sizeof(void*) * 8192];
}
JITMemoryManager::~JITMemoryManager() {
for (unsigned i = 0, e = Blocks.size(); i != e; ++i)
sys::Memory::ReleaseRWX(Blocks[i]);
+
+ delete[] GOTBase;
Blocks.clear();
}
}
sys::MemoryBlock JITMemoryManager::getNewMemoryBlock(unsigned size) {
- try {
- // Allocate a new block close to the last one.
- const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front();
- sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld);
- Blocks.push_back(B);
- return B;
- } catch (std::string &err) {
+ // Allocate a new block close to the last one.
+ const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front();
+ std::string ErrMsg;
+ sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld, &ErrMsg);
+ if (B.base() == 0) {
std::cerr << "Allocation failed when allocating new memory in the JIT\n";
- std::cerr << err << "\n";
+ std::cerr << ErrMsg << "\n";
abort();
}
+ Blocks.push_back(B);
+ return B;
}
//===----------------------------------------------------------------------===//
MutexGuard locked(TheJIT->lock);
/// Get the target-specific JIT resolver function.
state.getStubToFunctionMap(locked)[Location] = F;
- return (void*)LazyResolverFn;
+ return (void*)(intptr_t)LazyResolverFn;
}
/// getGOTIndexForAddress - Return a new or existing index in the GOT for
return TheJITResolver;
}
+#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
+ defined(__APPLE__)
+extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
+#endif
+
+/// synchronizeICache - On some targets, the JIT emitted code must be
+/// explicitly refetched to ensure correct execution.
+static void synchronizeICache(const void *Addr, size_t len) {
+#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
+ defined(__APPLE__)
+ sys_icache_invalidate(Addr, len);
+#endif
+}
+
/// getFunctionStub - This returns a pointer to a function stub, creating
/// one on demand as needed.
void *JITResolver::getFunctionStub(Function *F) {
// Call the lazy resolver function unless we already KNOW it is an external
// function, in which case we just skip the lazy resolution step.
- void *Actual = (void*)LazyResolverFn;
+ void *Actual = (void*)(intptr_t)LazyResolverFn;
if (F->isExternal() && F->hasExternalLinkage())
Actual = TheJIT->getPointerToFunction(F);
// resolver function.
Stub = TheJIT->getJITInfo().emitFunctionStub(Actual, MCE);
- if (Actual != (void*)LazyResolverFn) {
+ if (Actual != (void*)(intptr_t)LazyResolverFn) {
// If we are getting the stub for an external function, we really want the
// address of the stub in the GlobalAddressMap for the JIT, not the address
// of the external function.
TheJIT->updateGlobalMapping(F, Stub);
}
+ // Invalidate the icache if necessary.
+ synchronizeICache(Stub, MCE.getCurrentPCValue()-(intptr_t)Stub);
+
DEBUG(std::cerr << "JIT: Stub emitted at [" << Stub << "] for function '"
<< F->getName() << "'\n");
if (Stub) return Stub;
Stub = TheJIT->getJITInfo().emitFunctionStub(FnAddr, MCE);
+
+ // Invalidate the icache if necessary.
+ synchronizeICache(Stub, MCE.getCurrentPCValue()-(intptr_t)Stub);
+
DEBUG(std::cerr << "JIT: Stub emitted at [" << Stub
<< "] for external function at '" << FnAddr << "'\n");
return Stub;
// About to start emitting the machine code for the function.
emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
-
+
MBBLocations.clear();
}
emitJumpTableInfo(F.getJumpTableInfo());
- MemMgr.endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
- NumBytes += getCurrentPCOffset();
+ // FnStart is the start of the text, not the start of the constant pool and
+ // other per-function data.
+ unsigned char *FnStart =
+ (unsigned char *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction());
+ unsigned char *FnEnd = CurBufferPtr;
+
+ MemMgr.endFunctionBody(F.getFunction(), BufferBegin, FnEnd);
+ NumBytes += FnEnd-FnStart;
if (!Relocations.empty()) {
NumRelos += Relocations.size();
ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
BufferBegin+MR.getMachineCodeOffset(),
MR.doesntNeedFunctionStub());
- } else {
- assert(MR.isConstantPoolIndex());
+ } else if (MR.isBasicBlock()) {
+ ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock());
+ } else if (MR.isConstantPoolIndex()){
ResultPtr=(void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex());
+ } else {
+ assert(MR.isJumpTableIndex());
+ ResultPtr=(void*)getJumpTableEntryAddress(MR.getJumpTableIndex());
}
MR.setResultPointer(ResultPtr);
}
}
- DEBUG(std::cerr << "JIT: Finished CodeGen of [" << (void*)BufferBegin
+ // Invalidate the icache if necessary.
+ synchronizeICache(FnStart, FnEnd-FnStart);
+
+ DEBUG(std::cerr << "JIT: Finished CodeGen of [" << (void*)FnStart
<< "] Function: " << F.getFunction()->getName()
- << ": " << getCurrentPCOffset() << " bytes of text, "
+ << ": " << (FnEnd-FnStart) << " bytes of text, "
<< Relocations.size() << " relocations\n");
Relocations.clear();
return false;