LLVM API Documentation

JITDwarfEmitter.cpp

Go to the documentation of this file.
00001 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines a JITDwarfEmitter object that is used by the JIT to
00011 // write dwarf tables to memory.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "JIT.h"
00016 #include "JITDwarfEmitter.h"
00017 #include "llvm/Function.h"
00018 #include "llvm/ADT/DenseMap.h"
00019 #include "llvm/CodeGen/MachineCodeEmitter.h"
00020 #include "llvm/CodeGen/MachineFunction.h"
00021 #include "llvm/CodeGen/MachineLocation.h"
00022 #include "llvm/CodeGen/MachineModuleInfo.h"
00023 #include "llvm/ExecutionEngine/JITMemoryManager.h"
00024 #include "llvm/Target/TargetAsmInfo.h"
00025 #include "llvm/Target/TargetData.h"
00026 #include "llvm/Target/TargetInstrInfo.h"
00027 #include "llvm/Target/TargetFrameInfo.h"
00028 #include "llvm/Target/TargetMachine.h"
00029 #include "llvm/Target/TargetRegisterInfo.h"
00030 
00031 using namespace llvm;
00032 
00033 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
00034 
00035 
00036 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, 
00037                                                MachineCodeEmitter& mce,
00038                                                unsigned char* StartFunction,
00039                                                unsigned char* EndFunction) {
00040   const TargetMachine& TM = F.getTarget();
00041   TD = TM.getTargetData();
00042   needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
00043   stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
00044   RI = TM.getRegisterInfo();
00045   MCE = &mce;
00046   
00047   unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
00048                                                      EndFunction);
00049       
00050   unsigned char* Result = 0;
00051   unsigned char* EHFramePtr = 0;
00052 
00053   const std::vector<Function *> Personalities = MMI->getPersonalities();
00054   EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
00055 
00056   Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
00057                        StartFunction, EndFunction, ExceptionTable);
00058   
00059   return Result;
00060 }
00061 
00062 
00063 void 
00064 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
00065                                 const std::vector<MachineMove> &Moves) const {
00066   unsigned PointerSize = TD->getPointerSize();
00067   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
00068           PointerSize : -PointerSize;
00069   bool IsLocal = false;
00070   unsigned BaseLabelID = 0;
00071 
00072   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
00073     const MachineMove &Move = Moves[i];
00074     unsigned LabelID = Move.getLabelID();
00075     
00076     if (LabelID) {
00077       LabelID = MMI->MappedLabel(LabelID);
00078     
00079       // Throw out move if the label is invalid.
00080       if (!LabelID) continue;
00081     }
00082     
00083     intptr_t LabelPtr = 0;
00084     if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
00085 
00086     const MachineLocation &Dst = Move.getDestination();
00087     const MachineLocation &Src = Move.getSource();
00088     
00089     // Advance row if new location.
00090     if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
00091       MCE->emitByte(dwarf::DW_CFA_advance_loc4);
00092       MCE->emitInt32(LabelPtr - BaseLabelPtr);
00093       
00094       BaseLabelID = LabelID; 
00095       BaseLabelPtr = LabelPtr;
00096       IsLocal = true;
00097     }
00098     
00099     // If advancing cfa.
00100     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
00101       if (!Src.isReg()) {
00102         if (Src.getReg() == MachineLocation::VirtualFP) {
00103           MCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
00104         } else {
00105           MCE->emitByte(dwarf::DW_CFA_def_cfa);
00106           MCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true));
00107         }
00108         
00109         int Offset = -Src.getOffset();
00110         
00111         MCE->emitULEB128Bytes(Offset);
00112       } else {
00113         assert(0 && "Machine move no supported yet.");
00114       }
00115     } else if (Src.isReg() &&
00116       Src.getReg() == MachineLocation::VirtualFP) {
00117       if (Dst.isReg()) {
00118         MCE->emitByte(dwarf::DW_CFA_def_cfa_register);
00119         MCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true));
00120       } else {
00121         assert(0 && "Machine move no supported yet.");
00122       }
00123     } else {
00124       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
00125       int Offset = Dst.getOffset() / stackGrowth;
00126       
00127       if (Offset < 0) {
00128         MCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
00129         MCE->emitULEB128Bytes(Reg);
00130         MCE->emitSLEB128Bytes(Offset);
00131       } else if (Reg < 64) {
00132         MCE->emitByte(dwarf::DW_CFA_offset + Reg);
00133         MCE->emitULEB128Bytes(Offset);
00134       } else {
00135         MCE->emitByte(dwarf::DW_CFA_offset_extended);
00136         MCE->emitULEB128Bytes(Reg);
00137         MCE->emitULEB128Bytes(Offset);
00138       }
00139     }
00140   }
00141 }
00142 
00143 /// SharedTypeIds - How many leading type ids two landing pads have in common.
00144 static unsigned SharedTypeIds(const LandingPadInfo *L,
00145                               const LandingPadInfo *R) {
00146   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
00147   unsigned LSize = LIds.size(), RSize = RIds.size();
00148   unsigned MinSize = LSize < RSize ? LSize : RSize;
00149   unsigned Count = 0;
00150 
00151   for (; Count != MinSize; ++Count)
00152     if (LIds[Count] != RIds[Count])
00153       return Count;
00154 
00155   return Count;
00156 }
00157 
00158 
00159 /// PadLT - Order landing pads lexicographically by type id.
00160 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
00161   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
00162   unsigned LSize = LIds.size(), RSize = RIds.size();
00163   unsigned MinSize = LSize < RSize ? LSize : RSize;
00164 
00165   for (unsigned i = 0; i != MinSize; ++i)
00166     if (LIds[i] != RIds[i])
00167       return LIds[i] < RIds[i];
00168 
00169   return LSize < RSize;
00170 }
00171 
00172 namespace {
00173 
00174 struct KeyInfo {
00175   static inline unsigned getEmptyKey() { return -1U; }
00176   static inline unsigned getTombstoneKey() { return -2U; }
00177   static unsigned getHashValue(const unsigned &Key) { return Key; }
00178   static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
00179   static bool isPod() { return true; }
00180 };
00181 
00182 /// ActionEntry - Structure describing an entry in the actions table.
00183 struct ActionEntry {
00184   int ValueForTypeID; // The value to write - may not be equal to the type id.
00185   int NextAction;
00186   struct ActionEntry *Previous;
00187 };
00188 
00189 /// PadRange - Structure holding a try-range and the associated landing pad.
00190 struct PadRange {
00191   // The index of the landing pad.
00192   unsigned PadIndex;
00193   // The index of the begin and end labels in the landing pad's label lists.
00194   unsigned RangeIndex;
00195 };
00196 
00197 typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
00198 
00199 /// CallSiteEntry - Structure describing an entry in the call-site table.
00200 struct CallSiteEntry {
00201   unsigned BeginLabel; // zero indicates the start of the function.
00202   unsigned EndLabel;   // zero indicates the end of the function.
00203   unsigned PadLabel;   // zero indicates that there is no landing pad.
00204   unsigned Action;
00205 };
00206 
00207 }
00208 
00209 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
00210                                          unsigned char* StartFunction,
00211                                          unsigned char* EndFunction) const {
00212   // Map all labels and get rid of any dead landing pads.
00213   MMI->TidyLandingPads();
00214 
00215   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
00216   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
00217   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
00218   if (PadInfos.empty()) return 0;
00219 
00220   // Sort the landing pads in order of their type ids.  This is used to fold
00221   // duplicate actions.
00222   SmallVector<const LandingPadInfo *, 64> LandingPads;
00223   LandingPads.reserve(PadInfos.size());
00224   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
00225     LandingPads.push_back(&PadInfos[i]);
00226   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
00227 
00228   // Negative type ids index into FilterIds, positive type ids index into
00229   // TypeInfos.  The value written for a positive type id is just the type
00230   // id itself.  For a negative type id, however, the value written is the
00231   // (negative) byte offset of the corresponding FilterIds entry.  The byte
00232   // offset is usually equal to the type id, because the FilterIds entries
00233   // are written using a variable width encoding which outputs one byte per
00234   // entry as long as the value written is not too large, but can differ.
00235   // This kind of complication does not occur for positive type ids because
00236   // type infos are output using a fixed width encoding.
00237   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
00238   SmallVector<int, 16> FilterOffsets;
00239   FilterOffsets.reserve(FilterIds.size());
00240   int Offset = -1;
00241   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
00242     E = FilterIds.end(); I != E; ++I) {
00243     FilterOffsets.push_back(Offset);
00244     Offset -= TargetAsmInfo::getULEB128Size(*I);
00245   }
00246 
00247   // Compute the actions table and gather the first action index for each
00248   // landing pad site.
00249   SmallVector<ActionEntry, 32> Actions;
00250   SmallVector<unsigned, 64> FirstActions;
00251   FirstActions.reserve(LandingPads.size());
00252 
00253   int FirstAction = 0;
00254   unsigned SizeActions = 0;
00255   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
00256     const LandingPadInfo *LP = LandingPads[i];
00257     const std::vector<int> &TypeIds = LP->TypeIds;
00258     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
00259     unsigned SizeSiteActions = 0;
00260 
00261     if (NumShared < TypeIds.size()) {
00262       unsigned SizeAction = 0;
00263       ActionEntry *PrevAction = 0;
00264 
00265       if (NumShared) {
00266         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
00267         assert(Actions.size());
00268         PrevAction = &Actions.back();
00269         SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
00270           TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
00271         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
00272           SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
00273           SizeAction += -PrevAction->NextAction;
00274           PrevAction = PrevAction->Previous;
00275         }
00276       }
00277 
00278       // Compute the actions.
00279       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
00280         int TypeID = TypeIds[I];
00281         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
00282         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
00283         unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
00284 
00285         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
00286         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
00287         SizeSiteActions += SizeAction;
00288 
00289         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
00290         Actions.push_back(Action);
00291 
00292         PrevAction = &Actions.back();
00293       }
00294 
00295       // Record the first action of the landing pad site.
00296       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
00297     } // else identical - re-use previous FirstAction
00298 
00299     FirstActions.push_back(FirstAction);
00300 
00301     // Compute this sites contribution to size.
00302     SizeActions += SizeSiteActions;
00303   }
00304 
00305   // Compute the call-site table.  Entries must be ordered by address.
00306   SmallVector<CallSiteEntry, 64> CallSites;
00307 
00308   RangeMapType PadMap;
00309   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
00310     const LandingPadInfo *LandingPad = LandingPads[i];
00311     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
00312       unsigned BeginLabel = LandingPad->BeginLabels[j];
00313       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
00314       PadRange P = { i, j };
00315       PadMap[BeginLabel] = P;
00316     }
00317   }
00318 
00319   bool MayThrow = false;
00320   unsigned LastLabel = 0;
00321   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
00322         I != E; ++I) {
00323     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
00324           MI != E; ++MI) {
00325       if (!MI->isLabel()) {
00326         MayThrow |= MI->getDesc().isCall();
00327         continue;
00328       }
00329 
00330       unsigned BeginLabel = MI->getOperand(0).getImm();
00331       assert(BeginLabel && "Invalid label!");
00332 
00333       if (BeginLabel == LastLabel)
00334         MayThrow = false;
00335 
00336       RangeMapType::iterator L = PadMap.find(BeginLabel);
00337 
00338       if (L == PadMap.end())
00339         continue;
00340 
00341       PadRange P = L->second;
00342       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
00343 
00344       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
00345               "Inconsistent landing pad map!");
00346 
00347       // If some instruction between the previous try-range and this one may
00348       // throw, create a call-site entry with no landing pad for the region
00349       // between the try-ranges.
00350       if (MayThrow) {
00351         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
00352         CallSites.push_back(Site);
00353       }
00354 
00355       LastLabel = LandingPad->EndLabels[P.RangeIndex];
00356       CallSiteEntry Site = {BeginLabel, LastLabel,
00357         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
00358 
00359       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
00360               "Invalid landing pad!");
00361 
00362       // Try to merge with the previous call-site.
00363       if (CallSites.size()) {
00364         CallSiteEntry &Prev = CallSites.back();
00365         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
00366           // Extend the range of the previous entry.
00367           Prev.EndLabel = Site.EndLabel;
00368           continue;
00369         }
00370       }
00371 
00372       // Otherwise, create a new call-site.
00373       CallSites.push_back(Site);
00374     }
00375   }
00376   // If some instruction between the previous try-range and the end of the
00377   // function may throw, create a call-site entry with no landing pad for the
00378   // region following the try-range.
00379   if (MayThrow) {
00380     CallSiteEntry Site = {LastLabel, 0, 0, 0};
00381     CallSites.push_back(Site);
00382   }
00383 
00384   // Final tallies.
00385   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
00386                                             sizeof(int32_t) + // Site length.
00387                                             sizeof(int32_t)); // Landing pad.
00388   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
00389     SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
00390 
00391   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
00392 
00393   unsigned TypeOffset = sizeof(int8_t) + // Call site format
00394                         // Call-site table length
00395                         TargetAsmInfo::getULEB128Size(SizeSites) + 
00396                         SizeSites + SizeActions + SizeTypes;
00397 
00398   unsigned TotalSize = sizeof(int8_t) + // LPStart format
00399                        sizeof(int8_t) + // TType format
00400                        TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
00401                        TypeOffset;
00402 
00403   unsigned SizeAlign = (4 - TotalSize) & 3;
00404 
00405   // Begin the exception table.
00406   MCE->emitAlignment(4);
00407   for (unsigned i = 0; i != SizeAlign; ++i) {
00408     MCE->emitByte(0);
00409     // Asm->EOL("Padding");
00410   }
00411   
00412   unsigned char* DwarfExceptionTable = (unsigned char*)MCE->getCurrentPCValue();
00413 
00414   // Emit the header.
00415   MCE->emitByte(dwarf::DW_EH_PE_omit);
00416   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
00417   MCE->emitByte(dwarf::DW_EH_PE_absptr);
00418   // Asm->EOL("TType format (DW_EH_PE_absptr)");
00419   MCE->emitULEB128Bytes(TypeOffset);
00420   // Asm->EOL("TType base offset");
00421   MCE->emitByte(dwarf::DW_EH_PE_udata4);
00422   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
00423   MCE->emitULEB128Bytes(SizeSites);
00424   // Asm->EOL("Call-site table length");
00425 
00426   // Emit the landing pad site information.
00427   for (unsigned i = 0; i < CallSites.size(); ++i) {
00428     CallSiteEntry &S = CallSites[i];
00429     intptr_t BeginLabelPtr = 0;
00430     intptr_t EndLabelPtr = 0;
00431 
00432     if (!S.BeginLabel) {
00433       BeginLabelPtr = (intptr_t)StartFunction;
00434       MCE->emitInt32(0);
00435     } else {
00436       BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel);
00437       MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
00438     }
00439 
00440     // Asm->EOL("Region start");
00441 
00442     if (!S.EndLabel) {
00443       EndLabelPtr = (intptr_t)EndFunction;
00444       MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
00445     } else {
00446       EndLabelPtr = MCE->getLabelAddress(S.EndLabel);
00447       MCE->emitInt32(EndLabelPtr - BeginLabelPtr);
00448     }
00449     //Asm->EOL("Region length");
00450 
00451     if (!S.PadLabel) {
00452       MCE->emitInt32(0);
00453     } else {
00454       unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel);
00455       MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
00456     }
00457     // Asm->EOL("Landing pad");
00458 
00459     MCE->emitULEB128Bytes(S.Action);
00460     // Asm->EOL("Action");
00461   }
00462 
00463   // Emit the actions.
00464   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
00465     ActionEntry &Action = Actions[I];
00466 
00467     MCE->emitSLEB128Bytes(Action.ValueForTypeID);
00468     //Asm->EOL("TypeInfo index");
00469     MCE->emitSLEB128Bytes(Action.NextAction);
00470     //Asm->EOL("Next action");
00471   }
00472 
00473   // Emit the type ids.
00474   for (unsigned M = TypeInfos.size(); M; --M) {
00475     GlobalVariable *GV = TypeInfos[M - 1];
00476     
00477     if (GV) {
00478       if (TD->getPointerSize() == sizeof(int32_t)) {
00479         MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
00480       } else {
00481         MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
00482       }
00483     } else {
00484       if (TD->getPointerSize() == sizeof(int32_t))
00485         MCE->emitInt32(0);
00486       else
00487         MCE->emitInt64(0);
00488     }
00489     // Asm->EOL("TypeInfo");
00490   }
00491 
00492   // Emit the filter typeids.
00493   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
00494     unsigned TypeID = FilterIds[j];
00495     MCE->emitULEB128Bytes(TypeID);
00496     //Asm->EOL("Filter TypeInfo index");
00497   }
00498   
00499   MCE->emitAlignment(4);
00500 
00501   return DwarfExceptionTable;
00502 }
00503 
00504 unsigned char*
00505 JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
00506   unsigned PointerSize = TD->getPointerSize();
00507   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
00508           PointerSize : -PointerSize;
00509   
00510   unsigned char* StartCommonPtr = (unsigned char*)MCE->getCurrentPCValue();
00511   // EH Common Frame header
00512   MCE->allocateSpace(4, 0);
00513   unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
00514   MCE->emitInt32((int)0);
00515   MCE->emitByte(dwarf::DW_CIE_VERSION);
00516   MCE->emitString(Personality ? "zPLR" : "zR");
00517   MCE->emitULEB128Bytes(1);
00518   MCE->emitSLEB128Bytes(stackGrowth);
00519   MCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
00520   
00521   if (Personality) {
00522     MCE->emitULEB128Bytes(7);
00523     
00524     // Direct encoding, because we use the function pointer. Not relative,
00525     // because the current PC value may be bigger than the personality
00526     // function pointer.
00527     MCE->emitByte(dwarf::DW_EH_PE_sdata4);
00528      
00529     MCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
00530     
00531     MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
00532     MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
00533       
00534   } else {
00535     MCE->emitULEB128Bytes(1);
00536     MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
00537   }
00538 
00539   std::vector<MachineMove> Moves;
00540   RI->getInitialFrameState(Moves);
00541   EmitFrameMoves(0, Moves);
00542   MCE->emitAlignment(PointerSize);
00543   
00544   MCE->emitInt32At((uintptr_t*)StartCommonPtr, 
00545               (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() - 
00546                           FrameCommonBeginPtr));
00547 
00548   return StartCommonPtr;
00549 }
00550 
00551 
00552 unsigned char*
00553 JITDwarfEmitter::EmitEHFrame(const Function* Personality,
00554                              unsigned char* StartCommonPtr,
00555                              unsigned char* StartFunction, 
00556                              unsigned char* EndFunction,
00557                              unsigned char* ExceptionTable) const {
00558   unsigned PointerSize = TD->getPointerSize();
00559   
00560   // EH frame header.
00561   unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue();
00562   MCE->allocateSpace(4, 0);
00563   unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
00564   // FDE CIE Offset
00565   MCE->emitInt32(FrameBeginPtr - StartCommonPtr);
00566   MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
00567   MCE->emitInt32(EndFunction - StartFunction);
00568 
00569   // If there is a personality and landing pads then point to the language
00570   // specific data area in the exception table.
00571   if (MMI->getPersonalityIndex()) {
00572     MCE->emitULEB128Bytes(4);
00573         
00574     if (!MMI->getLandingPads().empty()) {
00575       MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
00576     } else {
00577       MCE->emitInt32((int)0);
00578     }
00579   } else {
00580     MCE->emitULEB128Bytes(0);
00581   }
00582       
00583   // Indicate locations of function specific  callee saved registers in
00584   // frame.
00585   EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
00586       
00587   MCE->emitAlignment(PointerSize);
00588   
00589   // Indicate the size of the table
00590   MCE->emitInt32At((uintptr_t*)StartEHPtr, 
00591               (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() - 
00592                           StartEHPtr));
00593   
00594   // Double zeroes for the unwind runtime
00595   if (PointerSize == 8) {
00596     MCE->emitInt64(0);
00597     MCE->emitInt64(0);
00598   } else {
00599     MCE->emitInt32(0);
00600     MCE->emitInt32(0);
00601   }
00602 
00603   
00604   return StartEHPtr;
00605 }
00606 
00607 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
00608                                          MachineCodeEmitter& mce,
00609                                          unsigned char* StartFunction,
00610                                          unsigned char* EndFunction) {
00611   const TargetMachine& TM = F.getTarget();
00612   TD = TM.getTargetData();
00613   needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
00614   stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
00615   RI = TM.getRegisterInfo();
00616   MCE = &mce;
00617   unsigned FinalSize = 0;
00618   
00619   FinalSize += GetExceptionTableSizeInBytes(&F);
00620       
00621   const std::vector<Function *> Personalities = MMI->getPersonalities();
00622   FinalSize += 
00623     GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
00624 
00625   FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()],
00626                                      StartFunction);
00627   
00628   return FinalSize;
00629 }
00630 
00631 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns
00632 /// the new value.
00633 static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
00634   if (Alignment == 0) Alignment = 1;
00635   // Since we do not know where the buffer will be allocated, be pessimistic.
00636   return FinalSize + Alignment;
00637 }
00638   
00639 unsigned
00640 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
00641                                        unsigned char* StartFunction) const { 
00642   unsigned PointerSize = TD->getPointerSize();
00643   unsigned FinalSize = 0;
00644   // EH frame header.
00645   FinalSize += PointerSize;
00646   // FDE CIE Offset
00647   FinalSize += 3 * PointerSize;
00648   // If there is a personality and landing pads then point to the language
00649   // specific data area in the exception table.
00650   if (MMI->getPersonalityIndex()) {
00651     FinalSize += TargetAsmInfo::getULEB128Size(4); 
00652     FinalSize += PointerSize;
00653   } else {
00654     FinalSize += TargetAsmInfo::getULEB128Size(0);
00655   }
00656       
00657   // Indicate locations of function specific  callee saved registers in
00658   // frame.
00659   FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
00660                                         MMI->getFrameMoves());
00661       
00662   FinalSize = RoundUpToAlign(FinalSize, 4);
00663   
00664   // Double zeroes for the unwind runtime
00665   FinalSize += 2 * PointerSize;
00666 
00667   return FinalSize;
00668 }
00669 
00670 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality) 
00671   const {
00672 
00673   unsigned PointerSize = TD->getPointerSize();
00674   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
00675           PointerSize : -PointerSize;
00676   unsigned FinalSize = 0; 
00677   // EH Common Frame header
00678   FinalSize += PointerSize;
00679   FinalSize += 4;
00680   FinalSize += 1;
00681   FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
00682   FinalSize += TargetAsmInfo::getULEB128Size(1);
00683   FinalSize += TargetAsmInfo::getSLEB128Size(stackGrowth);
00684   FinalSize += 1;
00685   
00686   if (Personality) {
00687     FinalSize += TargetAsmInfo::getULEB128Size(7);
00688     
00689     // Encoding
00690     FinalSize+= 1;
00691     //Personality
00692     FinalSize += PointerSize;
00693     
00694     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
00695     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
00696       
00697   } else {
00698     FinalSize += TargetAsmInfo::getULEB128Size(1);
00699     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
00700   }
00701 
00702   std::vector<MachineMove> Moves;
00703   RI->getInitialFrameState(Moves);
00704   FinalSize += GetFrameMovesSizeInBytes(0, Moves);
00705   FinalSize = RoundUpToAlign(FinalSize, 4);
00706   return FinalSize;
00707 }
00708 
00709 unsigned
00710 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
00711                                   const std::vector<MachineMove> &Moves) const {
00712   unsigned PointerSize = TD->getPointerSize();
00713   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
00714           PointerSize : -PointerSize;
00715   bool IsLocal = BaseLabelPtr;
00716   unsigned FinalSize = 0; 
00717 
00718   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
00719     const MachineMove &Move = Moves[i];
00720     unsigned LabelID = Move.getLabelID();
00721     
00722     if (LabelID) {
00723       LabelID = MMI->MappedLabel(LabelID);
00724     
00725       // Throw out move if the label is invalid.
00726       if (!LabelID) continue;
00727     }
00728     
00729     intptr_t LabelPtr = 0;
00730     if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
00731 
00732     const MachineLocation &Dst = Move.getDestination();
00733     const MachineLocation &Src = Move.getSource();
00734     
00735     // Advance row if new location.
00736     if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
00737       FinalSize++;
00738       FinalSize += PointerSize;
00739       BaseLabelPtr = LabelPtr;
00740       IsLocal = true;
00741     }
00742     
00743     // If advancing cfa.
00744     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
00745       if (!Src.isReg()) {
00746         if (Src.getReg() == MachineLocation::VirtualFP) {
00747           ++FinalSize;
00748         } else {
00749           ++FinalSize;
00750           unsigned RegNum = RI->getDwarfRegNum(Src.getReg(), true);
00751           FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
00752         }
00753         
00754         int Offset = -Src.getOffset();
00755         
00756         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
00757       } else {
00758         assert(0 && "Machine move no supported yet.");
00759       }
00760     } else if (Src.isReg() &&
00761       Src.getReg() == MachineLocation::VirtualFP) {
00762       if (Dst.isReg()) {
00763         ++FinalSize;
00764         unsigned RegNum = RI->getDwarfRegNum(Dst.getReg(), true);
00765         FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
00766       } else {
00767         assert(0 && "Machine move no supported yet.");
00768       }
00769     } else {
00770       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
00771       int Offset = Dst.getOffset() / stackGrowth;
00772       
00773       if (Offset < 0) {
00774         ++FinalSize;
00775         FinalSize += TargetAsmInfo::getULEB128Size(Reg);
00776         FinalSize += TargetAsmInfo::getSLEB128Size(Offset);
00777       } else if (Reg < 64) {
00778         ++FinalSize;
00779         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
00780       } else {
00781         ++FinalSize;
00782         FinalSize += TargetAsmInfo::getULEB128Size(Reg);
00783         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
00784       }
00785     }
00786   }
00787   return FinalSize;
00788 }
00789 
00790 unsigned 
00791 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
00792   unsigned FinalSize = 0;
00793 
00794   // Map all labels and get rid of any dead landing pads.
00795   MMI->TidyLandingPads();
00796 
00797   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
00798   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
00799   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
00800   if (PadInfos.empty()) return 0;
00801 
00802   // Sort the landing pads in order of their type ids.  This is used to fold
00803   // duplicate actions.
00804   SmallVector<const LandingPadInfo *, 64> LandingPads;
00805   LandingPads.reserve(PadInfos.size());
00806   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
00807     LandingPads.push_back(&PadInfos[i]);
00808   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
00809 
00810   // Negative type ids index into FilterIds, positive type ids index into
00811   // TypeInfos.  The value written for a positive type id is just the type
00812   // id itself.  For a negative type id, however, the value written is the
00813   // (negative) byte offset of the corresponding FilterIds entry.  The byte
00814   // offset is usually equal to the type id, because the FilterIds entries
00815   // are written using a variable width encoding which outputs one byte per
00816   // entry as long as the value written is not too large, but can differ.
00817   // This kind of complication does not occur for positive type ids because
00818   // type infos are output using a fixed width encoding.
00819   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
00820   SmallVector<int, 16> FilterOffsets;
00821   FilterOffsets.reserve(FilterIds.size());
00822   int Offset = -1;
00823   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
00824     E = FilterIds.end(); I != E; ++I) {
00825     FilterOffsets.push_back(Offset);
00826     Offset -= TargetAsmInfo::getULEB128Size(*I);
00827   }
00828 
00829   // Compute the actions table and gather the first action index for each
00830   // landing pad site.
00831   SmallVector<ActionEntry, 32> Actions;
00832   SmallVector<unsigned, 64> FirstActions;
00833   FirstActions.reserve(LandingPads.size());
00834 
00835   int FirstAction = 0;
00836   unsigned SizeActions = 0;
00837   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
00838     const LandingPadInfo *LP = LandingPads[i];
00839     const std::vector<int> &TypeIds = LP->TypeIds;
00840     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
00841     unsigned SizeSiteActions = 0;
00842 
00843     if (NumShared < TypeIds.size()) {
00844       unsigned SizeAction = 0;
00845       ActionEntry *PrevAction = 0;
00846 
00847       if (NumShared) {
00848         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
00849         assert(Actions.size());
00850         PrevAction = &Actions.back();
00851         SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
00852           TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
00853         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
00854           SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
00855           SizeAction += -PrevAction->NextAction;
00856           PrevAction = PrevAction->Previous;
00857         }
00858       }
00859 
00860       // Compute the actions.
00861       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
00862         int TypeID = TypeIds[I];
00863         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
00864         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
00865         unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
00866 
00867         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
00868         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
00869         SizeSiteActions += SizeAction;
00870 
00871         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
00872         Actions.push_back(Action);
00873 
00874         PrevAction = &Actions.back();
00875       }
00876 
00877       // Record the first action of the landing pad site.
00878       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
00879     } // else identical - re-use previous FirstAction
00880 
00881     FirstActions.push_back(FirstAction);
00882 
00883     // Compute this sites contribution to size.
00884     SizeActions += SizeSiteActions;
00885   }
00886 
00887   // Compute the call-site table.  Entries must be ordered by address.
00888   SmallVector<CallSiteEntry, 64> CallSites;
00889 
00890   RangeMapType PadMap;
00891   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
00892     const LandingPadInfo *LandingPad = LandingPads[i];
00893     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
00894       unsigned BeginLabel = LandingPad->BeginLabels[j];
00895       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
00896       PadRange P = { i, j };
00897       PadMap[BeginLabel] = P;
00898     }
00899   }
00900 
00901   bool MayThrow = false;
00902   unsigned LastLabel = 0;
00903   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
00904         I != E; ++I) {
00905     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
00906           MI != E; ++MI) {
00907       if (!MI->isLabel()) {
00908         MayThrow |= MI->getDesc().isCall();
00909         continue;
00910       }
00911 
00912       unsigned BeginLabel = MI->getOperand(0).getImm();
00913       assert(BeginLabel && "Invalid label!");
00914 
00915       if (BeginLabel == LastLabel)
00916         MayThrow = false;
00917 
00918       RangeMapType::iterator L = PadMap.find(BeginLabel);
00919 
00920       if (L == PadMap.end())
00921         continue;
00922 
00923       PadRange P = L->second;
00924       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
00925 
00926       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
00927               "Inconsistent landing pad map!");
00928 
00929       // If some instruction between the previous try-range and this one may
00930       // throw, create a call-site entry with no landing pad for the region
00931       // between the try-ranges.
00932       if (MayThrow) {
00933         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
00934         CallSites.push_back(Site);
00935       }
00936 
00937       LastLabel = LandingPad->EndLabels[P.RangeIndex];
00938       CallSiteEntry Site = {BeginLabel, LastLabel,
00939         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
00940 
00941       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
00942               "Invalid landing pad!");
00943 
00944       // Try to merge with the previous call-site.
00945       if (CallSites.size()) {
00946         CallSiteEntry &Prev = CallSites.back();
00947         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
00948           // Extend the range of the previous entry.
00949           Prev.EndLabel = Site.EndLabel;
00950           continue;
00951         }
00952       }
00953 
00954       // Otherwise, create a new call-site.
00955       CallSites.push_back(Site);
00956     }
00957   }
00958   // If some instruction between the previous try-range and the end of the
00959   // function may throw, create a call-site entry with no landing pad for the
00960   // region following the try-range.
00961   if (MayThrow) {
00962     CallSiteEntry Site = {LastLabel, 0, 0, 0};
00963     CallSites.push_back(Site);
00964   }
00965 
00966   // Final tallies.
00967   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
00968                                             sizeof(int32_t) + // Site length.
00969                                             sizeof(int32_t)); // Landing pad.
00970   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
00971     SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
00972 
00973   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
00974 
00975   unsigned TypeOffset = sizeof(int8_t) + // Call site format
00976                         // Call-site table length
00977                         TargetAsmInfo::getULEB128Size(SizeSites) + 
00978                         SizeSites + SizeActions + SizeTypes;
00979 
00980   unsigned TotalSize = sizeof(int8_t) + // LPStart format
00981                        sizeof(int8_t) + // TType format
00982                        TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
00983                        TypeOffset;
00984 
00985   unsigned SizeAlign = (4 - TotalSize) & 3;
00986 
00987   // Begin the exception table.
00988   FinalSize = RoundUpToAlign(FinalSize, 4);
00989   for (unsigned i = 0; i != SizeAlign; ++i) {
00990     ++FinalSize;
00991   }
00992   
00993   unsigned PointerSize = TD->getPointerSize();
00994 
00995   // Emit the header.
00996   ++FinalSize;
00997   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
00998   ++FinalSize;
00999   // Asm->EOL("TType format (DW_EH_PE_absptr)");
01000   ++FinalSize;
01001   // Asm->EOL("TType base offset");
01002   ++FinalSize;
01003   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
01004   ++FinalSize;
01005   // Asm->EOL("Call-site table length");
01006 
01007   // Emit the landing pad site information.
01008   for (unsigned i = 0; i < CallSites.size(); ++i) {
01009     CallSiteEntry &S = CallSites[i];
01010 
01011     // Asm->EOL("Region start");
01012     FinalSize += PointerSize;
01013     
01014     //Asm->EOL("Region length");
01015     FinalSize += PointerSize;
01016 
01017     // Asm->EOL("Landing pad");
01018     FinalSize += PointerSize;
01019 
01020     FinalSize += TargetAsmInfo::getULEB128Size(S.Action);
01021     // Asm->EOL("Action");
01022   }
01023 
01024   // Emit the actions.
01025   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
01026     ActionEntry &Action = Actions[I];
01027 
01028     //Asm->EOL("TypeInfo index");
01029     FinalSize += TargetAsmInfo::getSLEB128Size(Action.ValueForTypeID);
01030     //Asm->EOL("Next action");
01031     FinalSize += TargetAsmInfo::getSLEB128Size(Action.NextAction);
01032   }
01033 
01034   // Emit the type ids.
01035   for (unsigned M = TypeInfos.size(); M; --M) {
01036     // Asm->EOL("TypeInfo");
01037     FinalSize += PointerSize;
01038   }
01039 
01040   // Emit the filter typeids.
01041   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
01042     unsigned TypeID = FilterIds[j];
01043     FinalSize += TargetAsmInfo::getULEB128Size(TypeID);
01044     //Asm->EOL("Filter TypeInfo index");
01045   }
01046   
01047   FinalSize = RoundUpToAlign(FinalSize, 4);
01048 
01049   return FinalSize;
01050 }