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