summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJeffrey Yasskin <jyasskin@google.com>2009-11-23 22:49:00 +0000
committerJeffrey Yasskin <jyasskin@google.com>2009-11-23 22:49:00 +0000
commit0261d795f83a45dd53d82e511ae672d6d1f4e298 (patch)
tree04b08bde023562acfc4bf23d227fbfa6fe2e2b5e /lib
parentf81bf15552d3df7dd341e3970a002b9e35ea4992 (diff)
downloadllvm-0261d795f83a45dd53d82e511ae672d6d1f4e298.tar.gz
llvm-0261d795f83a45dd53d82e511ae672d6d1f4e298.tar.bz2
llvm-0261d795f83a45dd53d82e511ae672d6d1f4e298.tar.xz
Allow more than one stub to be being generated at the same time.
It's probably better in the long run to replace the indirect-GlobalVariable system. That'll be done after a subsequent patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89708 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp45
-rw-r--r--lib/Target/ARM/ARMJITInfo.cpp14
-rw-r--r--lib/Target/Alpha/AlphaJITInfo.cpp5
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp9
-rw-r--r--lib/Target/X86/X86JITInfo.cpp25
5 files changed, 46 insertions, 52 deletions
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index aabab98dcc..f34ae00f8b 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -268,10 +268,6 @@ namespace {
class JITEmitter : public JITCodeEmitter {
JITMemoryManager *MemMgr;
- // When outputting a function stub in the context of some other function, we
- // save BufferBegin/BufferEnd/CurBufferPtr here.
- uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
-
// When reattempting to JIT a function after running out of space, we store
// the estimated size of the function we're trying to JIT here, so we can
// ask the memory manager for at least this much space. When we
@@ -397,11 +393,11 @@ namespace {
void initJumpTableInfo(MachineJumpTableInfo *MJTI);
void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
- virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
- unsigned Alignment = 1);
- virtual void startGVStub(const GlobalValue* GV, void *Buffer,
+ virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
+ unsigned StubSize, unsigned Alignment = 1);
+ virtual void startGVStub(BufferState &BS, void *Buffer,
unsigned StubSize);
- virtual void* finishGVStub(const GlobalValue *GV);
+ virtual void* finishGVStub(BufferState &BS);
/// allocateSpace - Reserves space in the current block if any, or
/// allocate a new one of the given size.
@@ -1207,9 +1203,8 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
if (DwarfExceptionHandling || JITEmitDebugInfo) {
uintptr_t ActualSize = 0;
- SavedBufferBegin = BufferBegin;
- SavedBufferEnd = BufferEnd;
- SavedCurBufferPtr = CurBufferPtr;
+ BufferState BS;
+ SaveStateTo(BS);
if (MemMgr->NeedsExactSize()) {
ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
@@ -1225,9 +1220,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
FrameRegister);
uint8_t *EhEnd = CurBufferPtr;
- BufferBegin = SavedBufferBegin;
- BufferEnd = SavedBufferEnd;
- CurBufferPtr = SavedCurBufferPtr;
+ RestoreStateFrom(BS);
if (DwarfExceptionHandling) {
TheJIT->RegisterTable(FrameRegister);
@@ -1433,32 +1426,26 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
}
}
-void JITEmitter::startGVStub(const GlobalValue* GV, unsigned StubSize,
- unsigned Alignment) {
- SavedBufferBegin = BufferBegin;
- SavedBufferEnd = BufferEnd;
- SavedCurBufferPtr = CurBufferPtr;
+void JITEmitter::startGVStub(BufferState &BS, const GlobalValue* GV,
+ unsigned StubSize, unsigned Alignment) {
+ SaveStateTo(BS);
BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment);
BufferEnd = BufferBegin+StubSize+1;
}
-void JITEmitter::startGVStub(const GlobalValue* GV, void *Buffer,
- unsigned StubSize) {
- SavedBufferBegin = BufferBegin;
- SavedBufferEnd = BufferEnd;
- SavedCurBufferPtr = CurBufferPtr;
+void JITEmitter::startGVStub(BufferState &BS, void *Buffer, unsigned StubSize) {
+ SaveStateTo(BS);
BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
BufferEnd = BufferBegin+StubSize+1;
}
-void *JITEmitter::finishGVStub(const GlobalValue* GV) {
+void *JITEmitter::finishGVStub(BufferState &BS) {
NumBytes += getCurrentPCOffset();
- std::swap(SavedBufferBegin, BufferBegin);
- BufferEnd = SavedBufferEnd;
- CurBufferPtr = SavedCurBufferPtr;
- return SavedBufferBegin;
+ void *Result = BufferBegin;
+ RestoreStateFrom(BS);
+ return Result;
}
// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry
diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp
index bdddcd67fa..7031640471 100644
--- a/lib/Target/ARM/ARMJITInfo.cpp
+++ b/lib/Target/ARM/ARMJITInfo.cpp
@@ -139,7 +139,8 @@ ARMJITInfo::getLazyResolverFunction(JITCompilerFn F) {
void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,
JITCodeEmitter &JCE) {
- JCE.startGVStub(GV, 4, 4);
+ MachineCodeEmitter::BufferState BS;
+ JCE.startGVStub(BS, GV, 4, 4);
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
if (!sys::Memory::setRangeWritable((void*)Addr, 4)) {
llvm_unreachable("ERROR: Unable to mark indirect symbol writable");
@@ -148,13 +149,14 @@ void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,
if (!sys::Memory::setRangeExecutable((void*)Addr, 4)) {
llvm_unreachable("ERROR: Unable to mark indirect symbol executable");
}
- void *PtrAddr = JCE.finishGVStub(GV);
+ void *PtrAddr = JCE.finishGVStub(BS);
addIndirectSymAddr(Ptr, (intptr_t)PtrAddr);
return PtrAddr;
}
void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
JITCodeEmitter &JCE) {
+ MachineCodeEmitter::BufferState BS;
// If this is just a call to an external function, emit a branch instead of a
// call. The code is the same except for one bit of the last instruction.
if (Fn != (void*)(intptr_t)ARMCompilationCallback) {
@@ -172,7 +174,7 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
errs() << "JIT: Stub emitted at [" << LazyPtr
<< "] for external function at '" << Fn << "'\n");
}
- JCE.startGVStub(F, 16, 4);
+ JCE.startGVStub(BS, F, 16, 4);
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
if (!sys::Memory::setRangeWritable((void*)Addr, 16)) {
llvm_unreachable("ERROR: Unable to mark stub writable");
@@ -187,7 +189,7 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
}
} else {
// The stub is 8-byte size and 4-aligned.
- JCE.startGVStub(F, 8, 4);
+ JCE.startGVStub(BS, F, 8, 4);
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
if (!sys::Memory::setRangeWritable((void*)Addr, 8)) {
llvm_unreachable("ERROR: Unable to mark stub writable");
@@ -207,7 +209,7 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
//
// Branch and link to the compilation callback.
// The stub is 16-byte size and 4-byte aligned.
- JCE.startGVStub(F, 16, 4);
+ JCE.startGVStub(BS, F, 16, 4);
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
if (!sys::Memory::setRangeWritable((void*)Addr, 16)) {
llvm_unreachable("ERROR: Unable to mark stub writable");
@@ -228,7 +230,7 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
}
}
- return JCE.finishGVStub(F);
+ return JCE.finishGVStub(BS);
}
intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const {
diff --git a/lib/Target/Alpha/AlphaJITInfo.cpp b/lib/Target/Alpha/AlphaJITInfo.cpp
index d32813552f..4e59833953 100644
--- a/lib/Target/Alpha/AlphaJITInfo.cpp
+++ b/lib/Target/Alpha/AlphaJITInfo.cpp
@@ -192,15 +192,16 @@ extern "C" {
void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn,
JITCodeEmitter &JCE) {
+ MachineCodeEmitter::BufferState BS;
//assert(Fn == AlphaCompilationCallback && "Where are you going?\n");
//Do things in a stupid slow way!
- JCE.startGVStub(F, 19*4);
+ JCE.startGVStub(BS, F, 19*4);
void* Addr = (void*)(intptr_t)JCE.getCurrentPCValue();
for (int x = 0; x < 19; ++ x)
JCE.emitWordLE(0);
EmitBranchToAt(Addr, Fn);
DEBUG(errs() << "Emitting Stub to " << Fn << " at [" << Addr << "]\n");
- return JCE.finishGVStub(F);
+ return JCE.finishGVStub(BS);
}
TargetJITInfo::LazyResolverFn
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
index ef25d92f71..ddbb326570 100644
--- a/lib/Target/PowerPC/PPCJITInfo.cpp
+++ b/lib/Target/PowerPC/PPCJITInfo.cpp
@@ -330,11 +330,12 @@ extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
JITCodeEmitter &JCE) {
+ MachineCodeEmitter::BufferState BS;
// If this is just a call to an external function, emit a branch instead of a
// call. The code is the same except for one bit of the last instruction.
if (Fn != (void*)(intptr_t)PPC32CompilationCallback &&
Fn != (void*)(intptr_t)PPC64CompilationCallback) {
- JCE.startGVStub(F, 7*4);
+ JCE.startGVStub(BS, F, 7*4);
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
JCE.emitWordBE(0);
JCE.emitWordBE(0);
@@ -345,10 +346,10 @@ void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
JCE.emitWordBE(0);
EmitBranchToAt(Addr, (intptr_t)Fn, false, is64Bit);
sys::Memory::InvalidateInstructionCache((void*)Addr, 7*4);
- return JCE.finishGVStub(F);
+ return JCE.finishGVStub(BS);
}
- JCE.startGVStub(F, 10*4);
+ JCE.startGVStub(BS, F, 10*4);
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
if (is64Bit) {
JCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1)
@@ -373,7 +374,7 @@ void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
JCE.emitWordBE(0);
EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit);
sys::Memory::InvalidateInstructionCache((void*)Addr, 10*4);
- return JCE.finishGVStub(F);
+ return JCE.finishGVStub(BS);
}
diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp
index 0792bdd4dd..a14c155f17 100644
--- a/lib/Target/X86/X86JITInfo.cpp
+++ b/lib/Target/X86/X86JITInfo.cpp
@@ -426,19 +426,21 @@ X86JITInfo::X86JITInfo(X86TargetMachine &tm) : TM(tm) {
void *X86JITInfo::emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
JITCodeEmitter &JCE) {
+ MachineCodeEmitter::BufferState BS;
#if defined (X86_64_JIT)
- JCE.startGVStub(GV, 8, 8);
+ JCE.startGVStub(BS, GV, 8, 8);
JCE.emitWordLE((unsigned)(intptr_t)ptr);
JCE.emitWordLE((unsigned)(((intptr_t)ptr) >> 32));
#else
- JCE.startGVStub(GV, 4, 4);
+ JCE.startGVStub(BS, GV, 4, 4);
JCE.emitWordLE((intptr_t)ptr);
#endif
- return JCE.finishGVStub(GV);
+ return JCE.finishGVStub(BS);
}
void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
JITCodeEmitter &JCE) {
+ MachineCodeEmitter::BufferState BS;
// Note, we cast to intptr_t here to silence a -pedantic warning that
// complains about casting a function pointer to a normal pointer.
#if defined (X86_32_JIT) && !defined (_MSC_VER)
@@ -449,7 +451,7 @@ void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
#endif
if (NotCC) {
#if defined (X86_64_JIT)
- JCE.startGVStub(F, 13, 4);
+ JCE.startGVStub(BS, F, 13, 4);
JCE.emitByte(0x49); // REX prefix
JCE.emitByte(0xB8+2); // movabsq r10
JCE.emitWordLE((unsigned)(intptr_t)Fn);
@@ -458,15 +460,15 @@ void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
JCE.emitByte(0xFF); // jmpq *r10
JCE.emitByte(2 | (4 << 3) | (3 << 6));
#else
- JCE.startGVStub(F, 5, 4);
+ JCE.startGVStub(BS, F, 5, 4);
JCE.emitByte(0xE9);
JCE.emitWordLE((intptr_t)Fn-JCE.getCurrentPCValue()-4);
#endif
- return JCE.finishGVStub(F);
+ return JCE.finishGVStub(BS);
}
#if defined (X86_64_JIT)
- JCE.startGVStub(F, 14, 4);
+ JCE.startGVStub(BS, F, 14, 4);
JCE.emitByte(0x49); // REX prefix
JCE.emitByte(0xB8+2); // movabsq r10
JCE.emitWordLE((unsigned)(intptr_t)Fn);
@@ -475,7 +477,7 @@ void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
JCE.emitByte(0xFF); // callq *r10
JCE.emitByte(2 | (2 << 3) | (3 << 6));
#else
- JCE.startGVStub(F, 6, 4);
+ JCE.startGVStub(BS, F, 6, 4);
JCE.emitByte(0xE8); // Call with 32 bit pc-rel destination...
JCE.emitWordLE((intptr_t)Fn-JCE.getCurrentPCValue()-4);
@@ -485,14 +487,15 @@ void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
// initialize the buffer with garbage, which means it may follow a
// noreturn function call, confusing X86CompilationCallback2. PR 4929.
JCE.emitByte(0xCE); // Interrupt - Just a marker identifying the stub!
- return JCE.finishGVStub(F);
+ return JCE.finishGVStub(BS);
}
void X86JITInfo::emitFunctionStubAtAddr(const Function* F, void *Fn, void *Stub,
JITCodeEmitter &JCE) {
+ MachineCodeEmitter::BufferState BS;
// Note, we cast to intptr_t here to silence a -pedantic warning that
// complains about casting a function pointer to a normal pointer.
- JCE.startGVStub(F, Stub, 5);
+ JCE.startGVStub(BS, Stub, 5);
JCE.emitByte(0xE9);
#if defined (X86_64_JIT) && !defined (NDEBUG)
// Yes, we need both of these casts, or some broken versions of GCC (4.2.4)
@@ -502,7 +505,7 @@ void X86JITInfo::emitFunctionStubAtAddr(const Function* F, void *Fn, void *Stub,
&& "PIC displacement does not fit in displacement field!");
#endif
JCE.emitWordLE((intptr_t)Fn-JCE.getCurrentPCValue()-4);
- JCE.finishGVStub(F);
+ JCE.finishGVStub(BS);
}
/// getPICJumpTableEntry - Returns the value of the jumptable entry for the