Great! I'll apply it in the next couple of days, in case someone else
wants to review it.
Evan Cheng wrote:> Looks sane. Thanks.
>
> Evan
>
> On Feb 1, 2008, at 1:24 AM, Nicolas Geoffray wrote:
>
>
>> Dear all,
>>
>> Here's a new patch with Evan's comments (thx Evan!) and some
cleanups.
>> Now the (duplicated) exception handling code is in a new file:
>> lib/ExecutionEngine/JIT/JITDwarfEmitter.
>>
>> This patch should work on linux/x86 and linux/ppc (tested).
>>
>> Nicolas
>> Index: include/llvm/ExecutionEngine/ExecutionEngine.h
>>
==================================================================>> ---
include/llvm/ExecutionEngine/ExecutionEngine.h (revision 46612)
>> +++ include/llvm/ExecutionEngine/ExecutionEngine.h (working copy)
>> @@ -85,6 +85,11 @@
>> /// pointer is invoked to create it. If this returns null, the JIT
>> will abort.
>> void* (*LazyFunctionCreator)(const std::string &);
>>
>> + /// ExceptionTableRegister - If Exception Handling is set, the
>> JIT will
>> + /// register dwarf tables with this function
>> + typedef void (*EERegisterFn)(void*);
>> + static EERegisterFn ExceptionTableRegister;
>> +
>> public:
>> /// lock - This lock is protects the ExecutionEngine, JIT,
>> JITResolver and
>> /// JITEmitter classes. It must be held while changing the
>> internal state of
>> @@ -246,6 +251,18 @@
>> void InstallLazyFunctionCreator(void* (*P)(const std::string &))
{
>> LazyFunctionCreator = P;
>> }
>> +
>> + /// InstallExceptionTableRegister - The JIT will use the given
>> function
>> + /// to register the exception tables it generates.
>> + static void InstallExceptionTableRegister(void (*F)(void*)) {
>> + ExceptionTableRegister = F;
>> + }
>> +
>> + /// RegisterTable - Registers the given pointer as an exception
>> table. It uses
>> + /// the ExceptionTableRegister function.
>> + static void RegisterTable(void* res) {
>> + ExceptionTableRegister(res);
>> + }
>>
>> protected:
>> explicit ExecutionEngine(ModuleProvider *P);
>> Index: include/llvm/ExecutionEngine/JITMemoryManager.h
>>
==================================================================>> ---
include/llvm/ExecutionEngine/JITMemoryManager.h (revision 46612)
>> +++ include/llvm/ExecutionEngine/JITMemoryManager.h (working copy)
>> @@ -89,6 +89,17 @@
>> /// deallocateMemForFunction - Free JIT memory for the specified
>> function.
>> /// This is never called when the JIT is currently emitting a
>> function.
>> virtual void deallocateMemForFunction(const Function *F) = 0;
>> +
>> + /// startExceptionTable - When we finished JITing the function,
>> if exception
>> + /// handling is set, we emit the exception table.
>> + virtual unsigned char* startExceptionTable(const Function* F,
>> + uintptr_t
&ActualSize)
>> = 0;
>> +
>> + /// endExceptionTable - This method is called when the JIT is
>> done emitting
>> + /// the exception table.
>> + virtual void endExceptionTable(const Function *F, unsigned char
>> *TableStart,
>> + unsigned char *TableEnd,
>> + unsigned char* FrameRegister) = 0;
>> };
>>
>> } // end namespace llvm.
>> Index: include/llvm/CodeGen/MachineCodeEmitter.h
>>
==================================================================>> ---
include/llvm/CodeGen/MachineCodeEmitter.h (revision 46612)
>> +++ include/llvm/CodeGen/MachineCodeEmitter.h (working copy)
>> @@ -26,6 +26,7 @@
>> class MachineConstantPool;
>> class MachineJumpTableInfo;
>> class MachineFunction;
>> +class MachineModuleInfo;
>> class MachineRelocation;
>> class Value;
>> class GlobalValue;
>> @@ -136,6 +137,72 @@
>> CurBufferPtr = BufferEnd;
>> }
>>
>> +
>> + /// emitULEB128Bytes - This callback is invoked when a ULEB128
>> needs to be
>> + /// written to the output stream.
>> + void emitULEB128Bytes(unsigned Value) {
>> + do {
>> + unsigned char Byte = Value & 0x7f;
>> + Value >>= 7;
>> + if (Value) Byte |= 0x80;
>> + emitByte(Byte);
>> + } while (Value);
>> + }
>> +
>> + /// emitSLEB128Bytes - This callback is invoked when a SLEB128
>> needs to be
>> + /// written to the output stream.
>> + void emitSLEB128Bytes(int Value) {
>> + int Sign = Value >> (8 * sizeof(Value) - 1);
>> + bool IsMore;
>> +
>> + do {
>> + unsigned char Byte = Value & 0x7f;
>> + Value >>= 7;
>> + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
>> + if (IsMore) Byte |= 0x80;
>> + emitByte(Byte);
>> + } while (IsMore);
>> + }
>> +
>> + /// emitString - This callback is invoked when a String needs to be
>> + /// written to the output stream.
>> + void emitString(const std::string &String) {
>> + for (unsigned i = 0, N = String.size(); i < N; ++i) {
>> + unsigned char C = String[i];
>> + emitByte(C);
>> + }
>> + emitByte(0);
>> + }
>> +
>> + /// emitInt32 - Emit a int32 directive.
>> + void emitInt32(int Value) {
>> + if (CurBufferPtr+4 <= BufferEnd) {
>> + *((uint32_t*)CurBufferPtr) = Value;
>> + CurBufferPtr += 4;
>> + } else {
>> + CurBufferPtr = BufferEnd;
>> + }
>> + }
>> +
>> + /// emitInt64 - Emit a int64 directive.
>> + void emitInt64(uint64_t Value) {
>> + if (CurBufferPtr+8 <= BufferEnd) {
>> + *((uint64_t*)CurBufferPtr) = Value;
>> + CurBufferPtr += 8;
>> + } else {
>> + CurBufferPtr = BufferEnd;
>> + }
>> + }
>> +
>> + /// emitAt - Emit Value in Addr
>> + void emitAt(uintptr_t *Addr, uintptr_t Value) {
>> + if (Addr >= (uintptr_t*)BufferBegin && Addr <
>> (uintptr_t*)BufferEnd)
>> + (*Addr) = Value;
>> + }
>> +
>> + /// emitLabel - Emits a label
>> + virtual void emitLabel(uint64_t LabelID) = 0;
>> +
>> /// allocateSpace - Allocate a block of space in the current
>> output buffer,
>> /// returning null (and setting conditions to indicate buffer
>> overflow) on
>> /// failure. Alignment is the alignment in bytes of the buffer
>> desired.
>> @@ -194,6 +261,15 @@
>> /// emitted.
>> ///
>> virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock
>> *MBB) const= 0;
>> +
>> + /// getLabelAddress - Return the address of the specified
>> LabelID, only usable
>> + /// after the LabelID has been emitted.
>> + ///
>> + virtual intptr_t getLabelAddress(uint64_t LabelID) const = 0;
>> +
>> + /// Specifies the MachineModuleInfo object. This is used for
>> exception handling
>> + /// purposes.
>> + virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
>> };
>>
>> } // End llvm namespace
>> Index: lib/CodeGen/LLVMTargetMachine.cpp
>>
==================================================================>> ---
lib/CodeGen/LLVMTargetMachine.cpp (revision 46612)
>> +++ lib/CodeGen/LLVMTargetMachine.cpp (working copy)
>> @@ -186,8 +186,8 @@
>>
>> PM.add(createGCLoweringPass());
>>
>> - // FIXME: Implement the invoke/unwind instructions!
>> - PM.add(createLowerInvokePass(getTargetLowering()));
>> + if (!ExceptionHandling)
>> + PM.add(createLowerInvokePass(getTargetLowering()));
>>
>> // Make sure that no unreachable blocks are instruction selected.
>> PM.add(createUnreachableBlockEliminationPass());
>> Index: lib/CodeGen/ELFWriter.cpp
>>
==================================================================>> ---
lib/CodeGen/ELFWriter.cpp (revision 46612)
>> +++ lib/CodeGen/ELFWriter.cpp (working copy)
>> @@ -98,6 +98,21 @@
>> return 0;
>> }
>>
>> + virtual intptr_t getLabelAddress(uint64_t Label) const {
>> + assert(0 && "Label address not implementated
yet!");
>> + abort();
>> + return 0;
>> + }
>> +
>> + virtual void emitLabel(uint64_t LabelID) {
>> + assert(0 && "emit Label not implementated
yet!");
>> + abort();
>> + }
>> +
>> +
>> + virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
>> +
>> +
>> /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
>> void startFunctionStub(unsigned StubSize, unsigned Alignment =
>> 1) {
>> assert(0 && "JIT specific function called!");
>> Index: lib/CodeGen/MachOWriter.cpp
>>
==================================================================>> ---
lib/CodeGen/MachOWriter.cpp (revision 46612)
>> +++ lib/CodeGen/MachOWriter.cpp (working copy)
>> @@ -125,6 +125,20 @@
>> return MBBLocations[MBB->getNumber()];
>> }
>>
>> + virtual intptr_t getLabelAddress(uint64_t Label) const {
>> + assert(0 && "get Label not implemented");
>> + abort();
>> + return 0;
>> + }
>> +
>> + virtual void emitLabel(uint64_t LabelID) {
>> + assert(0 && "emit Label not implemented");
>> + abort();
>> + }
>> +
>> +
>> + virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
>> +
>> /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
>> virtual void startFunctionStub(unsigned StubSize, unsigned
>> Alignment = 1) {
>> assert(0 && "JIT specific function called!");
>> Index: lib/Target/PowerPC/PPCCodeEmitter.cpp
>>
==================================================================>> ---
lib/Target/PowerPC/PPCCodeEmitter.cpp (revision 46612)
>> +++ lib/Target/PowerPC/PPCCodeEmitter.cpp (working copy)
>> @@ -20,6 +20,7 @@
>> #include "llvm/CodeGen/MachineCodeEmitter.h"
>> #include "llvm/CodeGen/MachineFunctionPass.h"
>> #include "llvm/CodeGen/MachineInstrBuilder.h"
>> +#include "llvm/CodeGen/MachineModuleInfo.h"
>> #include "llvm/CodeGen/Passes.h"
>> #include "llvm/Support/Debug.h"
>> #include "llvm/Support/Compiler.h"
>> @@ -38,6 +39,11 @@
>> /// getMachineOpValue - evaluates the MachineOperand of a given
>> MachineInstr
>> ///
>> int getMachineOpValue(MachineInstr &MI, MachineOperand
&MO);
>> +
>> + void getAnalysisUsage(AnalysisUsage &AU) const {
>> + AU.addRequired<MachineModuleInfo>();
>> + MachineFunctionPass::getAnalysisUsage(AU);
>> + }
>>
>> public:
>> static char ID;
>> @@ -82,6 +88,8 @@
>> assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
>> MF.getTarget().getRelocationModel() != Reloc::Static)
&&
>> "JIT relocation model must be set to static or
default!");
>> +
>> + MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
>> do {
>> MovePCtoLROffset = 0;
>> MCE.startFunction(MF);
>> @@ -101,6 +109,9 @@
>> default:
>> MCE.emitWordBE(getBinaryCodeForInstr(*I));
>> break;
>> + case TargetInstrInfo::LABEL:
>> + MCE.emitLabel(MI.getOperand(0).getImm());
>> + break;
>> case PPC::IMPLICIT_DEF_GPRC:
>> case PPC::IMPLICIT_DEF_G8RC:
>> case PPC::IMPLICIT_DEF_F8:
>> Index: lib/Target/X86/X86CodeEmitter.cpp
>>
==================================================================>> ---
lib/Target/X86/X86CodeEmitter.cpp (revision 46612)
>> +++ lib/Target/X86/X86CodeEmitter.cpp (working copy)
>> @@ -23,6 +23,7 @@
>> #include "llvm/CodeGen/MachineCodeEmitter.h"
>> #include "llvm/CodeGen/MachineFunctionPass.h"
>> #include "llvm/CodeGen/MachineInstr.h"
>> +#include "llvm/CodeGen/MachineModuleInfo.h"
>> #include "llvm/CodeGen/Passes.h"
>> #include "llvm/Function.h"
>> #include "llvm/ADT/Statistic.h"
>> @@ -61,6 +62,11 @@
>>
>> void emitInstruction(const MachineInstr &MI,
>> const TargetInstrDesc *Desc);
>> +
>> + void getAnalysisUsage(AnalysisUsage &AU) const {
>> + AU.addRequired<MachineModuleInfo>();
>> + MachineFunctionPass::getAnalysisUsage(AU);
>> + }
>>
>> private:
>> void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
>> @@ -104,10 +110,13 @@
>> assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
>> MF.getTarget().getRelocationModel() != Reloc::Static)
&&
>> "JIT relocation model must be set to static or
default!");
>> +
>> + MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
>> +
>> II = ((X86TargetMachine&)TM).getInstrInfo();
>> TD = ((X86TargetMachine&)TM).getTargetData();
>> Is64BitMode = TM.getSubtarget<X86Subtarget>().is64Bit();
>> -
>> +
>> do {
>> MCE.startFunction(MF);
>> for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
>> @@ -596,13 +605,13 @@
>> // Remember the current PC offset, this is the PIC relocation
>> // base address.
>> switch (Opcode) {
>> -#ifndef NDEBUG
>> default:
>> assert(0 && "psuedo instructions should be removed
before code
>> emission");
>> case TargetInstrInfo::INLINEASM:
>> assert(0 && "JIT does not support inline
asm!\n");
>> case TargetInstrInfo::LABEL:
>> - assert(0 && "JIT does not support meta
labels!\n");
>> + MCE.emitLabel(MI.getOperand(0).getImm());
>> + break;
>> case X86::IMPLICIT_DEF_GR8:
>> case X86::IMPLICIT_DEF_GR16:
>> case X86::IMPLICIT_DEF_GR32:
>> @@ -613,7 +622,6 @@
>> case X86::IMPLICIT_DEF_VR128:
>> case X86::FP_REG_KILL:
>> break;
>> -#endif
>> case X86::MOVPC32r: {
>> // This emits the "call" portion of this pseudo
instruction.
>> MCE.emitByte(BaseOpcode);
>> @@ -627,7 +635,6 @@
>> }
>> CurOp = NumOps;
>> break;
>> -
>> case X86II::RawFrm:
>> MCE.emitByte(BaseOpcode);
>>
>> Index: lib/ExecutionEngine/JIT/JITEmitter.cpp
>>
==================================================================>> ---
lib/ExecutionEngine/JIT/JITEmitter.cpp (revision 46612)
>> +++ lib/ExecutionEngine/JIT/JITEmitter.cpp (working copy)
>> @@ -14,6 +14,7 @@
>>
>> #define DEBUG_TYPE "jit"
>> #include "JIT.h"
>> +#include "JITDwarfEmitter.h"
>> #include "llvm/Constant.h"
>> #include "llvm/Module.h"
>> #include "llvm/Type.h"
>> @@ -21,11 +22,13 @@
>> #include "llvm/CodeGen/MachineFunction.h"
>> #include "llvm/CodeGen/MachineConstantPool.h"
>> #include "llvm/CodeGen/MachineJumpTableInfo.h"
>> +#include "llvm/CodeGen/MachineModuleInfo.h"
>> #include "llvm/CodeGen/MachineRelocation.h"
>> #include "llvm/ExecutionEngine/JITMemoryManager.h"
>> #include "llvm/Target/TargetData.h"
>> #include "llvm/Target/TargetJITInfo.h"
>> #include "llvm/Target/TargetMachine.h"
>> +#include "llvm/Target/TargetOptions.h"
>> #include "llvm/Support/Debug.h"
>> #include "llvm/Support/MutexGuard.h"
>> #include "llvm/System/Disassembler.h"
>> @@ -336,6 +339,17 @@
>>
>> /// Resolver - This contains info about the currently resolved
>> functions.
>> JITResolver Resolver;
>> +
>> + /// DE - The dwarf emitter for the jit.
>> + JITDwarfEmitter *DE;
>> +
>> + /// LabelLocations - This vector is a mapping from Label ID's
>> to their
>> + /// address.
>> + std::vector<intptr_t> LabelLocations;
>> +
>> + /// MMI - Machine module info for exception informations
>> + MachineModuleInfo* MMI;
>> +
>> public:
>> JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit) {
>> MemMgr = JMM ? JMM :
>> JITMemoryManager::CreateDefaultMemManager();
>> @@ -343,9 +357,12 @@
>> MemMgr->AllocateGOT();
>> DOUT << "JIT is managing a GOT\n";
>> }
>> +
>> + if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
>> }
>> ~JITEmitter() {
>> delete MemMgr;
>> + if (ExceptionHandling) delete DE;
>> }
>>
>> JITResolver &getJITResolver() { return Resolver; }
>> @@ -384,6 +401,24 @@
>> void deallocateMemForFunction(Function *F) {
>> MemMgr->deallocateMemForFunction(F);
>> }
>> +
>> + virtual void emitLabel(uint64_t LabelID) {
>> + if (LabelLocations.size() <= LabelID)
>> + LabelLocations.resize((LabelID+1)*2);
>> + LabelLocations[LabelID] = getCurrentPCValue();
>> + }
>> +
>> + virtual intptr_t getLabelAddress(uint64_t LabelID) const {
>> + assert(LabelLocations.size() > (unsigned)LabelID &&
>> + LabelLocations[LabelID] && "Label not
emitted!");
>> + return LabelLocations[LabelID];
>> + }
>> +
>> + virtual void setModuleInfo(MachineModuleInfo* Info) {
>> + MMI = Info;
>> + if (ExceptionHandling) DE->setModuleInfo(Info);
>> + }
>> +
>> private:
>> void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool
>> NoNeedStub);
>> void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
>> @@ -544,7 +579,25 @@
>> DOUT << "Disassembled code:\n"
>> << sys::disassembleBuffer(FnStart, FnEnd-FnStart,
>> (uintptr_t)FnStart);
>> #endif
>> -
>> + if (ExceptionHandling) {
>> + uintptr_t ActualSize;
>> + SavedBufferBegin = BufferBegin;
>> + SavedBufferEnd = BufferEnd;
>> + SavedCurBufferPtr = CurBufferPtr;
>> +
>> + BufferBegin = CurBufferPtr = MemMgr-
>>
>>> startExceptionTable(F.getFunction(),
>>>
>> +
>> ActualSize);
>> + BufferEnd = BufferBegin+ActualSize;
>> + unsigned char* FrameRegister = DE->EmitDwarfTable(F, *this,
>> FnStart, FnEnd);
>> + MemMgr->endExceptionTable(F.getFunction(), BufferBegin,
>> CurBufferPtr, FrameRegister);
>> + BufferBegin = SavedBufferBegin;
>> + BufferEnd = SavedBufferEnd;
>> + CurBufferPtr = SavedCurBufferPtr;
>> +
>> + TheJIT->RegisterTable(FrameRegister);
>> + }
>> + MMI->EndFunction();
>> +
>> return false;
>> }
>>
>> Index: lib/ExecutionEngine/JIT/JITMemoryManager.cpp
>>
==================================================================>> ---
lib/ExecutionEngine/JIT/JITMemoryManager.cpp (revision 46612)
>> +++ lib/ExecutionEngine/JIT/JITMemoryManager.cpp (working copy)
>> @@ -256,6 +256,7 @@
>> sys::MemoryBlock getNewMemoryBlock(unsigned size);
>>
>> std::map<const Function*, MemoryRangeHeader*> FunctionBlocks;
>> + std::map<const Function*, MemoryRangeHeader*> TableBlocks;
>> public:
>> DefaultJITMemoryManager();
>> ~DefaultJITMemoryManager();
>> @@ -290,6 +291,28 @@
>> FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList,
>> BlockSize);
>> }
>>
>> + /// startExceptionTable - Use startFunctionBody to allocate
>> memory for the
>> + /// function's exception table.
>> + unsigned char* startExceptionTable(const Function* F, uintptr_t
>> &ActualSize) {
>> + return startFunctionBody(F, ActualSize);
>> + }
>> +
>> + /// endExceptionTable - The exception table of F is now
>> allocated,
>> + /// and takes the memory in the range [TableStart,TableEnd).
>> + void endExceptionTable(const Function *F, unsigned char
>> *TableStart,
>> + unsigned char *TableEnd,
>> + unsigned char* FrameRegister) {
>> + assert(TableEnd > TableStart);
>> + assert(TableStart == (unsigned char *)(CurBlock+1) &&
>> + "Mismatched table start/end!");
>> +
>> + uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock;
>> + TableBlocks[F] = CurBlock;
>> +
>> + // Release the memory at the end of this block that isn't
>> needed.
>> + FreeMemoryList =CurBlock-
>>
>>> TrimAllocationToSize(FreeMemoryList, BlockSize);
>>>
>> + }
>> +
>> unsigned char *getGOTBase() const {
>> return GOTBase;
>> }
>> @@ -315,6 +338,24 @@
>>
>> // Finally, remove this entry from FunctionBlocks.
>> FunctionBlocks.erase(I);
>> +
>> + I = TableBlocks.find(F);
>> + if (I == TableBlocks.end()) return;
>> +
>> + // Find the block that is allocated for this function.
>> + MemRange = I->second;
>> + assert(MemRange->ThisAllocated && "Block
isn't allocated!");
>> +
>> + // Fill the buffer with garbage!
>> +#ifndef NDEBUG
>> + memset(MemRange+1, 0xCD, MemRange->BlockSize-
>> sizeof(*MemRange));
>> +#endif
>> +
>> + // Free the memory.
>> + FreeMemoryList = MemRange->FreeBlock(FreeMemoryList);
>> +
>> + // Finally, remove this entry from TableBlocks.
>> + TableBlocks.erase(I);
>> }
>> };
>> }
>> Index: lib/ExecutionEngine/ExecutionEngine.cpp
>>
==================================================================>> ---
lib/ExecutionEngine/ExecutionEngine.cpp (revision 46612)
>> +++ lib/ExecutionEngine/ExecutionEngine.cpp (working copy)
>> @@ -34,7 +34,9 @@
>>
>> ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0;
>> ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0;
>> +ExecutionEngine::EERegisterFn
>> ExecutionEngine::ExceptionTableRegister = 0;
>>
>> +
>> ExecutionEngine::ExecutionEngine(ModuleProvider *P) :
>> LazyFunctionCreator(0) {
>> LazyCompilationDisabled = false;
>> Modules.push_back(P);
>> Index: lib/ExecutionEngine/JIT/JITDwarfEmitter.h
>>
==================================================================>> ---
lib/ExecutionEngine/JIT/JITDwarfEmitter.h (revision 0)
>> +++ lib/ExecutionEngine/JIT/JITDwarfEmitter.h (revision 0)
>> @@ -0,0 +1,69 @@
>> +//===------ JITDwarfEmitter.h - Write dwarf tables into memory
>> ------------===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open
>> Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//
>> =
>> =
>> =
>> ----------------------------------------------------------------------=
>> ==//
>> +//
>> +// This file defines a JITDwarfEmitter object that is used by the
>> JIT to
>> +// write dwarf tables to memory.
>> +//
>> +//
>> =
>> =
>> =
>> ----------------------------------------------------------------------=
>> ==//
>> +
>> +#ifndef LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
>> +#define LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
>> +
>> +namespace llvm {
>> +
>> +class Function;
>> +class MachineCodeEmitter;
>> +class MachineFunction;
>> +class MachineModuleInfo;
>> +class MachineMove;
>> +class MRegisterInfo;
>> +class TargetData;
>> +class TargetMachine;
>> +
>> +class JITDwarfEmitter {
>> + const TargetData* TD;
>> + MachineCodeEmitter* MCE;
>> + const MRegisterInfo* RI;
>> + MachineModuleInfo* MMI;
>> + JIT& Jit;
>> + bool needsIndirectEncoding;
>> + bool stackGrowthDirection;
>> +
>> +public:
>> + JITDwarfEmitter(JIT& jit);
>> +
>> + unsigned char* EmitExceptionTable(MachineFunction* MF,
>> + unsigned char* StartFunction,
>> + unsigned char* EndFunction);
>> +
>> + void EmitFrameMoves(intptr_t BaseLabelPtr,
>> + const std::vector<MachineMove>
&Moves);
>> +
>> + unsigned char* EmitCommonEHFrame(const Function* Personality);
>> +
>> + unsigned char* EmitEHFrame(const Function* Personality,
>> + unsigned char* StartBufferPtr,
>> + unsigned char* StartFunction,
>> + unsigned char* EndFunction,
>> + unsigned char* ExceptionTable);
>> +
>> +
>> + unsigned char* EmitDwarfTable(MachineFunction& F,
>> + MachineCodeEmitter& MCE,
>> + unsigned char* StartFunction,
>> + unsigned char* EndFunction);
>> +
>> + void setModuleInfo(MachineModuleInfo* Info) {
>> + MMI = Info;
>> + }
>> +};
>> +
>> +} // end namespace llvm
>> +
>> +#endif // LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
>> Index: lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
>>
==================================================================>> ---
lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp (revision 0)
>> +++ lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp (revision 0)
>> @@ -0,0 +1,636 @@
>> +//===----- JITDwarfEmitter.cpp - Write dwarf tables into memory
>> -----------===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open
>> Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//
>> =
>> =
>> =
>> ----------------------------------------------------------------------=
>> ==//
>> +//
>> +// This file defines a JITDwarfEmitter object that is used by the
>> JIT to
>> +// write dwarf tables to memory.
>> +//
>> +//
>> =
>> =
>> =
>> ----------------------------------------------------------------------=
>> ==//
>> +
>> +#include "JIT.h"
>> +#include "JITDwarfEmitter.h"
>> +#include "llvm/Function.h"
>> +#include "llvm/ADT/DenseMap.h"
>> +#include "llvm/CodeGen/AsmPrinter.h"
>> +#include "llvm/CodeGen/MachineCodeEmitter.h"
>> +#include "llvm/CodeGen/MachineFunction.h"
>> +#include "llvm/CodeGen/MachineLocation.h"
>> +#include "llvm/CodeGen/MachineModuleInfo.h"
>> +#include "llvm/ExecutionEngine/JITMemoryManager.h"
>> +#include "llvm/Target/MRegisterInfo.h"
>> +#include "llvm/Target/TargetAsmInfo.h"
>> +#include "llvm/Target/TargetData.h"
>> +#include "llvm/Target/TargetInstrInfo.h"
>> +#include "llvm/Target/TargetFrameInfo.h"
>> +#include "llvm/Target/TargetMachine.h"
>> +
>> +using namespace llvm;
>> +
>> +JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
>> +
>> +
>> +unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
>> + MachineCodeEmitter&
>> mce,
>> + unsigned char*
>> StartFunction,
>> + unsigned char*
>> EndFunction) {
>> + const TargetMachine& TM = F.getTarget();
>> + TD = TM.getTargetData();
>> + needsIndirectEncoding = TM.getTargetAsmInfo()-
>>
>>> getNeedsIndirectEncoding();
>>>
>> + stackGrowthDirection = TM.getFrameInfo()-
>>
>>> getStackGrowthDirection();
>>>
>> + RI = TM.getRegisterInfo();
>> + MCE = &mce;
>> +
>> + unsigned char* ExceptionTable = EmitExceptionTable(&F,
>> StartFunction,
>> + EndFunction);
>> +
>> + unsigned char* Result = 0;
>> + unsigned char* EHFramePtr = 0;
>> +
>> + const std::vector<Function *> Personalities = MMI-
>>
>>> getPersonalities();
>>>
>> + EHFramePtr = EmitCommonEHFrame(Personalities[MMI-
>>
>>> getPersonalityIndex()]);
>>>
>> +
>> + Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()],
>> EHFramePtr,
>> + StartFunction, EndFunction, ExceptionTable);
>> +
>> + return Result;
>> +}
>> +
>> +
>> +void JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
>> + const
std::vector<MachineMove>
>> &Moves) {
>> + unsigned PointerSize = TD->getPointerSize();
>> + int stackGrowth = stackGrowthDirection ==
>> TargetFrameInfo::StackGrowsUp ?
>> + PointerSize : -PointerSize;
>> + bool IsLocal = BaseLabelPtr;
>> +
>> + for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
>> + const MachineMove &Move = Moves[i];
>> + unsigned LabelID = Move.getLabelID();
>> +
>> + if (LabelID) {
>> + LabelID = MMI->MappedLabel(LabelID);
>> +
>> + // Throw out move if the label is invalid.
>> + if (!LabelID) continue;
>> + }
>> +
>> + intptr_t LabelPtr = 0;
>> + if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
>> +
>> + const MachineLocation &Dst = Move.getDestination();
>> + const MachineLocation &Src = Move.getSource();
>> +
>> + // Advance row if new location.
>> + if (BaseLabelPtr && LabelID && (BaseLabelPtr !=
LabelPtr || !
>> IsLocal)) {
>> + MCE->emitByte(dwarf::DW_CFA_advance_loc4);
>> + if (PointerSize == 8) {
>> + MCE->emitInt64(LabelPtr - BaseLabelPtr);
>> + } else {
>> + MCE->emitInt32(LabelPtr - BaseLabelPtr);
>> + }
>> +
>> + BaseLabelPtr = LabelPtr;
>> + IsLocal = true;
>> + }
>> +
>> + // If advancing cfa.
>> + if (Dst.isRegister() && Dst.getRegister() ==
>> MachineLocation::VirtualFP) {
>> + if (!Src.isRegister()) {
>> + if (Src.getRegister() == MachineLocation::VirtualFP) {
>> + MCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
>> + } else {
>> + MCE->emitByte(dwarf::DW_CFA_def_cfa);
>> + MCE->emitULEB128Bytes(RI-
>>
>>> getDwarfRegNum(Src.getRegister(), true));
>>>
>> + }
>> +
>> + int Offset = -Src.getOffset();
>> +
>> + MCE->emitULEB128Bytes(Offset);
>> + } else {
>> + assert(0 && "Machine move no supported
yet.");
>> + }
>> + } else if (Src.isRegister() &&
>> + Src.getRegister() == MachineLocation::VirtualFP) {
>> + if (Dst.isRegister()) {
>> + MCE->emitByte(dwarf::DW_CFA_def_cfa_register);
>> +
MCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister(),
>> true));
>> + } else {
>> + assert(0 && "Machine move no supported
yet.");
>> + }
>> + } else {
>> + unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
>> + int Offset = Dst.getOffset() / stackGrowth;
>> +
>> + if (Offset < 0) {
>> + MCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
>> + MCE->emitULEB128Bytes(Reg);
>> + MCE->emitSLEB128Bytes(Offset);
>> + } else if (Reg < 64) {
>> + MCE->emitByte(dwarf::DW_CFA_offset + Reg);
>> + MCE->emitULEB128Bytes(Offset);
>> + } else {
>> + MCE->emitByte(dwarf::DW_CFA_offset_extended);
>> + MCE->emitULEB128Bytes(Reg);
>> + MCE->emitULEB128Bytes(Offset);
>> + }
>> + }
>> + }
>> +}
>> +
>> +/// SharedTypeIds - How many leading type ids two landing pads have
>> in common.
>> +static unsigned SharedTypeIds(const LandingPadInfo *L,
>> + const LandingPadInfo *R) {
>> + const std::vector<int> &LIds = L->TypeIds, &RIds =
R->TypeIds;
>> + unsigned LSize = LIds.size(), RSize = RIds.size();
>> + unsigned MinSize = LSize < RSize ? LSize : RSize;
>> + unsigned Count = 0;
>> +
>> + for (; Count != MinSize; ++Count)
>> + if (LIds[Count] != RIds[Count])
>> + return Count;
>> +
>> + return Count;
>> +}
>> +
>> +
>> +/// PadLT - Order landing pads lexicographically by type id.
>> +static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
>> + const std::vector<int> &LIds = L->TypeIds, &RIds =
R->TypeIds;
>> + unsigned LSize = LIds.size(), RSize = RIds.size();
>> + unsigned MinSize = LSize < RSize ? LSize : RSize;
>> +
>> + for (unsigned i = 0; i != MinSize; ++i)
>> + if (LIds[i] != RIds[i])
>> + return LIds[i] < RIds[i];
>> +
>> + return LSize < RSize;
>> +}
>> +
>> +struct KeyInfo {
>> + static inline unsigned getEmptyKey() { return -1U; }
>> + static inline unsigned getTombstoneKey() { return -2U; }
>> + static unsigned getHashValue(const unsigned &Key) { return Key;
}
>> + static bool isEqual(unsigned LHS, unsigned RHS) { return LHS ==
>> RHS; }
>> + static bool isPod() { return true; }
>> +};
>> +
>> +/// ActionEntry - Structure describing an entry in the actions table.
>> +struct ActionEntry {
>> + int ValueForTypeID; // The value to write - may not be equal to
>> the type id.
>> + int NextAction;
>> + struct ActionEntry *Previous;
>> +};
>> +
>> +/// PadRange - Structure holding a try-range and the associated
>> landing pad.
>> +struct PadRange {
>> + // The index of the landing pad.
>> + unsigned PadIndex;
>> + // The index of the begin and end labels in the landing pad's
>> label lists.
>> + unsigned RangeIndex;
>> +};
>> +
>> +typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
>> +
>> +/// CallSiteEntry - Structure describing an entry in the call-site
>> table.
>> +struct CallSiteEntry {
>> + unsigned BeginLabel; // zero indicates the start of the function.
>> + unsigned EndLabel; // zero indicates the end of the function.
>> + unsigned PadLabel; // zero indicates that there is no landing
>> pad.
>> + unsigned Action;
>> +};
>> +
>> +unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction*
>> MF,
>> + unsigned char*
>> StartFunction,
>> + unsigned char*
>> EndFunction) {
>> + // Map all labels and get rid of any dead landing pads.
>> + MMI->TidyLandingPads();
>> +
>> + const std::vector<GlobalVariable *> &TypeInfos = MMI-
>>
>>> getTypeInfos();
>>>
>> + const std::vector<unsigned> &FilterIds =
MMI->getFilterIds();
>> + const std::vector<LandingPadInfo> &PadInfos = MMI-
>>
>>> getLandingPads();
>>>
>> + if (PadInfos.empty()) return 0;
>> +
>> + // Sort the landing pads in order of their type ids. This is
>> used to fold
>> + // duplicate actions.
>> + SmallVector<const LandingPadInfo *, 64> LandingPads;
>> + LandingPads.reserve(PadInfos.size());
>> + for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
>> + LandingPads.push_back(&PadInfos[i]);
>> + std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
>> +
>> + // Negative type ids index into FilterIds, positive type ids
>> index into
>> + // TypeInfos. The value written for a positive type id is just
>> the type
>> + // id itself. For a negative type id, however, the value written
>> is the
>> + // (negative) byte offset of the corresponding FilterIds entry.
>> The byte
>> + // offset is usually equal to the type id, because the FilterIds
>> entries
>> + // are written using a variable width encoding which outputs one
>> byte per
>> + // entry as long as the value written is not too large, but can
>> differ.
>> + // This kind of complication does not occur for positive type ids
>> because
>> + // type infos are output using a fixed width encoding.
>> + // FilterOffsets[i] holds the byte offset corresponding to
>> FilterIds[i].
>> + SmallVector<int, 16> FilterOffsets;
>> + FilterOffsets.reserve(FilterIds.size());
>> + int Offset = -1;
>> + for(std::vector<unsigned>::const_iterator I =
FilterIds.begin(),
>> + E = FilterIds.end(); I != E; ++I) {
>> + FilterOffsets.push_back(Offset);
>> + Offset -= AsmPrinter::SizeULEB128(*I);
>> + }
>> +
>> + // Compute the actions table and gather the first action index
>> for each
>> + // landing pad site.
>> + SmallVector<ActionEntry, 32> Actions;
>> + SmallVector<unsigned, 64> FirstActions;
>> + FirstActions.reserve(LandingPads.size());
>> +
>> + int FirstAction = 0;
>> + unsigned SizeActions = 0;
>> + for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
>> + const LandingPadInfo *LP = LandingPads[i];
>> + const std::vector<int> &TypeIds = LP->TypeIds;
>> + const unsigned NumShared = i ? SharedTypeIds(LP,
>> LandingPads[i-1]) : 0;
>> + unsigned SizeSiteActions = 0;
>> +
>> + if (NumShared < TypeIds.size()) {
>> + unsigned SizeAction = 0;
>> + ActionEntry *PrevAction = 0;
>> +
>> + if (NumShared) {
>> + const unsigned SizePrevIds = LandingPads[i-1]-
>>
>>> TypeIds.size();
>>>
>> + assert(Actions.size());
>> + PrevAction = &Actions.back();
>> + SizeAction = AsmPrinter::SizeSLEB128(PrevAction-
>>
>>> NextAction) +
>>>
>> + AsmPrinter::SizeSLEB128(PrevAction->ValueForTypeID);
>> + for (unsigned j = NumShared; j != SizePrevIds; ++j) {
>> + SizeAction -= AsmPrinter::SizeSLEB128(PrevAction-
>>
>>> ValueForTypeID);
>>>
>> + SizeAction += -PrevAction->NextAction;
>> + PrevAction = PrevAction->Previous;
>> + }
>> + }
>> +
>> + // Compute the actions.
>> + for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
>> + int TypeID = TypeIds[I];
>> + assert(-1-TypeID < (int)FilterOffsets.size() &&
"Unknown
>> filter id!");
>> + int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 -
>> TypeID] : TypeID;
>> + unsigned SizeTypeID =
>> AsmPrinter::SizeSLEB128(ValueForTypeID);
>> +
>> + int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
>> + SizeAction = SizeTypeID +
>> AsmPrinter::SizeSLEB128(NextAction);
>> + SizeSiteActions += SizeAction;
>> +
>> + ActionEntry Action = {ValueForTypeID, NextAction,
>> PrevAction};
>> + Actions.push_back(Action);
>> +
>> + PrevAction = &Actions.back();
>> + }
>> +
>> + // Record the first action of the landing pad site.
>> + FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
>> + } // else identical - re-use previous FirstAction
>> +
>> + FirstActions.push_back(FirstAction);
>> +
>> + // Compute this sites contribution to size.
>> + SizeActions += SizeSiteActions;
>> + }
>> +
>> + // Compute the call-site table. Entries must be ordered by
>> address.
>> + SmallVector<CallSiteEntry, 64> CallSites;
>> +
>> + RangeMapType PadMap;
>> + for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
>> + const LandingPadInfo *LandingPad = LandingPads[i];
>> + for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E;
+
>> +j) {
>> + unsigned BeginLabel = LandingPad->BeginLabels[j];
>> + assert(!PadMap.count(BeginLabel) && "Duplicate
landing pad
>> labels!");
>> + PadRange P = { i, j };
>> + PadMap[BeginLabel] = P;
>> + }
>> + }
>> +
>> + bool MayThrow = false;
>> + unsigned LastLabel = 0;
>> + for (MachineFunction::const_iterator I = MF->begin(), E = MF-
>>
>>> end();
>>>
>> + I != E; ++I) {
>> + for (MachineBasicBlock::const_iterator MI = I->begin(), E = I-
>>
>>> end();
>>>
>> + MI != E; ++MI) {
>> + if (MI->getOpcode() != TargetInstrInfo::LABEL) {
>> + MayThrow |= MI->getDesc().isCall();
>> + continue;
>> + }
>> +
>> + unsigned BeginLabel = MI->getOperand(0).getImm();
>> + assert(BeginLabel && "Invalid label!");
>> +
>> + if (BeginLabel == LastLabel)
>> + MayThrow = false;
>> +
>> + RangeMapType::iterator L = PadMap.find(BeginLabel);
>> +
>> + if (L == PadMap.end())
>> + continue;
>> +
>> + PadRange P = L->second;
>> + const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
>> +
>> + assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex]
&&
>> + "Inconsistent landing pad map!");
>> +
>> + // If some instruction between the previous try-range and
>> this one may
>> + // throw, create a call-site entry with no landing pad for
>> the region
>> + // between the try-ranges.
>> + if (MayThrow) {
>> + CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
>> + CallSites.push_back(Site);
>> + }
>> +
>> + LastLabel = LandingPad->EndLabels[P.RangeIndex];
>> + CallSiteEntry Site = {BeginLabel, LastLabel,
>> + LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
>> +
>> + assert(Site.BeginLabel && Site.EndLabel &&
Site.PadLabel &&
>> + "Invalid landing pad!");
>> +
>> + // Try to merge with the previous call-site.
>> + if (CallSites.size()) {
>> + CallSiteEntry &Prev = CallSites[CallSites.size()-1];
>> + if (Site.PadLabel == Prev.PadLabel && Site.Action ==
>> Prev.Action) {
>> + // Extend the range of the previous entry.
>> + Prev.EndLabel = Site.EndLabel;
>> + continue;
>> + }
>> + }
>> +
>> + // Otherwise, create a new call-site.
>> + CallSites.push_back(Site);
>> + }
>> + }
>> + // If some instruction between the previous try-range and the end
>> of the
>> + // function may throw, create a call-site entry with no landing
>> pad for the
>> + // region following the try-range.
>> + if (MayThrow) {
>> + CallSiteEntry Site = {LastLabel, 0, 0, 0};
>> + CallSites.push_back(Site);
>> + }
>> +
>> + // Final tallies.
>> + unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + //
>> Site start.
>> + sizeof(int32_t) + //
>> Site length.
>> + sizeof(int32_t)); //
>> Landing pad.
>> + for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
>> + SizeSites += AsmPrinter::SizeULEB128(CallSites[i].Action);
>> +
>> + unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
>> +
>> + unsigned TypeOffset = sizeof(int8_t) + // Call site format
>> + // Call-site table length
>> + AsmPrinter::SizeULEB128(SizeSites) +
>> + SizeSites + SizeActions + SizeTypes;
>> +
>> + unsigned TotalSize = sizeof(int8_t) + // LPStart format
>> + sizeof(int8_t) + // TType format
>> + AsmPrinter::SizeULEB128(TypeOffset) + //
>> TType base offset
>> + TypeOffset;
>> +
>> + unsigned SizeAlign = (4 - TotalSize) & 3;
>> +
>> + // Begin the exception table.
>> + MCE->emitAlignment(4);
>> + for (unsigned i = 0; i != SizeAlign; ++i) {
>> + MCE->emitByte(0);
>> + // Asm->EOL("Padding");
>> + }
>> +
>> + unsigned char* DwarfExceptionTable = (unsigned char*)MCE-
>>
>>> getCurrentPCValue();
>>>
>> +
>> + // Emit the header.
>> + MCE->emitByte(dwarf::DW_EH_PE_omit);
>> + // Asm->EOL("LPStart format (DW_EH_PE_omit)");
>> + MCE->emitByte(dwarf::DW_EH_PE_absptr);
>> + // Asm->EOL("TType format (DW_EH_PE_absptr)");
>> + MCE->emitULEB128Bytes(TypeOffset);
>> + // Asm->EOL("TType base offset");
>> + MCE->emitByte(dwarf::DW_EH_PE_udata4);
>> + // Asm->EOL("Call site format (DW_EH_PE_udata4)");
>> + MCE->emitULEB128Bytes(SizeSites);
>> + // Asm->EOL("Call-site table length");
>> +
>> + // Emit the landing pad site information.
>> + for (unsigned i = 0; i < CallSites.size(); ++i) {
>> + CallSiteEntry &S = CallSites[i];
>> + intptr_t BeginLabelPtr = 0;
>> + intptr_t EndLabelPtr = 0;
>> +
>> + if (!S.BeginLabel) {
>> + BeginLabelPtr = (intptr_t)StartFunction;
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32(0);
>> + else
>> + MCE->emitInt64(0);
>> + } else {
>> + BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel);
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
>> + else
>> + MCE->emitInt64(BeginLabelPtr - (intptr_t)StartFunction);
>> + }
>> +
>> + // Asm->EOL("Region start");
>> +
>> + if (!S.EndLabel) {
>> + EndLabelPtr = (intptr_t)EndFunction;
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
>> + else
>> + MCE->emitInt64((intptr_t)EndFunction - BeginLabelPtr);
>> + } else {
>> + EndLabelPtr = MCE->getLabelAddress(S.EndLabel);
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32(EndLabelPtr - BeginLabelPtr);
>> + else
>> + MCE->emitInt64(EndLabelPtr - BeginLabelPtr);
>> + }
>> + //Asm->EOL("Region length");
>> +
>> + if (!S.PadLabel) {
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32(0);
>> + else
>> + MCE->emitInt64(0);
>> + } else {
>> + unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel);
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
>> + else
>> + MCE->emitInt64(PadLabelPtr - (intptr_t)StartFunction);
>> + }
>> + // Asm->EOL("Landing pad");
>> +
>> + MCE->emitULEB128Bytes(S.Action);
>> + // Asm->EOL("Action");
>> + }
>> +
>> + // Emit the actions.
>> + for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
>> + ActionEntry &Action = Actions[I];
>> +
>> + MCE->emitSLEB128Bytes(Action.ValueForTypeID);
>> + //Asm->EOL("TypeInfo index");
>> + MCE->emitSLEB128Bytes(Action.NextAction);
>> + //Asm->EOL("Next action");
>> + }
>> +
>> + // Emit the type ids.
>> + for (unsigned M = TypeInfos.size(); M; --M) {
>> + GlobalVariable *GV = TypeInfos[M - 1];
>> +
>> + if (GV) {
>> + if (TD->getPointerSize() == sizeof(int32_t)) {
>> + MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
>> + } else {
>> + MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
>> + }
>> + } else {
>> + if (TD->getPointerSize() == sizeof(int32_t))
>> + MCE->emitInt32(0);
>> + else
>> + MCE->emitInt64(0);
>> + }
>> + // Asm->EOL("TypeInfo");
>> + }
>> +
>> + // Emit the filter typeids.
>> + for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
>> + unsigned TypeID = FilterIds[j];
>> + MCE->emitULEB128Bytes(TypeID);
>> + //Asm->EOL("Filter TypeInfo index");
>> + }
>> +
>> + MCE->emitAlignment(4);
>> +
>> + return DwarfExceptionTable;
>> +}
>> +
>> +unsigned char* JITDwarfEmitter::EmitCommonEHFrame(const Function*
>> Personality) {
>> + unsigned PointerSize = TD->getPointerSize();
>> + int stackGrowth = stackGrowthDirection ==
>> TargetFrameInfo::StackGrowsUp ?
>> + PointerSize : -PointerSize;
>> +
>> + unsigned char* StartCommonPtr = (unsigned char*)MCE-
>>
>>> getCurrentPCValue();
>>>
>> + // EH Common Frame header
>> + MCE->allocateSpace(PointerSize, 0);
>> + unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE-
>>
>>> getCurrentPCValue();
>>>
>> + MCE->emitInt32((int)0);
>> + MCE->emitByte(dwarf::DW_CIE_VERSION);
>> + MCE->emitString(Personality ? "zPLR" : "zR");
>> + MCE->emitULEB128Bytes(1);
>> + MCE->emitSLEB128Bytes(stackGrowth);
>> + MCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(),
true));
>> +
>> + if (Personality) {
>> + MCE->emitULEB128Bytes(7);
>> +
>> + if (needsIndirectEncoding)
>> + MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
|
>> + dwarf::DW_EH_PE_indirect);
>> + else
>> + MCE->emitByte(dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4);
>> +
>> + if (PointerSize == 8)
>> + MCE->emitInt64((intptr_t)Jit.getPointerToGlobal(Personality)
-
>> + MCE->getCurrentPCValue());
>> + else
>> + MCE->emitInt32((intptr_t)Jit.getPointerToGlobal(Personality)
-
>> + MCE->getCurrentPCValue());
>> +
>> + MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
>> + MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
>> +
>> + } else {
>> + MCE->emitULEB128Bytes(1);
>> + MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
>> + }
>> +
>> + std::vector<MachineMove> Moves;
>> + RI->getInitialFrameState(Moves);
>> + EmitFrameMoves(0, Moves);
>> + MCE->emitAlignment(4);
>> +
>> + MCE->emitAt((uintptr_t*)StartCommonPtr,
>> + (uintptr_t)((unsigned char*)MCE->getCurrentPCValue()
-
>> + FrameCommonBeginPtr));
>> +
>> + return StartCommonPtr;
>> +}
>> +
>> +
>> +unsigned char* JITDwarfEmitter::EmitEHFrame(const Function*
>> Personality,
>> + unsigned char*
>> StartCommonPtr,
>> + unsigned char*
>> StartFunction,
>> + unsigned char*
>> EndFunction,
>> + unsigned char*
>> ExceptionTable) {
>> + unsigned PointerSize = TD->getPointerSize();
>> +
>> + // EH frame header.
>> + unsigned char* StartEHPtr = (unsigned char*)MCE-
>>
>>> getCurrentPCValue();
>>>
>> + MCE->allocateSpace(PointerSize, 0);
>> + unsigned char* FrameBeginPtr = (unsigned char*)MCE-
>>
>>> getCurrentPCValue();
>>>
>> + // FDE CIE Offset
>> + if (PointerSize == 8) {
>> + MCE->emitInt64(FrameBeginPtr - StartCommonPtr);
>> + MCE->emitInt64(StartFunction - (unsigned char*)MCE-
>>
>>> getCurrentPCValue());
>>>
>> + MCE->emitInt64(EndFunction - StartFunction);
>> + } else {
>> + MCE->emitInt32(FrameBeginPtr - StartCommonPtr);
>> + MCE->emitInt32(StartFunction - (unsigned char*)MCE-
>>
>>> getCurrentPCValue());
>>>
>> + MCE->emitInt32(EndFunction - StartFunction);
>> + }
>> +
>> + // If there is a personality and landing pads then point to the
>> language
>> + // specific data area in the exception table.
>> + if (MMI->getPersonalityIndex()) {
>> + MCE->emitULEB128Bytes(4);
>> +
>> + if (!MMI->getLandingPads().empty()) {
>> + if (PointerSize == 8)
>> + MCE->emitInt64(ExceptionTable - (unsigned char*)MCE-
>>
>>> getCurrentPCValue());
>>>
>> + else
>> + MCE->emitInt32(ExceptionTable - (unsigned char*)MCE-
>>
>>> getCurrentPCValue());
>>>
>> + } else if (PointerSize == 8) {
>> + MCE->emitInt64((int)0);
>> + } else {
>> + MCE->emitInt32((int)0);
>> + }
>> + } else {
>> + MCE->emitULEB128Bytes(0);
>> + }
>> +
>> + // Indicate locations of function specific callee saved
>> registers in
>> + // frame.
>> + EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
>> +
>> + MCE->emitAlignment(4);
>> +
>> + // Indicate the size of the table
>> + MCE->emitAt((uintptr_t*)StartEHPtr,
>> + (uintptr_t)((unsigned char*)MCE->getCurrentPCValue()
-
>> + StartEHPtr));
>> +
>> + // Double zeroes for the unwind runtime
>> + if (PointerSize == 8) {
>> + MCE->emitInt64(0);
>> + MCE->emitInt64(0);
>> + } else {
>> + MCE->emitInt32(0);
>> + MCE->emitInt32(0);
>> + }
>> +
>> +
>> + return StartEHPtr;
>> +}
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>