Add a JITEventListener interface that gets called back when a new function is
[oota-llvm.git] / lib / ExecutionEngine / JIT / JITDwarfEmitter.cpp
1 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a JITDwarfEmitter object that is used by the JIT to
11 // write dwarf tables to memory.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "JIT.h"
16 #include "JITDwarfEmitter.h"
17 #include "llvm/Function.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/CodeGen/JITCodeEmitter.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineLocation.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/ExecutionEngine/JITMemoryManager.h"
24 #include "llvm/Target/TargetAsmInfo.h"
25 #include "llvm/Target/TargetData.h"
26 #include "llvm/Target/TargetInstrInfo.h"
27 #include "llvm/Target/TargetFrameInfo.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/Target/TargetRegisterInfo.h"
30
31 using namespace llvm;
32
33 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
34
35
36 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, 
37                                                JITCodeEmitter& jce,
38                                                unsigned char* StartFunction,
39                                                unsigned char* EndFunction) {
40   const TargetMachine& TM = F.getTarget();
41   TD = TM.getTargetData();
42   needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
43   stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
44   RI = TM.getRegisterInfo();
45   JCE = &jce;
46   
47   unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
48                                                      EndFunction);
49       
50   unsigned char* Result = 0;
51   unsigned char* EHFramePtr = 0;
52
53   const std::vector<Function *> Personalities = MMI->getPersonalities();
54   EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
55
56   Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
57                        StartFunction, EndFunction, ExceptionTable);
58   
59   return Result;
60 }
61
62
63 void 
64 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
65                                 const std::vector<MachineMove> &Moves) const {
66   unsigned PointerSize = TD->getPointerSize();
67   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
68           PointerSize : -PointerSize;
69   bool IsLocal = false;
70   unsigned BaseLabelID = 0;
71
72   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
73     const MachineMove &Move = Moves[i];
74     unsigned LabelID = Move.getLabelID();
75     
76     if (LabelID) {
77       LabelID = MMI->MappedLabel(LabelID);
78     
79       // Throw out move if the label is invalid.
80       if (!LabelID) continue;
81     }
82     
83     intptr_t LabelPtr = 0;
84     if (LabelID) LabelPtr = JCE->getLabelAddress(LabelID);
85
86     const MachineLocation &Dst = Move.getDestination();
87     const MachineLocation &Src = Move.getSource();
88     
89     // Advance row if new location.
90     if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
91       JCE->emitByte(dwarf::DW_CFA_advance_loc4);
92       JCE->emitInt32(LabelPtr - BaseLabelPtr);
93       
94       BaseLabelID = LabelID; 
95       BaseLabelPtr = LabelPtr;
96       IsLocal = true;
97     }
98     
99     // If advancing cfa.
100     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
101       if (!Src.isReg()) {
102         if (Src.getReg() == MachineLocation::VirtualFP) {
103           JCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
104         } else {
105           JCE->emitByte(dwarf::DW_CFA_def_cfa);
106           JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true));
107         }
108         
109         int Offset = -Src.getOffset();
110         
111         JCE->emitULEB128Bytes(Offset);
112       } else {
113         assert(0 && "Machine move no supported yet.");
114       }
115     } else if (Src.isReg() &&
116       Src.getReg() == MachineLocation::VirtualFP) {
117       if (Dst.isReg()) {
118         JCE->emitByte(dwarf::DW_CFA_def_cfa_register);
119         JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true));
120       } else {
121         assert(0 && "Machine move no supported yet.");
122       }
123     } else {
124       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
125       int Offset = Dst.getOffset() / stackGrowth;
126       
127       if (Offset < 0) {
128         JCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
129         JCE->emitULEB128Bytes(Reg);
130         JCE->emitSLEB128Bytes(Offset);
131       } else if (Reg < 64) {
132         JCE->emitByte(dwarf::DW_CFA_offset + Reg);
133         JCE->emitULEB128Bytes(Offset);
134       } else {
135         JCE->emitByte(dwarf::DW_CFA_offset_extended);
136         JCE->emitULEB128Bytes(Reg);
137         JCE->emitULEB128Bytes(Offset);
138       }
139     }
140   }
141 }
142
143 /// SharedTypeIds - How many leading type ids two landing pads have in common.
144 static unsigned SharedTypeIds(const LandingPadInfo *L,
145                               const LandingPadInfo *R) {
146   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
147   unsigned LSize = LIds.size(), RSize = RIds.size();
148   unsigned MinSize = LSize < RSize ? LSize : RSize;
149   unsigned Count = 0;
150
151   for (; Count != MinSize; ++Count)
152     if (LIds[Count] != RIds[Count])
153       return Count;
154
155   return Count;
156 }
157
158
159 /// PadLT - Order landing pads lexicographically by type id.
160 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
161   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
162   unsigned LSize = LIds.size(), RSize = RIds.size();
163   unsigned MinSize = LSize < RSize ? LSize : RSize;
164
165   for (unsigned i = 0; i != MinSize; ++i)
166     if (LIds[i] != RIds[i])
167       return LIds[i] < RIds[i];
168
169   return LSize < RSize;
170 }
171
172 namespace {
173
174 struct KeyInfo {
175   static inline unsigned getEmptyKey() { return -1U; }
176   static inline unsigned getTombstoneKey() { return -2U; }
177   static unsigned getHashValue(const unsigned &Key) { return Key; }
178   static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
179   static bool isPod() { return true; }
180 };
181
182 /// ActionEntry - Structure describing an entry in the actions table.
183 struct ActionEntry {
184   int ValueForTypeID; // The value to write - may not be equal to the type id.
185   int NextAction;
186   struct ActionEntry *Previous;
187 };
188
189 /// PadRange - Structure holding a try-range and the associated landing pad.
190 struct PadRange {
191   // The index of the landing pad.
192   unsigned PadIndex;
193   // The index of the begin and end labels in the landing pad's label lists.
194   unsigned RangeIndex;
195 };
196
197 typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
198
199 /// CallSiteEntry - Structure describing an entry in the call-site table.
200 struct CallSiteEntry {
201   unsigned BeginLabel; // zero indicates the start of the function.
202   unsigned EndLabel;   // zero indicates the end of the function.
203   unsigned PadLabel;   // zero indicates that there is no landing pad.
204   unsigned Action;
205 };
206
207 }
208
209 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
210                                          unsigned char* StartFunction,
211                                          unsigned char* EndFunction) const {
212   // Map all labels and get rid of any dead landing pads.
213   MMI->TidyLandingPads();
214
215   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
216   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
217   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
218   if (PadInfos.empty()) return 0;
219
220   // Sort the landing pads in order of their type ids.  This is used to fold
221   // duplicate actions.
222   SmallVector<const LandingPadInfo *, 64> LandingPads;
223   LandingPads.reserve(PadInfos.size());
224   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
225     LandingPads.push_back(&PadInfos[i]);
226   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
227
228   // Negative type ids index into FilterIds, positive type ids index into
229   // TypeInfos.  The value written for a positive type id is just the type
230   // id itself.  For a negative type id, however, the value written is the
231   // (negative) byte offset of the corresponding FilterIds entry.  The byte
232   // offset is usually equal to the type id, because the FilterIds entries
233   // are written using a variable width encoding which outputs one byte per
234   // entry as long as the value written is not too large, but can differ.
235   // This kind of complication does not occur for positive type ids because
236   // type infos are output using a fixed width encoding.
237   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
238   SmallVector<int, 16> FilterOffsets;
239   FilterOffsets.reserve(FilterIds.size());
240   int Offset = -1;
241   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
242     E = FilterIds.end(); I != E; ++I) {
243     FilterOffsets.push_back(Offset);
244     Offset -= TargetAsmInfo::getULEB128Size(*I);
245   }
246
247   // Compute the actions table and gather the first action index for each
248   // landing pad site.
249   SmallVector<ActionEntry, 32> Actions;
250   SmallVector<unsigned, 64> FirstActions;
251   FirstActions.reserve(LandingPads.size());
252
253   int FirstAction = 0;
254   unsigned SizeActions = 0;
255   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
256     const LandingPadInfo *LP = LandingPads[i];
257     const std::vector<int> &TypeIds = LP->TypeIds;
258     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
259     unsigned SizeSiteActions = 0;
260
261     if (NumShared < TypeIds.size()) {
262       unsigned SizeAction = 0;
263       ActionEntry *PrevAction = 0;
264
265       if (NumShared) {
266         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
267         assert(Actions.size());
268         PrevAction = &Actions.back();
269         SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
270           TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
271         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
272           SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
273           SizeAction += -PrevAction->NextAction;
274           PrevAction = PrevAction->Previous;
275         }
276       }
277
278       // Compute the actions.
279       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
280         int TypeID = TypeIds[I];
281         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
282         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
283         unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
284
285         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
286         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
287         SizeSiteActions += SizeAction;
288
289         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
290         Actions.push_back(Action);
291
292         PrevAction = &Actions.back();
293       }
294
295       // Record the first action of the landing pad site.
296       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
297     } // else identical - re-use previous FirstAction
298
299     FirstActions.push_back(FirstAction);
300
301     // Compute this sites contribution to size.
302     SizeActions += SizeSiteActions;
303   }
304
305   // Compute the call-site table.  Entries must be ordered by address.
306   SmallVector<CallSiteEntry, 64> CallSites;
307
308   RangeMapType PadMap;
309   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
310     const LandingPadInfo *LandingPad = LandingPads[i];
311     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
312       unsigned BeginLabel = LandingPad->BeginLabels[j];
313       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
314       PadRange P = { i, j };
315       PadMap[BeginLabel] = P;
316     }
317   }
318
319   bool MayThrow = false;
320   unsigned LastLabel = 0;
321   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
322         I != E; ++I) {
323     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
324           MI != E; ++MI) {
325       if (!MI->isLabel()) {
326         MayThrow |= MI->getDesc().isCall();
327         continue;
328       }
329
330       unsigned BeginLabel = MI->getOperand(0).getImm();
331       assert(BeginLabel && "Invalid label!");
332
333       if (BeginLabel == LastLabel)
334         MayThrow = false;
335
336       RangeMapType::iterator L = PadMap.find(BeginLabel);
337
338       if (L == PadMap.end())
339         continue;
340
341       PadRange P = L->second;
342       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
343
344       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
345               "Inconsistent landing pad map!");
346
347       // If some instruction between the previous try-range and this one may
348       // throw, create a call-site entry with no landing pad for the region
349       // between the try-ranges.
350       if (MayThrow) {
351         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
352         CallSites.push_back(Site);
353       }
354
355       LastLabel = LandingPad->EndLabels[P.RangeIndex];
356       CallSiteEntry Site = {BeginLabel, LastLabel,
357         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
358
359       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
360               "Invalid landing pad!");
361
362       // Try to merge with the previous call-site.
363       if (CallSites.size()) {
364         CallSiteEntry &Prev = CallSites.back();
365         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
366           // Extend the range of the previous entry.
367           Prev.EndLabel = Site.EndLabel;
368           continue;
369         }
370       }
371
372       // Otherwise, create a new call-site.
373       CallSites.push_back(Site);
374     }
375   }
376   // If some instruction between the previous try-range and the end of the
377   // function may throw, create a call-site entry with no landing pad for the
378   // region following the try-range.
379   if (MayThrow) {
380     CallSiteEntry Site = {LastLabel, 0, 0, 0};
381     CallSites.push_back(Site);
382   }
383
384   // Final tallies.
385   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
386                                             sizeof(int32_t) + // Site length.
387                                             sizeof(int32_t)); // Landing pad.
388   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
389     SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
390
391   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
392
393   unsigned TypeOffset = sizeof(int8_t) + // Call site format
394                         // Call-site table length
395                         TargetAsmInfo::getULEB128Size(SizeSites) + 
396                         SizeSites + SizeActions + SizeTypes;
397
398   unsigned TotalSize = sizeof(int8_t) + // LPStart format
399                        sizeof(int8_t) + // TType format
400                        TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
401                        TypeOffset;
402
403   unsigned SizeAlign = (4 - TotalSize) & 3;
404
405   // Begin the exception table.
406   JCE->emitAlignment(4);
407   for (unsigned i = 0; i != SizeAlign; ++i) {
408     JCE->emitByte(0);
409     // Asm->EOL("Padding");
410   }
411   
412   unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
413
414   // Emit the header.
415   JCE->emitByte(dwarf::DW_EH_PE_omit);
416   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
417   JCE->emitByte(dwarf::DW_EH_PE_absptr);
418   // Asm->EOL("TType format (DW_EH_PE_absptr)");
419   JCE->emitULEB128Bytes(TypeOffset);
420   // Asm->EOL("TType base offset");
421   JCE->emitByte(dwarf::DW_EH_PE_udata4);
422   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
423   JCE->emitULEB128Bytes(SizeSites);
424   // Asm->EOL("Call-site table length");
425
426   // Emit the landing pad site information.
427   for (unsigned i = 0; i < CallSites.size(); ++i) {
428     CallSiteEntry &S = CallSites[i];
429     intptr_t BeginLabelPtr = 0;
430     intptr_t EndLabelPtr = 0;
431
432     if (!S.BeginLabel) {
433       BeginLabelPtr = (intptr_t)StartFunction;
434       JCE->emitInt32(0);
435     } else {
436       BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel);
437       JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
438     }
439
440     // Asm->EOL("Region start");
441
442     if (!S.EndLabel) {
443       EndLabelPtr = (intptr_t)EndFunction;
444       JCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
445     } else {
446       EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
447       JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
448     }
449     //Asm->EOL("Region length");
450
451     if (!S.PadLabel) {
452       JCE->emitInt32(0);
453     } else {
454       unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
455       JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
456     }
457     // Asm->EOL("Landing pad");
458
459     JCE->emitULEB128Bytes(S.Action);
460     // Asm->EOL("Action");
461   }
462
463   // Emit the actions.
464   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
465     ActionEntry &Action = Actions[I];
466
467     JCE->emitSLEB128Bytes(Action.ValueForTypeID);
468     //Asm->EOL("TypeInfo index");
469     JCE->emitSLEB128Bytes(Action.NextAction);
470     //Asm->EOL("Next action");
471   }
472
473   // Emit the type ids.
474   for (unsigned M = TypeInfos.size(); M; --M) {
475     GlobalVariable *GV = TypeInfos[M - 1];
476     
477     if (GV) {
478       if (TD->getPointerSize() == sizeof(int32_t)) {
479         JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
480       } else {
481         JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
482       }
483     } else {
484       if (TD->getPointerSize() == sizeof(int32_t))
485         JCE->emitInt32(0);
486       else
487         JCE->emitInt64(0);
488     }
489     // Asm->EOL("TypeInfo");
490   }
491
492   // Emit the filter typeids.
493   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
494     unsigned TypeID = FilterIds[j];
495     JCE->emitULEB128Bytes(TypeID);
496     //Asm->EOL("Filter TypeInfo index");
497   }
498   
499   JCE->emitAlignment(4);
500
501   return DwarfExceptionTable;
502 }
503
504 unsigned char*
505 JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
506   unsigned PointerSize = TD->getPointerSize();
507   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
508           PointerSize : -PointerSize;
509   
510   unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue();
511   // EH Common Frame header
512   JCE->allocateSpace(4, 0);
513   unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
514   JCE->emitInt32((int)0);
515   JCE->emitByte(dwarf::DW_CIE_VERSION);
516   JCE->emitString(Personality ? "zPLR" : "zR");
517   JCE->emitULEB128Bytes(1);
518   JCE->emitSLEB128Bytes(stackGrowth);
519   JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
520   
521   if (Personality) {
522     // Augmentation Size: 3 small ULEBs of one byte each, and the personality
523     // function which size is PointerSize.
524     JCE->emitULEB128Bytes(3 + PointerSize); 
525     
526     // We set the encoding of the personality as direct encoding because we use
527     // the function pointer. The encoding is not relative because the current
528     // PC value may be bigger than the personality function pointer.
529     if (PointerSize == 4) {
530       JCE->emitByte(dwarf::DW_EH_PE_sdata4); 
531       JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
532     } else {
533       JCE->emitByte(dwarf::DW_EH_PE_sdata8);
534       JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
535     }
536     
537     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
538     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
539       
540   } else {
541     JCE->emitULEB128Bytes(1);
542     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
543   }
544
545   std::vector<MachineMove> Moves;
546   RI->getInitialFrameState(Moves);
547   EmitFrameMoves(0, Moves);
548   JCE->emitAlignment(PointerSize);
549   
550   JCE->emitInt32At((uintptr_t*)StartCommonPtr, 
551               (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() - 
552                           FrameCommonBeginPtr));
553
554   return StartCommonPtr;
555 }
556
557
558 unsigned char*
559 JITDwarfEmitter::EmitEHFrame(const Function* Personality,
560                              unsigned char* StartCommonPtr,
561                              unsigned char* StartFunction, 
562                              unsigned char* EndFunction,
563                              unsigned char* ExceptionTable) const {
564   unsigned PointerSize = TD->getPointerSize();
565   
566   // EH frame header.
567   unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue();
568   JCE->allocateSpace(4, 0);
569   unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
570   // FDE CIE Offset
571   JCE->emitInt32(FrameBeginPtr - StartCommonPtr);
572   JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue());
573   JCE->emitInt32(EndFunction - StartFunction);
574
575   // If there is a personality and landing pads then point to the language
576   // specific data area in the exception table.
577   if (MMI->getPersonalityIndex()) {
578     JCE->emitULEB128Bytes(4);
579         
580     if (!MMI->getLandingPads().empty()) {
581       JCE->emitInt32(ExceptionTable - (unsigned char*)JCE->getCurrentPCValue());
582     } else {
583       JCE->emitInt32((int)0);
584     }
585   } else {
586     JCE->emitULEB128Bytes(0);
587   }
588       
589   // Indicate locations of function specific  callee saved registers in
590   // frame.
591   EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
592       
593   JCE->emitAlignment(PointerSize);
594   
595   // Indicate the size of the table
596   JCE->emitInt32At((uintptr_t*)StartEHPtr, 
597               (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() - 
598                           StartEHPtr));
599   
600   // Double zeroes for the unwind runtime
601   if (PointerSize == 8) {
602     JCE->emitInt64(0);
603     JCE->emitInt64(0);
604   } else {
605     JCE->emitInt32(0);
606     JCE->emitInt32(0);
607   }
608
609   
610   return StartEHPtr;
611 }
612
613 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
614                                          JITCodeEmitter& jce,
615                                          unsigned char* StartFunction,
616                                          unsigned char* EndFunction) {
617   const TargetMachine& TM = F.getTarget();
618   TD = TM.getTargetData();
619   needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
620   stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
621   RI = TM.getRegisterInfo();
622   JCE = &jce;
623   unsigned FinalSize = 0;
624   
625   FinalSize += GetExceptionTableSizeInBytes(&F);
626       
627   const std::vector<Function *> Personalities = MMI->getPersonalities();
628   FinalSize += 
629     GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
630
631   FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()],
632                                      StartFunction);
633   
634   return FinalSize;
635 }
636
637 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns
638 /// the new value.
639 static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
640   if (Alignment == 0) Alignment = 1;
641   // Since we do not know where the buffer will be allocated, be pessimistic.
642   return FinalSize + Alignment;
643 }
644   
645 unsigned
646 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
647                                        unsigned char* StartFunction) const { 
648   unsigned PointerSize = TD->getPointerSize();
649   unsigned FinalSize = 0;
650   // EH frame header.
651   FinalSize += PointerSize;
652   // FDE CIE Offset
653   FinalSize += 3 * PointerSize;
654   // If there is a personality and landing pads then point to the language
655   // specific data area in the exception table.
656   if (MMI->getPersonalityIndex()) {
657     FinalSize += TargetAsmInfo::getULEB128Size(4); 
658     FinalSize += PointerSize;
659   } else {
660     FinalSize += TargetAsmInfo::getULEB128Size(0);
661   }
662       
663   // Indicate locations of function specific  callee saved registers in
664   // frame.
665   FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
666                                         MMI->getFrameMoves());
667       
668   FinalSize = RoundUpToAlign(FinalSize, 4);
669   
670   // Double zeroes for the unwind runtime
671   FinalSize += 2 * PointerSize;
672
673   return FinalSize;
674 }
675
676 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality) 
677   const {
678
679   unsigned PointerSize = TD->getPointerSize();
680   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
681           PointerSize : -PointerSize;
682   unsigned FinalSize = 0; 
683   // EH Common Frame header
684   FinalSize += PointerSize;
685   FinalSize += 4;
686   FinalSize += 1;
687   FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
688   FinalSize += TargetAsmInfo::getULEB128Size(1);
689   FinalSize += TargetAsmInfo::getSLEB128Size(stackGrowth);
690   FinalSize += 1;
691   
692   if (Personality) {
693     FinalSize += TargetAsmInfo::getULEB128Size(7);
694     
695     // Encoding
696     FinalSize+= 1;
697     //Personality
698     FinalSize += PointerSize;
699     
700     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
701     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
702       
703   } else {
704     FinalSize += TargetAsmInfo::getULEB128Size(1);
705     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
706   }
707
708   std::vector<MachineMove> Moves;
709   RI->getInitialFrameState(Moves);
710   FinalSize += GetFrameMovesSizeInBytes(0, Moves);
711   FinalSize = RoundUpToAlign(FinalSize, 4);
712   return FinalSize;
713 }
714
715 unsigned
716 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
717                                   const std::vector<MachineMove> &Moves) const {
718   unsigned PointerSize = TD->getPointerSize();
719   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
720           PointerSize : -PointerSize;
721   bool IsLocal = BaseLabelPtr;
722   unsigned FinalSize = 0; 
723
724   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
725     const MachineMove &Move = Moves[i];
726     unsigned LabelID = Move.getLabelID();
727     
728     if (LabelID) {
729       LabelID = MMI->MappedLabel(LabelID);
730     
731       // Throw out move if the label is invalid.
732       if (!LabelID) continue;
733     }
734     
735     intptr_t LabelPtr = 0;
736     if (LabelID) LabelPtr = JCE->getLabelAddress(LabelID);
737
738     const MachineLocation &Dst = Move.getDestination();
739     const MachineLocation &Src = Move.getSource();
740     
741     // Advance row if new location.
742     if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
743       FinalSize++;
744       FinalSize += PointerSize;
745       BaseLabelPtr = LabelPtr;
746       IsLocal = true;
747     }
748     
749     // If advancing cfa.
750     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
751       if (!Src.isReg()) {
752         if (Src.getReg() == MachineLocation::VirtualFP) {
753           ++FinalSize;
754         } else {
755           ++FinalSize;
756           unsigned RegNum = RI->getDwarfRegNum(Src.getReg(), true);
757           FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
758         }
759         
760         int Offset = -Src.getOffset();
761         
762         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
763       } else {
764         assert(0 && "Machine move no supported yet.");
765       }
766     } else if (Src.isReg() &&
767       Src.getReg() == MachineLocation::VirtualFP) {
768       if (Dst.isReg()) {
769         ++FinalSize;
770         unsigned RegNum = RI->getDwarfRegNum(Dst.getReg(), true);
771         FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
772       } else {
773         assert(0 && "Machine move no supported yet.");
774       }
775     } else {
776       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
777       int Offset = Dst.getOffset() / stackGrowth;
778       
779       if (Offset < 0) {
780         ++FinalSize;
781         FinalSize += TargetAsmInfo::getULEB128Size(Reg);
782         FinalSize += TargetAsmInfo::getSLEB128Size(Offset);
783       } else if (Reg < 64) {
784         ++FinalSize;
785         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
786       } else {
787         ++FinalSize;
788         FinalSize += TargetAsmInfo::getULEB128Size(Reg);
789         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
790       }
791     }
792   }
793   return FinalSize;
794 }
795
796 unsigned 
797 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
798   unsigned FinalSize = 0;
799
800   // Map all labels and get rid of any dead landing pads.
801   MMI->TidyLandingPads();
802
803   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
804   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
805   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
806   if (PadInfos.empty()) return 0;
807
808   // Sort the landing pads in order of their type ids.  This is used to fold
809   // duplicate actions.
810   SmallVector<const LandingPadInfo *, 64> LandingPads;
811   LandingPads.reserve(PadInfos.size());
812   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
813     LandingPads.push_back(&PadInfos[i]);
814   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
815
816   // Negative type ids index into FilterIds, positive type ids index into
817   // TypeInfos.  The value written for a positive type id is just the type
818   // id itself.  For a negative type id, however, the value written is the
819   // (negative) byte offset of the corresponding FilterIds entry.  The byte
820   // offset is usually equal to the type id, because the FilterIds entries
821   // are written using a variable width encoding which outputs one byte per
822   // entry as long as the value written is not too large, but can differ.
823   // This kind of complication does not occur for positive type ids because
824   // type infos are output using a fixed width encoding.
825   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
826   SmallVector<int, 16> FilterOffsets;
827   FilterOffsets.reserve(FilterIds.size());
828   int Offset = -1;
829   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
830     E = FilterIds.end(); I != E; ++I) {
831     FilterOffsets.push_back(Offset);
832     Offset -= TargetAsmInfo::getULEB128Size(*I);
833   }
834
835   // Compute the actions table and gather the first action index for each
836   // landing pad site.
837   SmallVector<ActionEntry, 32> Actions;
838   SmallVector<unsigned, 64> FirstActions;
839   FirstActions.reserve(LandingPads.size());
840
841   int FirstAction = 0;
842   unsigned SizeActions = 0;
843   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
844     const LandingPadInfo *LP = LandingPads[i];
845     const std::vector<int> &TypeIds = LP->TypeIds;
846     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
847     unsigned SizeSiteActions = 0;
848
849     if (NumShared < TypeIds.size()) {
850       unsigned SizeAction = 0;
851       ActionEntry *PrevAction = 0;
852
853       if (NumShared) {
854         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
855         assert(Actions.size());
856         PrevAction = &Actions.back();
857         SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
858           TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
859         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
860           SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
861           SizeAction += -PrevAction->NextAction;
862           PrevAction = PrevAction->Previous;
863         }
864       }
865
866       // Compute the actions.
867       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
868         int TypeID = TypeIds[I];
869         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
870         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
871         unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
872
873         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
874         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
875         SizeSiteActions += SizeAction;
876
877         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
878         Actions.push_back(Action);
879
880         PrevAction = &Actions.back();
881       }
882
883       // Record the first action of the landing pad site.
884       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
885     } // else identical - re-use previous FirstAction
886
887     FirstActions.push_back(FirstAction);
888
889     // Compute this sites contribution to size.
890     SizeActions += SizeSiteActions;
891   }
892
893   // Compute the call-site table.  Entries must be ordered by address.
894   SmallVector<CallSiteEntry, 64> CallSites;
895
896   RangeMapType PadMap;
897   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
898     const LandingPadInfo *LandingPad = LandingPads[i];
899     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
900       unsigned BeginLabel = LandingPad->BeginLabels[j];
901       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
902       PadRange P = { i, j };
903       PadMap[BeginLabel] = P;
904     }
905   }
906
907   bool MayThrow = false;
908   unsigned LastLabel = 0;
909   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
910         I != E; ++I) {
911     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
912           MI != E; ++MI) {
913       if (!MI->isLabel()) {
914         MayThrow |= MI->getDesc().isCall();
915         continue;
916       }
917
918       unsigned BeginLabel = MI->getOperand(0).getImm();
919       assert(BeginLabel && "Invalid label!");
920
921       if (BeginLabel == LastLabel)
922         MayThrow = false;
923
924       RangeMapType::iterator L = PadMap.find(BeginLabel);
925
926       if (L == PadMap.end())
927         continue;
928
929       PadRange P = L->second;
930       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
931
932       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
933               "Inconsistent landing pad map!");
934
935       // If some instruction between the previous try-range and this one may
936       // throw, create a call-site entry with no landing pad for the region
937       // between the try-ranges.
938       if (MayThrow) {
939         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
940         CallSites.push_back(Site);
941       }
942
943       LastLabel = LandingPad->EndLabels[P.RangeIndex];
944       CallSiteEntry Site = {BeginLabel, LastLabel,
945         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
946
947       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
948               "Invalid landing pad!");
949
950       // Try to merge with the previous call-site.
951       if (CallSites.size()) {
952         CallSiteEntry &Prev = CallSites.back();
953         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
954           // Extend the range of the previous entry.
955           Prev.EndLabel = Site.EndLabel;
956           continue;
957         }
958       }
959
960       // Otherwise, create a new call-site.
961       CallSites.push_back(Site);
962     }
963   }
964   // If some instruction between the previous try-range and the end of the
965   // function may throw, create a call-site entry with no landing pad for the
966   // region following the try-range.
967   if (MayThrow) {
968     CallSiteEntry Site = {LastLabel, 0, 0, 0};
969     CallSites.push_back(Site);
970   }
971
972   // Final tallies.
973   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
974                                             sizeof(int32_t) + // Site length.
975                                             sizeof(int32_t)); // Landing pad.
976   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
977     SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
978
979   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
980
981   unsigned TypeOffset = sizeof(int8_t) + // Call site format
982                         // Call-site table length
983                         TargetAsmInfo::getULEB128Size(SizeSites) + 
984                         SizeSites + SizeActions + SizeTypes;
985
986   unsigned TotalSize = sizeof(int8_t) + // LPStart format
987                        sizeof(int8_t) + // TType format
988                        TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
989                        TypeOffset;
990
991   unsigned SizeAlign = (4 - TotalSize) & 3;
992
993   // Begin the exception table.
994   FinalSize = RoundUpToAlign(FinalSize, 4);
995   for (unsigned i = 0; i != SizeAlign; ++i) {
996     ++FinalSize;
997   }
998   
999   unsigned PointerSize = TD->getPointerSize();
1000
1001   // Emit the header.
1002   ++FinalSize;
1003   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
1004   ++FinalSize;
1005   // Asm->EOL("TType format (DW_EH_PE_absptr)");
1006   ++FinalSize;
1007   // Asm->EOL("TType base offset");
1008   ++FinalSize;
1009   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1010   ++FinalSize;
1011   // Asm->EOL("Call-site table length");
1012
1013   // Emit the landing pad site information.
1014   for (unsigned i = 0; i < CallSites.size(); ++i) {
1015     CallSiteEntry &S = CallSites[i];
1016
1017     // Asm->EOL("Region start");
1018     FinalSize += PointerSize;
1019     
1020     //Asm->EOL("Region length");
1021     FinalSize += PointerSize;
1022
1023     // Asm->EOL("Landing pad");
1024     FinalSize += PointerSize;
1025
1026     FinalSize += TargetAsmInfo::getULEB128Size(S.Action);
1027     // Asm->EOL("Action");
1028   }
1029
1030   // Emit the actions.
1031   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
1032     ActionEntry &Action = Actions[I];
1033
1034     //Asm->EOL("TypeInfo index");
1035     FinalSize += TargetAsmInfo::getSLEB128Size(Action.ValueForTypeID);
1036     //Asm->EOL("Next action");
1037     FinalSize += TargetAsmInfo::getSLEB128Size(Action.NextAction);
1038   }
1039
1040   // Emit the type ids.
1041   for (unsigned M = TypeInfos.size(); M; --M) {
1042     // Asm->EOL("TypeInfo");
1043     FinalSize += PointerSize;
1044   }
1045
1046   // Emit the filter typeids.
1047   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
1048     unsigned TypeID = FilterIds[j];
1049     FinalSize += TargetAsmInfo::getULEB128Size(TypeID);
1050     //Asm->EOL("Filter TypeInfo index");
1051   }
1052   
1053   FinalSize = RoundUpToAlign(FinalSize, 4);
1054
1055   return FinalSize;
1056 }