diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-07 20:53:59 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-07 20:53:59 +0000 |
commit | e4496548155ba6606f107fbdc10ea17e58fd3401 (patch) | |
tree | 17c17dc523c763cbea08e75f19e757c40ad8777c | |
parent | baa52fff392bbf2133eb0c948d56bdc4e4c1b7f9 (diff) | |
download | external_llvm-e4496548155ba6606f107fbdc10ea17e58fd3401.zip external_llvm-e4496548155ba6606f107fbdc10ea17e58fd3401.tar.gz external_llvm-e4496548155ba6606f107fbdc10ea17e58fd3401.tar.bz2 |
Remove exception handling support from the old JIT.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181354 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/ReleaseNotes_34.rst | 3 | ||||
-rw-r--r-- | examples/ExceptionDemo/ExceptionDemo.cpp | 1 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/JITMemoryManager.h | 16 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/SectionMemoryManager.h | 12 | ||||
-rw-r--r-- | include/llvm/Target/TargetOptions.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/TargetOptionsImpl.cpp | 1 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp | 596 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 47 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITMemoryManager.cpp | 26 | ||||
-rw-r--r-- | tools/lli/RecordingMemoryManager.cpp | 11 | ||||
-rw-r--r-- | tools/lli/RecordingMemoryManager.h | 5 | ||||
-rw-r--r-- | tools/lli/lli.cpp | 6 | ||||
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITTest.cpp | 110 |
14 files changed, 5 insertions, 836 deletions
diff --git a/docs/ReleaseNotes_34.rst b/docs/ReleaseNotes_34.rst index 8b5624e..7decad0 100644 --- a/docs/ReleaseNotes_34.rst +++ b/docs/ReleaseNotes_34.rst @@ -41,6 +41,9 @@ Non-comprehensive list of changes in this release functionality, or simply have a lot to talk about), see the `NOTE` below for adding a new subsection. +* Support for exception handling has been removed from the old JIT. Use MCJIT + if you need EH support. + * ... next change ... .. NOTE diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index f9498a5..cf39ea7 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -1950,7 +1950,6 @@ int main(int argc, char *argv[]) { // If not set, exception handling will not be turned on llvm::TargetOptions Opts; - Opts.JITExceptionHandling = true; llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 714a980..b22d899 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -115,22 +115,6 @@ public: /// emitting a function. virtual void deallocateFunctionBody(void *Body) = 0; - /// startExceptionTable - When we finished JITing the function, if exception - /// handling is set, we emit the exception table. - virtual uint8_t* 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, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) = 0; - - /// deallocateExceptionTable - Free the specified exception table's memory. - /// The argument must be the return value from a call to startExceptionTable() - /// that hasn't been deallocated yet. This is never called when the JIT is - /// currently emitting an exception table. - virtual void deallocateExceptionTable(void *ET) = 0; - /// CheckInvariants - For testing only. Return true if all internal /// invariants are preserved, or return false and set ErrorStr to a helpful /// error message. diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h index 84a4e08..07e6832 100644 --- a/include/llvm/ExecutionEngine/SectionMemoryManager.h +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -156,18 +156,6 @@ public: virtual void deallocateFunctionBody(void *Body) { llvm_unreachable("Unexpected call!"); } - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t *FrameRegister) { - llvm_unreachable("Unexpected call!"); - } - virtual void deallocateExceptionTable(void *ET) { - llvm_unreachable("Unexpected call!"); - } }; } diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index c763a59..31c4c75 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -45,7 +45,7 @@ namespace llvm { NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false), UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false), - UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false), + UseSoftFloat(false), NoZerosInBSS(false), JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false), DisableTailCalls(false), StackAlignmentOverride(0), RealignStack(true), SSPBufferSize(0), @@ -123,10 +123,6 @@ namespace llvm { /// crt*.o compiling). unsigned NoZerosInBSS : 1; - /// JITExceptionHandling - This flag indicates that the JIT should emit - /// exception handling information. - unsigned JITExceptionHandling : 1; - /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit /// debug information and notify a debugger about it. unsigned JITEmitDebugInfo : 1; diff --git a/lib/CodeGen/TargetOptionsImpl.cpp b/lib/CodeGen/TargetOptionsImpl.cpp index 435a5e7..c9c88c1 100644 --- a/lib/CodeGen/TargetOptionsImpl.cpp +++ b/lib/CodeGen/TargetOptionsImpl.cpp @@ -59,7 +59,6 @@ bool TargetOptions::operator==(const TargetOptions &TO) { ARE_EQUAL(HonorSignDependentRoundingFPMathOption) && ARE_EQUAL(UseSoftFloat) && ARE_EQUAL(NoZerosInBSS) && - ARE_EQUAL(JITExceptionHandling) && ARE_EQUAL(JITEmitDebugInfo) && ARE_EQUAL(JITEmitDebugInfoToDisk) && ARE_EQUAL(GuaranteedTailCallOpt) && diff --git a/lib/ExecutionEngine/JIT/CMakeLists.txt b/lib/ExecutionEngine/JIT/CMakeLists.txt index 52bb389..e16baed 100644 --- a/lib/ExecutionEngine/JIT/CMakeLists.txt +++ b/lib/ExecutionEngine/JIT/CMakeLists.txt @@ -3,7 +3,6 @@ add_definitions(-DENABLE_X86_JIT) add_llvm_library(LLVMJIT JIT.cpp - JITDwarfEmitter.cpp JITEmitter.cpp JITMemoryManager.cpp ) diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp deleted file mode 100644 index 35d2b8b..0000000 --- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp +++ /dev/null @@ -1,596 +0,0 @@ -//===----- 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 "JITDwarfEmitter.h" -#include "JIT.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/CodeGen/JITCodeEmitter.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Function.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -using namespace llvm; - -JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : MMI(0), Jit(theJit) {} - - -unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, - JITCodeEmitter& jce, - unsigned char* StartFunction, - unsigned char* EndFunction, - unsigned char* &EHFramePtr) { - assert(MMI && "MachineModuleInfo not registered!"); - - const TargetMachine& TM = F.getTarget(); - TD = TM.getDataLayout(); - stackGrowthDirection = TM.getFrameLowering()->getStackGrowthDirection(); - RI = TM.getRegisterInfo(); - MAI = TM.getMCAsmInfo(); - JCE = &jce; - - unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction, - EndFunction); - - unsigned char* Result = 0; - - const std::vector<const 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) const { - unsigned PointerSize = TD->getPointerSize(); - int stackGrowth = stackGrowthDirection == TargetFrameLowering::StackGrowsUp ? - PointerSize : -PointerSize; - MCSymbol *BaseLabel = 0; - - for (unsigned i = 0, N = Moves.size(); i < N; ++i) { - const MachineMove &Move = Moves[i]; - MCSymbol *Label = Move.getLabel(); - - // Throw out move if the label is invalid. - if (Label && (*JCE->getLabelLocations())[Label] == 0) - continue; - - intptr_t LabelPtr = 0; - if (Label) LabelPtr = JCE->getLabelAddress(Label); - - const MachineLocation &Dst = Move.getDestination(); - const MachineLocation &Src = Move.getSource(); - - // Advance row if new location. - if (BaseLabelPtr && Label && BaseLabel != Label) { - JCE->emitByte(dwarf::DW_CFA_advance_loc4); - JCE->emitInt32(LabelPtr - BaseLabelPtr); - - BaseLabel = Label; - BaseLabelPtr = LabelPtr; - } - - // If advancing cfa. - if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { - if (!Src.isReg()) { - if (Src.getReg() == MachineLocation::VirtualFP) { - JCE->emitByte(dwarf::DW_CFA_def_cfa_offset); - } else { - JCE->emitByte(dwarf::DW_CFA_def_cfa); - JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true)); - } - - JCE->emitULEB128Bytes(-Src.getOffset()); - } else { - llvm_unreachable("Machine move not supported yet."); - } - } else if (Src.isReg() && - Src.getReg() == MachineLocation::VirtualFP) { - if (Dst.isReg()) { - JCE->emitByte(dwarf::DW_CFA_def_cfa_register); - JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true)); - } else { - llvm_unreachable("Machine move not supported yet."); - } - } else { - unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true); - int Offset = Dst.getOffset() / stackGrowth; - - if (Offset < 0) { - JCE->emitByte(dwarf::DW_CFA_offset_extended_sf); - JCE->emitULEB128Bytes(Reg); - JCE->emitSLEB128Bytes(Offset); - } else if (Reg < 64) { - JCE->emitByte(dwarf::DW_CFA_offset + Reg); - JCE->emitULEB128Bytes(Offset); - } else { - JCE->emitByte(dwarf::DW_CFA_offset_extended); - JCE->emitULEB128Bytes(Reg); - JCE->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; -} - -namespace { - -/// 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<MCSymbol*, PadRange> RangeMapType; - -/// CallSiteEntry - Structure describing an entry in the call-site table. -struct CallSiteEntry { - MCSymbol *BeginLabel; // zero indicates the start of the function. - MCSymbol *EndLabel; // zero indicates the end of the function. - MCSymbol *PadLabel; // zero indicates that there is no landing pad. - unsigned Action; -}; - -} - -unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF, - unsigned char* StartFunction, - unsigned char* EndFunction) const { - assert(MMI && "MachineModuleInfo not registered!"); - - // Map all labels and get rid of any dead landing pads. - MMI->TidyLandingPads(JCE->getLabelLocations()); - - const std::vector<const 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 -= MCAsmInfo::getULEB128Size(*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 = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) + - MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); - for (unsigned j = NumShared; j != SizePrevIds; ++j) { - SizeAction -= MCAsmInfo::getSLEB128Size(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 = MCAsmInfo::getSLEB128Size(ValueForTypeID); - - int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; - SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(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) { - MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; - assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); - PadRange P = { i, j }; - PadMap[BeginLabel] = P; - } - } - - bool MayThrow = false; - MCSymbol *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->isLabel()) { - MayThrow |= MI->isCall(); - continue; - } - - MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol(); - 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.back(); - 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 += MCAsmInfo::getULEB128Size(CallSites[i].Action); - - unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize(); - - unsigned TypeOffset = sizeof(int8_t) + // Call site format - // Call-site table length - MCAsmInfo::getULEB128Size(SizeSites) + - SizeSites + SizeActions + SizeTypes; - - // Begin the exception table. - JCE->emitAlignmentWithFill(4, 0); - // Asm->EOL("Padding"); - - unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue(); - - // Emit the header. - JCE->emitByte(dwarf::DW_EH_PE_omit); - // Asm->EOL("LPStart format (DW_EH_PE_omit)"); - JCE->emitByte(dwarf::DW_EH_PE_absptr); - // Asm->EOL("TType format (DW_EH_PE_absptr)"); - JCE->emitULEB128Bytes(TypeOffset); - // Asm->EOL("TType base offset"); - JCE->emitByte(dwarf::DW_EH_PE_udata4); - // Asm->EOL("Call site format (DW_EH_PE_udata4)"); - JCE->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; - JCE->emitInt32(0); - } else { - BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel); - JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction); - } - - // Asm->EOL("Region start"); - - if (!S.EndLabel) - EndLabelPtr = (intptr_t)EndFunction; - else - EndLabelPtr = JCE->getLabelAddress(S.EndLabel); - - JCE->emitInt32(EndLabelPtr - BeginLabelPtr); - //Asm->EOL("Region length"); - - if (!S.PadLabel) { - JCE->emitInt32(0); - } else { - unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel); - JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction); - } - // Asm->EOL("Landing pad"); - - JCE->emitULEB128Bytes(S.Action); - // Asm->EOL("Action"); - } - - // Emit the actions. - for (unsigned I = 0, N = Actions.size(); I != N; ++I) { - ActionEntry &Action = Actions[I]; - - JCE->emitSLEB128Bytes(Action.ValueForTypeID); - //Asm->EOL("TypeInfo index"); - JCE->emitSLEB128Bytes(Action.NextAction); - //Asm->EOL("Next action"); - } - - // Emit the type ids. - for (unsigned M = TypeInfos.size(); M; --M) { - const GlobalVariable *GV = TypeInfos[M - 1]; - - if (GV) { - if (TD->getPointerSize() == sizeof(int32_t)) - JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV)); - else - JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV)); - } else { - if (TD->getPointerSize() == sizeof(int32_t)) - JCE->emitInt32(0); - else - JCE->emitInt64(0); - } - // Asm->EOL("TypeInfo"); - } - - // Emit the filter typeids. - for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { - unsigned TypeID = FilterIds[j]; - JCE->emitULEB128Bytes(TypeID); - //Asm->EOL("Filter TypeInfo index"); - } - - JCE->emitAlignmentWithFill(4, 0); - - return DwarfExceptionTable; -} - -unsigned char* -JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const { - unsigned PointerSize = TD->getPointerSize(); - int stackGrowth = stackGrowthDirection == TargetFrameLowering::StackGrowsUp ? - PointerSize : -PointerSize; - - unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue(); - // EH Common Frame header - JCE->allocateSpace(4, 0); - unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue(); - JCE->emitInt32((int)0); - JCE->emitByte(dwarf::DW_CIE_VERSION); - JCE->emitString(Personality ? "zPLR" : "zR"); - JCE->emitULEB128Bytes(1); - JCE->emitSLEB128Bytes(stackGrowth); - JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true)); - - if (Personality) { - // Augmentation Size: 3 small ULEBs of one byte each, and the personality - // function which size is PointerSize. - JCE->emitULEB128Bytes(3 + PointerSize); - - // We set the encoding of the personality as direct encoding because we use - // the function pointer. The encoding is not relative because the current - // PC value may be bigger than the personality function pointer. - if (PointerSize == 4) { - JCE->emitByte(dwarf::DW_EH_PE_sdata4); - JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality))); - } else { - JCE->emitByte(dwarf::DW_EH_PE_sdata8); - JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality))); - } - - // LSDA encoding: This must match the encoding used in EmitEHFrame () - if (PointerSize == 4) - JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - else - JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8); - JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - } else { - JCE->emitULEB128Bytes(1); - JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - } - - EmitFrameMoves(0, MAI->getInitialFrameState()); - - JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop); - - JCE->emitInt32At((uintptr_t*)StartCommonPtr, - (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() - - FrameCommonBeginPtr)); - - return StartCommonPtr; -} - - -unsigned char* -JITDwarfEmitter::EmitEHFrame(const Function* Personality, - unsigned char* StartCommonPtr, - unsigned char* StartFunction, - unsigned char* EndFunction, - unsigned char* ExceptionTable) const { - unsigned PointerSize = TD->getPointerSize(); - - // EH frame header. - unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue(); - JCE->allocateSpace(4, 0); - unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue(); - // FDE CIE Offset - JCE->emitInt32(FrameBeginPtr - StartCommonPtr); - JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue()); - JCE->emitInt32(EndFunction - StartFunction); - - // If there is a personality and landing pads then point to the language - // specific data area in the exception table. - if (Personality) { - JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8); - - if (PointerSize == 4) { - if (!MMI->getLandingPads().empty()) - JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue()); - else - JCE->emitInt32((int)0); - } else { - if (!MMI->getLandingPads().empty()) - JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue()); - else - JCE->emitInt64((int)0); - } - } else { - JCE->emitULEB128Bytes(0); - } - - // Indicate locations of function specific callee saved registers in - // frame. - EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves()); - - JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop); - - // Indicate the size of the table - JCE->emitInt32At((uintptr_t*)StartEHPtr, - (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() - - StartEHPtr)); - - // Double zeroes for the unwind runtime - if (PointerSize == 8) { - JCE->emitInt64(0); - JCE->emitInt64(0); - } else { - JCE->emitInt32(0); - JCE->emitInt32(0); - } - - return StartEHPtr; -} diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index c273876..d813c53 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -363,22 +363,16 @@ namespace { /// Instance of the JIT JIT *TheJIT; - bool JITExceptionHandling; - public: JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) : SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0), - EmittedFunctions(this), TheJIT(&jit), - JITExceptionHandling(TM.Options.JITExceptionHandling) { + EmittedFunctions(this), TheJIT(&jit) { MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); if (jit.getJITInfo().needsGOT()) { MemMgr->AllocateGOT(); DEBUG(dbgs() << "JIT is managing a GOT\n"); } - if (JITExceptionHandling) { - DE.reset(new JITDwarfEmitter(jit)); - } } ~JITEmitter() { delete MemMgr; @@ -964,40 +958,6 @@ bool JITEmitter::finishFunction(MachineFunction &F) { } }); - if (JITExceptionHandling) { - uintptr_t ActualSize = 0; - SavedBufferBegin = BufferBegin; - SavedBufferEnd = BufferEnd; - SavedCurBufferPtr = CurBufferPtr; - uint8_t *FrameRegister; - - while (true) { - BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), - ActualSize); - BufferEnd = BufferBegin+ActualSize; - EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin; - uint8_t *EhStart; - FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart); - - // If the buffer was large enough to hold the table then we are done. - if (CurBufferPtr != BufferEnd) - break; - - // Try again with twice as much space. - ActualSize = (CurBufferPtr - BufferBegin) * 2; - MemMgr->deallocateExceptionTable(BufferBegin); - } - MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, - FrameRegister); - BufferBegin = SavedBufferBegin; - BufferEnd = SavedBufferEnd; - CurBufferPtr = SavedCurBufferPtr; - - if (JITExceptionHandling) { - TheJIT->RegisterTable(F.getFunction(), FrameRegister); - } - } - if (MMI) MMI->EndFunction(); @@ -1027,15 +987,10 @@ void JITEmitter::deallocateMemForFunction(const Function *F) { Emitted = EmittedFunctions.find(F); if (Emitted != EmittedFunctions.end()) { MemMgr->deallocateFunctionBody(Emitted->second.FunctionBody); - MemMgr->deallocateExceptionTable(Emitted->second.ExceptionTable); TheJIT->NotifyFreeingMachineCode(Emitted->second.Code); EmittedFunctions.erase(Emitted); } - - if (JITExceptionHandling) { - TheJIT->DeregisterTable(F); - } } diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp index 66aeb77..bf5680d 100644 --- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp +++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp @@ -513,26 +513,6 @@ namespace { return false; } - /// startExceptionTable - Use startFunctionBody to allocate memory for the - /// function's exception table. - uint8_t* 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, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) { - assert(TableEnd > TableStart); - assert(TableStart == (uint8_t *)(CurBlock+1) && - "Mismatched table start/end!"); - - uintptr_t BlockSize = TableEnd - (uint8_t *)CurBlock; - - // Release the memory at the end of this block that isn't needed. - FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); - } - uint8_t *getGOTBase() const { return GOTBase; } @@ -557,12 +537,6 @@ namespace { if (Body) deallocateBlock(Body); } - /// deallocateExceptionTable - Deallocate memory for the specified - /// exception table. - void deallocateExceptionTable(void *ET) { - if (ET) deallocateBlock(ET); - } - /// setMemoryWritable - When code generation is in progress, /// the code pages may need permissions changed. void setMemoryWritable() diff --git a/tools/lli/RecordingMemoryManager.cpp b/tools/lli/RecordingMemoryManager.cpp index e4d992d..1fa8176 100644 --- a/tools/lli/RecordingMemoryManager.cpp +++ b/tools/lli/RecordingMemoryManager.cpp @@ -98,17 +98,6 @@ uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignme void RecordingMemoryManager::deallocateFunctionBody(void *Body) { llvm_unreachable("Unexpected!"); } -uint8_t* RecordingMemoryManager::startExceptionTable(const Function* F, uintptr_t &ActualSize) { - llvm_unreachable("Unexpected!"); - return 0; -} -void RecordingMemoryManager::endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) { - llvm_unreachable("Unexpected!"); -} -void RecordingMemoryManager::deallocateExceptionTable(void *ET) { - llvm_unreachable("Unexpected!"); -} static int jit_noop() { return 0; diff --git a/tools/lli/RecordingMemoryManager.h b/tools/lli/RecordingMemoryManager.h index 991f535..f3d026f 100644 --- a/tools/lli/RecordingMemoryManager.h +++ b/tools/lli/RecordingMemoryManager.h @@ -75,11 +75,6 @@ public: uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment); void deallocateFunctionBody(void *Body); - uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize); - void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister); - void deallocateExceptionTable(void *ET); - }; } // end namespace llvm diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 297763f..1866403 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -159,11 +159,6 @@ namespace { clEnumValEnd)); cl::opt<bool> - EnableJITExceptionHandling("jit-enable-eh", - cl::desc("Emit exception handling information"), - cl::init(false)); - - cl::opt<bool> GenerateSoftFloatCalls("soft-float", cl::desc("Generate software floating point library calls"), cl::init(false)); @@ -381,7 +376,6 @@ int main(int argc, char **argv, char * const *envp) { // Remote target execution doesn't handle EH or debug registration. if (!RemoteMCJIT) { - Options.JITExceptionHandling = EnableJITExceptionHandling; Options.JITEmitDebugInfo = EmitJitDebugInfo; Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk; } diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index e6f4cb9..cf995aa 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -143,54 +143,6 @@ public: deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body)); Base->deallocateFunctionBody(Body); } - struct DeallocateExceptionTableCall { - DeallocateExceptionTableCall(const void *ET) : ET(ET) {} - const void *ET; - }; - std::vector<DeallocateExceptionTableCall> deallocateExceptionTableCalls; - virtual void deallocateExceptionTable(void *ET) { - deallocateExceptionTableCalls.push_back(DeallocateExceptionTableCall(ET)); - Base->deallocateExceptionTable(ET); - } - struct StartExceptionTableCall { - StartExceptionTableCall(uint8_t *Result, const Function *F, - uintptr_t ActualSize, uintptr_t ActualSizeResult) - : Result(Result), F(F), F_dump(DumpFunction(F)), - ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {} - uint8_t *Result; - const Function *F; - std::string F_dump; - uintptr_t ActualSize; - uintptr_t ActualSizeResult; - }; - std::vector<StartExceptionTableCall> startExceptionTableCalls; - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - uintptr_t InitialActualSize = ActualSize; - uint8_t *Result = Base->startExceptionTable(F, ActualSize); - startExceptionTableCalls.push_back( - StartExceptionTableCall(Result, F, InitialActualSize, ActualSize)); - return Result; - } - struct EndExceptionTableCall { - EndExceptionTableCall(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) - : F(F), F_dump(DumpFunction(F)), - TableStart(TableStart), TableEnd(TableEnd), - FrameRegister(FrameRegister) {} - const Function *F; - std::string F_dump; - uint8_t *TableStart; - uint8_t *TableEnd; - uint8_t *FrameRegister; - }; - std::vector<EndExceptionTableCall> endExceptionTableCalls; - virtual void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) { - endExceptionTableCalls.push_back( - EndExceptionTableCall(F, TableStart, TableEnd, FrameRegister)); - return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister); - } }; bool LoadAssemblyInto(Module *M, const char *assembly) { @@ -216,7 +168,6 @@ class JITTest : public testing::Test { RJMM->setPoisonMemory(true); std::string Error; TargetOptions Options; - Options.JITExceptionHandling = true; TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT) .setJITMemoryManager(RJMM) .setErrorStr(&Error) @@ -302,46 +253,6 @@ TEST(JIT, GlobalInFunction) { EXPECT_EQ(3, *GPtr); } -// Regression test for a bug. The JITEmitter wasn't checking to verify that -// it hadn't run out of space while generating the DWARF exception information -// for an emitted function. - -class ExceptionMemoryManagerMock : public RecordingJITMemoryManager { - public: - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - // force an insufficient size the first time through. - bool ChangeActualSize = false; - if (ActualSize == 0) - ChangeActualSize = true;; - uint8_t *result = - RecordingJITMemoryManager::startExceptionTable(F, ActualSize); - if (ChangeActualSize) - ActualSize = 1; - return result; - } -}; - -class JITExceptionMemoryTest : public JITTest { - protected: - virtual RecordingJITMemoryManager *createMemoryManager() { - return new ExceptionMemoryManagerMock; - } -}; - -TEST_F(JITExceptionMemoryTest, ExceptionTableOverflow) { - Function *F = Function::Create(TypeBuilder<void(void), false>::get(Context), - Function::ExternalLinkage, - "func1", M); - BasicBlock *Block = BasicBlock::Create(Context, "block", F); - IRBuilder<> Builder(Block); - Builder.CreateRetVoid(); - TheJIT->getPointerToFunction(F); - ASSERT_TRUE(RJMM->startExceptionTableCalls.size() == 2); - ASSERT_TRUE(RJMM->deallocateExceptionTableCalls.size() == 1); - ASSERT_TRUE(RJMM->endExceptionTableCalls.size() == 1); -} - int PlusOne(int arg) { return arg + 1; } @@ -501,27 +412,6 @@ TEST_F(JITTest, ModuleDeletion) { } EXPECT_EQ(RJMM->startFunctionBodyCalls.size(), RJMM->deallocateFunctionBodyCalls.size()); - - SmallPtrSet<const void*, 2> ExceptionTablesDeallocated; - unsigned NumTablesDeallocated = 0; - for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size(); - i != e; ++i) { - ExceptionTablesDeallocated.insert( - RJMM->deallocateExceptionTableCalls[i].ET); - if (RJMM->deallocateExceptionTableCalls[i].ET != NULL) { - // If JITEmitDebugInfo is off, we'll "deallocate" NULL, which doesn't - // appear in startExceptionTableCalls. - NumTablesDeallocated++; - } - } - for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) { - EXPECT_TRUE(ExceptionTablesDeallocated.count( - RJMM->startExceptionTableCalls[i].Result)) - << "Function's exception table leaked: \n" - << RJMM->startExceptionTableCalls[i].F_dump; - } - EXPECT_EQ(RJMM->startExceptionTableCalls.size(), - NumTablesDeallocated); } // ARM, MIPS and PPC still emit stubs for calls since the target may be |