forked from OSchip/llvm-project
Change indirect-globals to use a dedicated allocIndirectGV. This lets us
remove start/finishGVStub and the BufferState helper class from the MachineCodeEmitter interface. It has the side-effect of not setting the indirect global writable and then executable on ARM, but that shouldn't be necessary. llvm-svn: 91464
This commit is contained in:
parent
098a38b5ce
commit
e0d8e14e11
|
@ -68,29 +68,11 @@ public:
|
||||||
///
|
///
|
||||||
virtual bool finishFunction(MachineFunction &F) = 0;
|
virtual bool finishFunction(MachineFunction &F) = 0;
|
||||||
|
|
||||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
/// allocIndirectGV - Allocates and fills storage for an indirect
|
||||||
/// GV (e.g. function) that has not been code generated yet. The StubSize
|
/// GlobalValue, and returns the address.
|
||||||
/// specifies the total size required by the stub. The BufferState must be
|
virtual void *allocIndirectGV(const GlobalValue *GV,
|
||||||
/// passed to finishGVStub, and start/finish pairs with the same BufferState
|
const uint8_t *Buffer, size_t Size,
|
||||||
/// must be properly nested.
|
unsigned Alignment) = 0;
|
||||||
///
|
|
||||||
virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
|
|
||||||
unsigned StubSize, unsigned Alignment = 1) = 0;
|
|
||||||
|
|
||||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
|
||||||
/// GV (e.g. function) that has not been code generated yet. Buffer points to
|
|
||||||
/// memory already allocated for this stub. The BufferState must be passed to
|
|
||||||
/// finishGVStub, and start/finish pairs with the same BufferState must be
|
|
||||||
/// properly nested.
|
|
||||||
///
|
|
||||||
virtual void startGVStub(BufferState &BS, void *Buffer,
|
|
||||||
unsigned StubSize) = 0;
|
|
||||||
|
|
||||||
/// finishGVStub - This callback is invoked to terminate a GV stub and returns
|
|
||||||
/// the start address of the stub. The BufferState must first have been
|
|
||||||
/// passed to startGVStub.
|
|
||||||
///
|
|
||||||
virtual void *finishGVStub(BufferState &BS) = 0;
|
|
||||||
|
|
||||||
/// emitByte - This callback is invoked when a byte needs to be written to the
|
/// emitByte - This callback is invoked when a byte needs to be written to the
|
||||||
/// output stream.
|
/// output stream.
|
||||||
|
|
|
@ -48,41 +48,16 @@ class Function;
|
||||||
/// occurred, more memory is allocated, and we reemit the code into it.
|
/// occurred, more memory is allocated, and we reemit the code into it.
|
||||||
///
|
///
|
||||||
class MachineCodeEmitter {
|
class MachineCodeEmitter {
|
||||||
public:
|
|
||||||
class BufferState {
|
|
||||||
friend class MachineCodeEmitter;
|
|
||||||
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
|
|
||||||
/// allocated for this code buffer.
|
|
||||||
uint8_t *BufferBegin, *BufferEnd;
|
|
||||||
|
|
||||||
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
|
|
||||||
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
|
|
||||||
/// this pointer is at BufferEnd, it will never move due to code emission,
|
|
||||||
/// and all code emission requests will be ignored (this is the buffer
|
|
||||||
/// overflow condition).
|
|
||||||
uint8_t *CurBufferPtr;
|
|
||||||
public:
|
|
||||||
BufferState() : BufferBegin(NULL), BufferEnd(NULL), CurBufferPtr(NULL) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// These have the same meanings as the fields in BufferState
|
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
|
||||||
uint8_t *BufferBegin, *BufferEnd, *CurBufferPtr;
|
/// allocated for this code buffer.
|
||||||
|
uint8_t *BufferBegin, *BufferEnd;
|
||||||
/// Save or restore the current buffer state. The BufferState objects must be
|
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
|
||||||
/// used as a stack.
|
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
|
||||||
void SaveStateTo(BufferState &BS) {
|
/// this pointer is at BufferEnd, it will never move due to code emission, and
|
||||||
assert(BS.BufferBegin == NULL &&
|
/// all code emission requests will be ignored (this is the buffer overflow
|
||||||
"Can't save state into the same BufferState twice.");
|
/// condition).
|
||||||
BS.BufferBegin = BufferBegin;
|
uint8_t *CurBufferPtr;
|
||||||
BS.BufferEnd = BufferEnd;
|
|
||||||
BS.CurBufferPtr = CurBufferPtr;
|
|
||||||
}
|
|
||||||
void RestoreStateFrom(BufferState &BS) {
|
|
||||||
BufferBegin = BS.BufferBegin;
|
|
||||||
BufferEnd = BS.BufferEnd;
|
|
||||||
CurBufferPtr = BS.CurBufferPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~MachineCodeEmitter() {}
|
virtual ~MachineCodeEmitter() {}
|
||||||
|
@ -113,15 +88,23 @@ public:
|
||||||
///
|
///
|
||||||
void emitWordLE(uint32_t W) {
|
void emitWordLE(uint32_t W) {
|
||||||
if (4 <= BufferEnd-CurBufferPtr) {
|
if (4 <= BufferEnd-CurBufferPtr) {
|
||||||
*CurBufferPtr++ = (uint8_t)(W >> 0);
|
emitWordLEInto(CurBufferPtr, W);
|
||||||
*CurBufferPtr++ = (uint8_t)(W >> 8);
|
|
||||||
*CurBufferPtr++ = (uint8_t)(W >> 16);
|
|
||||||
*CurBufferPtr++ = (uint8_t)(W >> 24);
|
|
||||||
} else {
|
} else {
|
||||||
CurBufferPtr = BufferEnd;
|
CurBufferPtr = BufferEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// emitWordLEInto - This callback is invoked when a 32-bit word needs to be
|
||||||
|
/// written to an arbitrary buffer in little-endian format. Buf must have at
|
||||||
|
/// least 4 bytes of available space.
|
||||||
|
///
|
||||||
|
static void emitWordLEInto(uint8_t *&Buf, uint32_t W) {
|
||||||
|
*Buf++ = (uint8_t)(W >> 0);
|
||||||
|
*Buf++ = (uint8_t)(W >> 8);
|
||||||
|
*Buf++ = (uint8_t)(W >> 16);
|
||||||
|
*Buf++ = (uint8_t)(W >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
/// emitWordBE - This callback is invoked when a 32-bit word needs to be
|
/// emitWordBE - This callback is invoked when a 32-bit word needs to be
|
||||||
/// written to the output stream in big-endian format.
|
/// written to the output stream in big-endian format.
|
||||||
///
|
///
|
||||||
|
|
|
@ -271,6 +271,10 @@ namespace {
|
||||||
class JITEmitter : public JITCodeEmitter {
|
class JITEmitter : public JITCodeEmitter {
|
||||||
JITMemoryManager *MemMgr;
|
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
|
// 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
|
// 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
|
// ask the memory manager for at least this much space. When we
|
||||||
|
@ -396,11 +400,13 @@ namespace {
|
||||||
void initJumpTableInfo(MachineJumpTableInfo *MJTI);
|
void initJumpTableInfo(MachineJumpTableInfo *MJTI);
|
||||||
void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
|
void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
|
||||||
|
|
||||||
virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
|
void startGVStub(const GlobalValue* GV,
|
||||||
unsigned StubSize, unsigned Alignment = 1);
|
unsigned StubSize, unsigned Alignment = 1);
|
||||||
virtual void startGVStub(BufferState &BS, void *Buffer,
|
void startGVStub(void *Buffer, unsigned StubSize);
|
||||||
unsigned StubSize);
|
void finishGVStub();
|
||||||
virtual void* finishGVStub(BufferState &BS);
|
virtual void *allocIndirectGV(const GlobalValue *GV,
|
||||||
|
const uint8_t *Buffer, size_t Size,
|
||||||
|
unsigned Alignment);
|
||||||
|
|
||||||
/// allocateSpace - Reserves space in the current block if any, or
|
/// allocateSpace - Reserves space in the current block if any, or
|
||||||
/// allocate a new one of the given size.
|
/// allocate a new one of the given size.
|
||||||
|
@ -521,13 +527,12 @@ void *JITResolver::getLazyFunctionStub(Function *F) {
|
||||||
if (!Actual) return 0;
|
if (!Actual) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
|
TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
|
||||||
JE.startGVStub(BS, F, SL.Size, SL.Alignment);
|
JE.startGVStub(F, SL.Size, SL.Alignment);
|
||||||
// Codegen a new stub, calling the lazy resolver or the actual address of the
|
// Codegen a new stub, calling the lazy resolver or the actual address of the
|
||||||
// external function, if it was resolved.
|
// external function, if it was resolved.
|
||||||
Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE);
|
Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE);
|
||||||
JE.finishGVStub(BS);
|
JE.finishGVStub();
|
||||||
|
|
||||||
if (Actual != (void*)(intptr_t)LazyResolverFn) {
|
if (Actual != (void*)(intptr_t)LazyResolverFn) {
|
||||||
// If we are getting the stub for an external function, we really want the
|
// If we are getting the stub for an external function, we really want the
|
||||||
|
@ -579,11 +584,10 @@ void *JITResolver::getExternalFunctionStub(void *FnAddr) {
|
||||||
void *&Stub = ExternalFnToStubMap[FnAddr];
|
void *&Stub = ExternalFnToStubMap[FnAddr];
|
||||||
if (Stub) return Stub;
|
if (Stub) return Stub;
|
||||||
|
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
|
TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
|
||||||
JE.startGVStub(BS, 0, SL.Size, SL.Alignment);
|
JE.startGVStub(0, SL.Size, SL.Alignment);
|
||||||
Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE);
|
Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE);
|
||||||
JE.finishGVStub(BS);
|
JE.finishGVStub();
|
||||||
|
|
||||||
DEBUG(errs() << "JIT: Stub emitted at [" << Stub
|
DEBUG(errs() << "JIT: Stub emitted at [" << Stub
|
||||||
<< "] for external function at '" << FnAddr << "'\n");
|
<< "] for external function at '" << FnAddr << "'\n");
|
||||||
|
@ -1215,8 +1219,9 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
|
||||||
|
|
||||||
if (DwarfExceptionHandling || JITEmitDebugInfo) {
|
if (DwarfExceptionHandling || JITEmitDebugInfo) {
|
||||||
uintptr_t ActualSize = 0;
|
uintptr_t ActualSize = 0;
|
||||||
BufferState BS;
|
SavedBufferBegin = BufferBegin;
|
||||||
SaveStateTo(BS);
|
SavedBufferEnd = BufferEnd;
|
||||||
|
SavedCurBufferPtr = CurBufferPtr;
|
||||||
|
|
||||||
if (MemMgr->NeedsExactSize()) {
|
if (MemMgr->NeedsExactSize()) {
|
||||||
ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
|
ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
|
||||||
|
@ -1232,7 +1237,9 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
|
||||||
MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
|
MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
|
||||||
FrameRegister);
|
FrameRegister);
|
||||||
uint8_t *EhEnd = CurBufferPtr;
|
uint8_t *EhEnd = CurBufferPtr;
|
||||||
RestoreStateFrom(BS);
|
BufferBegin = SavedBufferBegin;
|
||||||
|
BufferEnd = SavedBufferEnd;
|
||||||
|
CurBufferPtr = SavedCurBufferPtr;
|
||||||
|
|
||||||
if (DwarfExceptionHandling) {
|
if (DwarfExceptionHandling) {
|
||||||
TheJIT->RegisterTable(FrameRegister);
|
TheJIT->RegisterTable(FrameRegister);
|
||||||
|
@ -1438,27 +1445,39 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JITEmitter::startGVStub(BufferState &BS, const GlobalValue* GV,
|
void JITEmitter::startGVStub(const GlobalValue* GV,
|
||||||
unsigned StubSize, unsigned Alignment) {
|
unsigned StubSize, unsigned Alignment) {
|
||||||
SaveStateTo(BS);
|
SavedBufferBegin = BufferBegin;
|
||||||
|
SavedBufferEnd = BufferEnd;
|
||||||
|
SavedCurBufferPtr = CurBufferPtr;
|
||||||
|
|
||||||
BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment);
|
BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment);
|
||||||
BufferEnd = BufferBegin+StubSize+1;
|
BufferEnd = BufferBegin+StubSize+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JITEmitter::startGVStub(BufferState &BS, void *Buffer, unsigned StubSize) {
|
void JITEmitter::startGVStub(void *Buffer, unsigned StubSize) {
|
||||||
SaveStateTo(BS);
|
SavedBufferBegin = BufferBegin;
|
||||||
|
SavedBufferEnd = BufferEnd;
|
||||||
|
SavedCurBufferPtr = CurBufferPtr;
|
||||||
|
|
||||||
BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
|
BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
|
||||||
BufferEnd = BufferBegin+StubSize+1;
|
BufferEnd = BufferBegin+StubSize+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *JITEmitter::finishGVStub(BufferState &BS) {
|
void JITEmitter::finishGVStub() {
|
||||||
assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
|
assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
|
||||||
NumBytes += getCurrentPCOffset();
|
NumBytes += getCurrentPCOffset();
|
||||||
void *Result = BufferBegin;
|
BufferBegin = SavedBufferBegin;
|
||||||
RestoreStateFrom(BS);
|
BufferEnd = SavedBufferEnd;
|
||||||
return Result;
|
CurBufferPtr = SavedCurBufferPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *JITEmitter::allocIndirectGV(const GlobalValue *GV,
|
||||||
|
const uint8_t *Buffer, size_t Size,
|
||||||
|
unsigned Alignment) {
|
||||||
|
uint8_t *IndGV = MemMgr->allocateStub(GV, Size, Alignment);
|
||||||
|
memcpy(IndGV, Buffer, Size);
|
||||||
|
return IndGV;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry
|
// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry
|
||||||
|
@ -1546,11 +1565,10 @@ void JIT::updateFunctionStub(Function *F) {
|
||||||
|
|
||||||
// Tell the target jit info to rewrite the stub at the specified address,
|
// Tell the target jit info to rewrite the stub at the specified address,
|
||||||
// rather than creating a new one.
|
// rather than creating a new one.
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout();
|
TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout();
|
||||||
JE->startGVStub(BS, Stub, layout.Size);
|
JE->startGVStub(Stub, layout.Size);
|
||||||
getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter());
|
getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter());
|
||||||
JE->finishGVStub(BS);
|
JE->finishGVStub();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// freeMachineCodeForFunction - release machine code memory for given Function.
|
/// freeMachineCodeForFunction - release machine code memory for given Function.
|
||||||
|
|
|
@ -139,17 +139,11 @@ ARMJITInfo::getLazyResolverFunction(JITCompilerFn F) {
|
||||||
|
|
||||||
void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,
|
void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,
|
||||||
JITCodeEmitter &JCE) {
|
JITCodeEmitter &JCE) {
|
||||||
MachineCodeEmitter::BufferState BS;
|
uint8_t Buffer[4];
|
||||||
JCE.startGVStub(BS, GV, 4, 4);
|
uint8_t *Cur = Buffer;
|
||||||
intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
|
MachineCodeEmitter::emitWordLEInto(Cur, (intptr_t)Ptr);
|
||||||
if (!sys::Memory::setRangeWritable((void*)Addr, 4)) {
|
void *PtrAddr = JCE.allocIndirectGV(
|
||||||
llvm_unreachable("ERROR: Unable to mark indirect symbol writable");
|
GV, Buffer, sizeof(Buffer), /*Alignment=*/4);
|
||||||
}
|
|
||||||
JCE.emitWordLE((intptr_t)Ptr);
|
|
||||||
if (!sys::Memory::setRangeExecutable((void*)Addr, 4)) {
|
|
||||||
llvm_unreachable("ERROR: Unable to mark indirect symbol executable");
|
|
||||||
}
|
|
||||||
void *PtrAddr = JCE.finishGVStub(BS);
|
|
||||||
addIndirectSymAddr(Ptr, (intptr_t)PtrAddr);
|
addIndirectSymAddr(Ptr, (intptr_t)PtrAddr);
|
||||||
return PtrAddr;
|
return PtrAddr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,6 @@ TargetJITInfo::StubLayout AlphaJITInfo::getStubLayout() {
|
||||||
|
|
||||||
void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn,
|
void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn,
|
||||||
JITCodeEmitter &JCE) {
|
JITCodeEmitter &JCE) {
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
//assert(Fn == AlphaCompilationCallback && "Where are you going?\n");
|
//assert(Fn == AlphaCompilationCallback && "Where are you going?\n");
|
||||||
//Do things in a stupid slow way!
|
//Do things in a stupid slow way!
|
||||||
void* Addr = (void*)(intptr_t)JCE.getCurrentPCValue();
|
void* Addr = (void*)(intptr_t)JCE.getCurrentPCValue();
|
||||||
|
|
|
@ -339,7 +339,6 @@ extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
|
||||||
|
|
||||||
void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
|
void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
|
||||||
JITCodeEmitter &JCE) {
|
JITCodeEmitter &JCE) {
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
// If this is just a call to an external function, emit a branch instead of a
|
// 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.
|
// call. The code is the same except for one bit of the last instruction.
|
||||||
if (Fn != (void*)(intptr_t)PPC32CompilationCallback &&
|
if (Fn != (void*)(intptr_t)PPC32CompilationCallback &&
|
||||||
|
|
|
@ -426,16 +426,19 @@ X86JITInfo::X86JITInfo(X86TargetMachine &tm) : TM(tm) {
|
||||||
|
|
||||||
void *X86JITInfo::emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
|
void *X86JITInfo::emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
|
||||||
JITCodeEmitter &JCE) {
|
JITCodeEmitter &JCE) {
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
#if defined (X86_64_JIT)
|
#if defined (X86_64_JIT)
|
||||||
JCE.startGVStub(BS, GV, 8, 8);
|
const unsigned Alignment = 8;
|
||||||
JCE.emitWordLE((unsigned)(intptr_t)ptr);
|
uint8_t Buffer[8];
|
||||||
JCE.emitWordLE((unsigned)(((intptr_t)ptr) >> 32));
|
uint8_t *Cur = Buffer;
|
||||||
|
MachineCodeEmitter::emitWordLEInto(Cur, (unsigned)(intptr_t)ptr);
|
||||||
|
MachineCodeEmitter::emitWordLEInto(Cur, (unsigned)(((intptr_t)ptr) >> 32));
|
||||||
#else
|
#else
|
||||||
JCE.startGVStub(BS, GV, 4, 4);
|
const unsigned Alignment = 4;
|
||||||
JCE.emitWordLE((intptr_t)ptr);
|
uint8_t Buffer[4];
|
||||||
|
uint8_t *Cur = Buffer;
|
||||||
|
MachineCodeEmitter::emitWordLEInto(Cur, (intptr_t)ptr);
|
||||||
#endif
|
#endif
|
||||||
return JCE.finishGVStub(BS);
|
return JCE.allocIndirectGV(GV, Buffer, sizeof(Buffer), Alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetJITInfo::StubLayout X86JITInfo::getStubLayout() {
|
TargetJITInfo::StubLayout X86JITInfo::getStubLayout() {
|
||||||
|
@ -451,7 +454,6 @@ TargetJITInfo::StubLayout X86JITInfo::getStubLayout() {
|
||||||
|
|
||||||
void *X86JITInfo::emitFunctionStub(const Function* F, void *Target,
|
void *X86JITInfo::emitFunctionStub(const Function* F, void *Target,
|
||||||
JITCodeEmitter &JCE) {
|
JITCodeEmitter &JCE) {
|
||||||
MachineCodeEmitter::BufferState BS;
|
|
||||||
// Note, we cast to intptr_t here to silence a -pedantic warning that
|
// Note, we cast to intptr_t here to silence a -pedantic warning that
|
||||||
// complains about casting a function pointer to a normal pointer.
|
// complains about casting a function pointer to a normal pointer.
|
||||||
#if defined (X86_32_JIT) && !defined (_MSC_VER)
|
#if defined (X86_32_JIT) && !defined (_MSC_VER)
|
||||||
|
|
Loading…
Reference in New Issue