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