blob: 1bbad863d6199cb3a094506ec5ffecf9789c016e [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"
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000019#include "llvm/CodeGen/MachineCodeEmitter.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
31using namespace llvm;
32
33JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
34
35
36unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
37 MachineCodeEmitter& mce,
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 MCE = &mce;
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
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +000063void
64JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
65 const std::vector<MachineMove> &Moves) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000066 unsigned PointerSize = TD->getPointerSize();
67 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
68 PointerSize : -PointerSize;
69 bool IsLocal = BaseLabelPtr;
70
71 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
72 const MachineMove &Move = Moves[i];
73 unsigned LabelID = Move.getLabelID();
74
75 if (LabelID) {
76 LabelID = MMI->MappedLabel(LabelID);
77
78 // Throw out move if the label is invalid.
79 if (!LabelID) continue;
80 }
81
82 intptr_t LabelPtr = 0;
83 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
84
85 const MachineLocation &Dst = Move.getDestination();
86 const MachineLocation &Src = Move.getSource();
87
88 // Advance row if new location.
89 if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
90 MCE->emitByte(dwarf::DW_CFA_advance_loc4);
91 if (PointerSize == 8) {
92 MCE->emitInt64(LabelPtr - BaseLabelPtr);
93 } else {
94 MCE->emitInt32(LabelPtr - BaseLabelPtr);
95 }
96
97 BaseLabelPtr = LabelPtr;
98 IsLocal = true;
99 }
100
101 // If advancing cfa.
102 if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
103 if (!Src.isRegister()) {
104 if (Src.getRegister() == MachineLocation::VirtualFP) {
105 MCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
106 } else {
107 MCE->emitByte(dwarf::DW_CFA_def_cfa);
108 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), true));
109 }
110
111 int Offset = -Src.getOffset();
112
113 MCE->emitULEB128Bytes(Offset);
114 } else {
115 assert(0 && "Machine move no supported yet.");
116 }
117 } else if (Src.isRegister() &&
118 Src.getRegister() == MachineLocation::VirtualFP) {
119 if (Dst.isRegister()) {
120 MCE->emitByte(dwarf::DW_CFA_def_cfa_register);
121 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister(), true));
122 } else {
123 assert(0 && "Machine move no supported yet.");
124 }
125 } else {
126 unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
127 int Offset = Dst.getOffset() / stackGrowth;
128
129 if (Offset < 0) {
130 MCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
131 MCE->emitULEB128Bytes(Reg);
132 MCE->emitSLEB128Bytes(Offset);
133 } else if (Reg < 64) {
134 MCE->emitByte(dwarf::DW_CFA_offset + Reg);
135 MCE->emitULEB128Bytes(Offset);
136 } else {
137 MCE->emitByte(dwarf::DW_CFA_offset_extended);
138 MCE->emitULEB128Bytes(Reg);
139 MCE->emitULEB128Bytes(Offset);
140 }
141 }
142 }
143}
144
145/// SharedTypeIds - How many leading type ids two landing pads have in common.
146static unsigned SharedTypeIds(const LandingPadInfo *L,
147 const LandingPadInfo *R) {
148 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
149 unsigned LSize = LIds.size(), RSize = RIds.size();
150 unsigned MinSize = LSize < RSize ? LSize : RSize;
151 unsigned Count = 0;
152
153 for (; Count != MinSize; ++Count)
154 if (LIds[Count] != RIds[Count])
155 return Count;
156
157 return Count;
158}
159
160
161/// PadLT - Order landing pads lexicographically by type id.
162static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
163 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
164 unsigned LSize = LIds.size(), RSize = RIds.size();
165 unsigned MinSize = LSize < RSize ? LSize : RSize;
166
167 for (unsigned i = 0; i != MinSize; ++i)
168 if (LIds[i] != RIds[i])
169 return LIds[i] < RIds[i];
170
171 return LSize < RSize;
172}
173
Dan Gohman844731a2008-05-13 00:00:25 +0000174namespace {
175
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000176struct KeyInfo {
177 static inline unsigned getEmptyKey() { return -1U; }
178 static inline unsigned getTombstoneKey() { return -2U; }
179 static unsigned getHashValue(const unsigned &Key) { return Key; }
180 static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
181 static bool isPod() { return true; }
182};
183
184/// ActionEntry - Structure describing an entry in the actions table.
185struct ActionEntry {
186 int ValueForTypeID; // The value to write - may not be equal to the type id.
187 int NextAction;
188 struct ActionEntry *Previous;
189};
190
191/// PadRange - Structure holding a try-range and the associated landing pad.
192struct PadRange {
193 // The index of the landing pad.
194 unsigned PadIndex;
195 // The index of the begin and end labels in the landing pad's label lists.
196 unsigned RangeIndex;
197};
198
199typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
200
201/// CallSiteEntry - Structure describing an entry in the call-site table.
202struct CallSiteEntry {
203 unsigned BeginLabel; // zero indicates the start of the function.
204 unsigned EndLabel; // zero indicates the end of the function.
205 unsigned PadLabel; // zero indicates that there is no landing pad.
206 unsigned Action;
207};
208
Dan Gohman844731a2008-05-13 00:00:25 +0000209}
210
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000211unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
212 unsigned char* StartFunction,
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000213 unsigned char* EndFunction) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000214 // Map all labels and get rid of any dead landing pads.
215 MMI->TidyLandingPads();
216
217 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
218 const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
219 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
220 if (PadInfos.empty()) return 0;
221
222 // Sort the landing pads in order of their type ids. This is used to fold
223 // duplicate actions.
224 SmallVector<const LandingPadInfo *, 64> LandingPads;
225 LandingPads.reserve(PadInfos.size());
226 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
227 LandingPads.push_back(&PadInfos[i]);
228 std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
229
230 // Negative type ids index into FilterIds, positive type ids index into
231 // TypeInfos. The value written for a positive type id is just the type
232 // id itself. For a negative type id, however, the value written is the
233 // (negative) byte offset of the corresponding FilterIds entry. The byte
234 // offset is usually equal to the type id, because the FilterIds entries
235 // are written using a variable width encoding which outputs one byte per
236 // entry as long as the value written is not too large, but can differ.
237 // This kind of complication does not occur for positive type ids because
238 // type infos are output using a fixed width encoding.
239 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
240 SmallVector<int, 16> FilterOffsets;
241 FilterOffsets.reserve(FilterIds.size());
242 int Offset = -1;
243 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
244 E = FilterIds.end(); I != E; ++I) {
245 FilterOffsets.push_back(Offset);
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000246 Offset -= TargetAsmInfo::getULEB128Size(*I);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000247 }
248
249 // Compute the actions table and gather the first action index for each
250 // landing pad site.
251 SmallVector<ActionEntry, 32> Actions;
252 SmallVector<unsigned, 64> FirstActions;
253 FirstActions.reserve(LandingPads.size());
254
255 int FirstAction = 0;
256 unsigned SizeActions = 0;
257 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
258 const LandingPadInfo *LP = LandingPads[i];
259 const std::vector<int> &TypeIds = LP->TypeIds;
260 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
261 unsigned SizeSiteActions = 0;
262
263 if (NumShared < TypeIds.size()) {
264 unsigned SizeAction = 0;
265 ActionEntry *PrevAction = 0;
266
267 if (NumShared) {
268 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
269 assert(Actions.size());
270 PrevAction = &Actions.back();
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000271 SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
272 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000273 for (unsigned j = NumShared; j != SizePrevIds; ++j) {
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000274 SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000275 SizeAction += -PrevAction->NextAction;
276 PrevAction = PrevAction->Previous;
277 }
278 }
279
280 // Compute the actions.
281 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
282 int TypeID = TypeIds[I];
283 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
284 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000285 unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000286
287 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000288 SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000289 SizeSiteActions += SizeAction;
290
291 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
292 Actions.push_back(Action);
293
294 PrevAction = &Actions.back();
295 }
296
297 // Record the first action of the landing pad site.
298 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
299 } // else identical - re-use previous FirstAction
300
301 FirstActions.push_back(FirstAction);
302
303 // Compute this sites contribution to size.
304 SizeActions += SizeSiteActions;
305 }
306
307 // Compute the call-site table. Entries must be ordered by address.
308 SmallVector<CallSiteEntry, 64> CallSites;
309
310 RangeMapType PadMap;
311 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
312 const LandingPadInfo *LandingPad = LandingPads[i];
313 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
314 unsigned BeginLabel = LandingPad->BeginLabels[j];
315 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
316 PadRange P = { i, j };
317 PadMap[BeginLabel] = P;
318 }
319 }
320
321 bool MayThrow = false;
322 unsigned LastLabel = 0;
323 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
324 I != E; ++I) {
325 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
326 MI != E; ++MI) {
Dan Gohman44066042008-07-01 00:05:16 +0000327 if (!MI->isLabel()) {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000328 MayThrow |= MI->getDesc().isCall();
329 continue;
330 }
331
332 unsigned BeginLabel = MI->getOperand(0).getImm();
333 assert(BeginLabel && "Invalid label!");
334
335 if (BeginLabel == LastLabel)
336 MayThrow = false;
337
338 RangeMapType::iterator L = PadMap.find(BeginLabel);
339
340 if (L == PadMap.end())
341 continue;
342
343 PadRange P = L->second;
344 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
345
346 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
347 "Inconsistent landing pad map!");
348
349 // If some instruction between the previous try-range and this one may
350 // throw, create a call-site entry with no landing pad for the region
351 // between the try-ranges.
352 if (MayThrow) {
353 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
354 CallSites.push_back(Site);
355 }
356
357 LastLabel = LandingPad->EndLabels[P.RangeIndex];
358 CallSiteEntry Site = {BeginLabel, LastLabel,
359 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
360
361 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
362 "Invalid landing pad!");
363
364 // Try to merge with the previous call-site.
365 if (CallSites.size()) {
Dan Gohman719de532008-06-21 22:00:54 +0000366 CallSiteEntry &Prev = CallSites.back();
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000367 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
368 // Extend the range of the previous entry.
369 Prev.EndLabel = Site.EndLabel;
370 continue;
371 }
372 }
373
374 // Otherwise, create a new call-site.
375 CallSites.push_back(Site);
376 }
377 }
378 // If some instruction between the previous try-range and the end of the
379 // function may throw, create a call-site entry with no landing pad for the
380 // region following the try-range.
381 if (MayThrow) {
382 CallSiteEntry Site = {LastLabel, 0, 0, 0};
383 CallSites.push_back(Site);
384 }
385
386 // Final tallies.
387 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
388 sizeof(int32_t) + // Site length.
389 sizeof(int32_t)); // Landing pad.
390 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000391 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000392
393 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
394
395 unsigned TypeOffset = sizeof(int8_t) + // Call site format
396 // Call-site table length
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000397 TargetAsmInfo::getULEB128Size(SizeSites) +
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000398 SizeSites + SizeActions + SizeTypes;
399
400 unsigned TotalSize = sizeof(int8_t) + // LPStart format
401 sizeof(int8_t) + // TType format
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000402 TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000403 TypeOffset;
404
405 unsigned SizeAlign = (4 - TotalSize) & 3;
406
407 // Begin the exception table.
408 MCE->emitAlignment(4);
409 for (unsigned i = 0; i != SizeAlign; ++i) {
410 MCE->emitByte(0);
411 // Asm->EOL("Padding");
412 }
413
414 unsigned char* DwarfExceptionTable = (unsigned char*)MCE->getCurrentPCValue();
415
416 // Emit the header.
417 MCE->emitByte(dwarf::DW_EH_PE_omit);
418 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
419 MCE->emitByte(dwarf::DW_EH_PE_absptr);
420 // Asm->EOL("TType format (DW_EH_PE_absptr)");
421 MCE->emitULEB128Bytes(TypeOffset);
422 // Asm->EOL("TType base offset");
423 MCE->emitByte(dwarf::DW_EH_PE_udata4);
424 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
425 MCE->emitULEB128Bytes(SizeSites);
426 // Asm->EOL("Call-site table length");
427
428 // Emit the landing pad site information.
429 for (unsigned i = 0; i < CallSites.size(); ++i) {
430 CallSiteEntry &S = CallSites[i];
431 intptr_t BeginLabelPtr = 0;
432 intptr_t EndLabelPtr = 0;
433
434 if (!S.BeginLabel) {
435 BeginLabelPtr = (intptr_t)StartFunction;
436 if (TD->getPointerSize() == sizeof(int32_t))
437 MCE->emitInt32(0);
438 else
439 MCE->emitInt64(0);
440 } else {
441 BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel);
442 if (TD->getPointerSize() == sizeof(int32_t))
443 MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
444 else
445 MCE->emitInt64(BeginLabelPtr - (intptr_t)StartFunction);
446 }
447
448 // Asm->EOL("Region start");
449
450 if (!S.EndLabel) {
451 EndLabelPtr = (intptr_t)EndFunction;
452 if (TD->getPointerSize() == sizeof(int32_t))
453 MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
454 else
455 MCE->emitInt64((intptr_t)EndFunction - BeginLabelPtr);
456 } else {
457 EndLabelPtr = MCE->getLabelAddress(S.EndLabel);
458 if (TD->getPointerSize() == sizeof(int32_t))
459 MCE->emitInt32(EndLabelPtr - BeginLabelPtr);
460 else
461 MCE->emitInt64(EndLabelPtr - BeginLabelPtr);
462 }
463 //Asm->EOL("Region length");
464
465 if (!S.PadLabel) {
466 if (TD->getPointerSize() == sizeof(int32_t))
467 MCE->emitInt32(0);
468 else
469 MCE->emitInt64(0);
470 } else {
471 unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel);
472 if (TD->getPointerSize() == sizeof(int32_t))
473 MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
474 else
475 MCE->emitInt64(PadLabelPtr - (intptr_t)StartFunction);
476 }
477 // Asm->EOL("Landing pad");
478
479 MCE->emitULEB128Bytes(S.Action);
480 // Asm->EOL("Action");
481 }
482
483 // Emit the actions.
484 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
485 ActionEntry &Action = Actions[I];
486
487 MCE->emitSLEB128Bytes(Action.ValueForTypeID);
488 //Asm->EOL("TypeInfo index");
489 MCE->emitSLEB128Bytes(Action.NextAction);
490 //Asm->EOL("Next action");
491 }
492
493 // Emit the type ids.
494 for (unsigned M = TypeInfos.size(); M; --M) {
495 GlobalVariable *GV = TypeInfos[M - 1];
496
497 if (GV) {
498 if (TD->getPointerSize() == sizeof(int32_t)) {
499 MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
500 } else {
501 MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
502 }
503 } else {
504 if (TD->getPointerSize() == sizeof(int32_t))
505 MCE->emitInt32(0);
506 else
507 MCE->emitInt64(0);
508 }
509 // Asm->EOL("TypeInfo");
510 }
511
512 // Emit the filter typeids.
513 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
514 unsigned TypeID = FilterIds[j];
515 MCE->emitULEB128Bytes(TypeID);
516 //Asm->EOL("Filter TypeInfo index");
517 }
518
519 MCE->emitAlignment(4);
520
521 return DwarfExceptionTable;
522}
523
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000524unsigned char*
525JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000526 unsigned PointerSize = TD->getPointerSize();
527 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
528 PointerSize : -PointerSize;
529
530 unsigned char* StartCommonPtr = (unsigned char*)MCE->getCurrentPCValue();
531 // EH Common Frame header
532 MCE->allocateSpace(PointerSize, 0);
533 unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
534 MCE->emitInt32((int)0);
535 MCE->emitByte(dwarf::DW_CIE_VERSION);
536 MCE->emitString(Personality ? "zPLR" : "zR");
537 MCE->emitULEB128Bytes(1);
538 MCE->emitSLEB128Bytes(stackGrowth);
539 MCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
540
541 if (Personality) {
542 MCE->emitULEB128Bytes(7);
543
544 if (needsIndirectEncoding)
545 MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
546 dwarf::DW_EH_PE_indirect);
547 else
548 MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
549
550 if (PointerSize == 8)
551 MCE->emitInt64((intptr_t)Jit.getPointerToGlobal(Personality) -
552 MCE->getCurrentPCValue());
553 else
554 MCE->emitInt32((intptr_t)Jit.getPointerToGlobal(Personality) -
555 MCE->getCurrentPCValue());
556
557 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
558 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
559
560 } else {
561 MCE->emitULEB128Bytes(1);
562 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
563 }
564
565 std::vector<MachineMove> Moves;
566 RI->getInitialFrameState(Moves);
567 EmitFrameMoves(0, Moves);
568 MCE->emitAlignment(4);
569
570 MCE->emitAt((uintptr_t*)StartCommonPtr,
571 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
572 FrameCommonBeginPtr));
573
574 return StartCommonPtr;
575}
576
577
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000578unsigned char*
579JITDwarfEmitter::EmitEHFrame(const Function* Personality,
580 unsigned char* StartCommonPtr,
581 unsigned char* StartFunction,
582 unsigned char* EndFunction,
583 unsigned char* ExceptionTable) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000584 unsigned PointerSize = TD->getPointerSize();
585
586 // EH frame header.
587 unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue();
588 MCE->allocateSpace(PointerSize, 0);
589 unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
590 // FDE CIE Offset
591 if (PointerSize == 8) {
592 MCE->emitInt64(FrameBeginPtr - StartCommonPtr);
593 MCE->emitInt64(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
594 MCE->emitInt64(EndFunction - StartFunction);
595 } else {
596 MCE->emitInt32(FrameBeginPtr - StartCommonPtr);
597 MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
598 MCE->emitInt32(EndFunction - StartFunction);
599 }
600
601 // If there is a personality and landing pads then point to the language
602 // specific data area in the exception table.
603 if (MMI->getPersonalityIndex()) {
604 MCE->emitULEB128Bytes(4);
605
606 if (!MMI->getLandingPads().empty()) {
607 if (PointerSize == 8)
608 MCE->emitInt64(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
609 else
610 MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
611 } else if (PointerSize == 8) {
612 MCE->emitInt64((int)0);
613 } else {
614 MCE->emitInt32((int)0);
615 }
616 } else {
617 MCE->emitULEB128Bytes(0);
618 }
619
620 // Indicate locations of function specific callee saved registers in
621 // frame.
622 EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
623
624 MCE->emitAlignment(4);
625
626 // Indicate the size of the table
627 MCE->emitAt((uintptr_t*)StartEHPtr,
628 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
629 StartEHPtr));
630
631 // Double zeroes for the unwind runtime
632 if (PointerSize == 8) {
633 MCE->emitInt64(0);
634 MCE->emitInt64(0);
635 } else {
636 MCE->emitInt32(0);
637 MCE->emitInt32(0);
638 }
639
640
641 return StartEHPtr;
642}
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000643
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000644unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000645 MachineCodeEmitter& mce,
646 unsigned char* StartFunction,
647 unsigned char* EndFunction) {
648 const TargetMachine& TM = F.getTarget();
649 TD = TM.getTargetData();
650 needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
651 stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
652 RI = TM.getRegisterInfo();
653 MCE = &mce;
654 unsigned FinalSize = 0;
655
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000656 FinalSize += GetExceptionTableSizeInBytes(&F);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000657
658 const std::vector<Function *> Personalities = MMI->getPersonalities();
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000659 FinalSize += GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000660
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000661 FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()], StartFunction);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000662
663 return FinalSize;
664}
665
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000666/// RoundUpToAlign - Add the specified alignment to FinalSize and returns
667/// the new value.
668static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000669 if (Alignment == 0) Alignment = 1;
Nicolas Geoffray580631a2008-04-20 23:39:44 +0000670 // Since we do not know where the buffer will be allocated, be pessimistic.
671 return FinalSize + Alignment;
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000672}
673
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000674unsigned
675JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
676 unsigned char* StartFunction) const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000677 unsigned PointerSize = TD->getPointerSize();
678 unsigned FinalSize = 0;
679 // EH frame header.
680 FinalSize += PointerSize;
681 // FDE CIE Offset
682 FinalSize += 3 * PointerSize;
683 // If there is a personality and landing pads then point to the language
684 // specific data area in the exception table.
685 if (MMI->getPersonalityIndex()) {
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000686 FinalSize += TargetAsmInfo::getULEB128Size(4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000687 FinalSize += PointerSize;
688 } else {
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000689 FinalSize += TargetAsmInfo::getULEB128Size(0);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000690 }
691
692 // Indicate locations of function specific callee saved registers in
693 // frame.
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000694 FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
695 MMI->getFrameMoves());
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000696
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000697 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000698
699 // Double zeroes for the unwind runtime
700 FinalSize += 2 * PointerSize;
701
702 return FinalSize;
703}
704
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000705unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality)
706 const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000707
708 unsigned PointerSize = TD->getPointerSize();
709 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
710 PointerSize : -PointerSize;
711 unsigned FinalSize = 0;
712 // EH Common Frame header
713 FinalSize += PointerSize;
714 FinalSize += 4;
715 FinalSize += 1;
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000716 FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000717 FinalSize += TargetAsmInfo::getULEB128Size(1);
718 FinalSize += TargetAsmInfo::getSLEB128Size(stackGrowth);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000719 FinalSize += 1;
720
721 if (Personality) {
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000722 FinalSize += TargetAsmInfo::getULEB128Size(7);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000723
724 // Encoding
725 FinalSize+= 1;
726 //Personality
727 FinalSize += PointerSize;
728
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000729 FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
730 FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000731
732 } else {
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000733 FinalSize += TargetAsmInfo::getULEB128Size(1);
734 FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000735 }
736
737 std::vector<MachineMove> Moves;
738 RI->getInitialFrameState(Moves);
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000739 FinalSize += GetFrameMovesSizeInBytes(0, Moves);
740 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000741 return FinalSize;
742}
743
744unsigned
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000745JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
746 const std::vector<MachineMove> &Moves) const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000747 unsigned PointerSize = TD->getPointerSize();
748 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
749 PointerSize : -PointerSize;
750 bool IsLocal = BaseLabelPtr;
751 unsigned FinalSize = 0;
752
753 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
754 const MachineMove &Move = Moves[i];
755 unsigned LabelID = Move.getLabelID();
756
757 if (LabelID) {
758 LabelID = MMI->MappedLabel(LabelID);
759
760 // Throw out move if the label is invalid.
761 if (!LabelID) continue;
762 }
763
764 intptr_t LabelPtr = 0;
765 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
766
767 const MachineLocation &Dst = Move.getDestination();
768 const MachineLocation &Src = Move.getSource();
769
770 // Advance row if new location.
771 if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
772 FinalSize++;
773 FinalSize += PointerSize;
774 BaseLabelPtr = LabelPtr;
775 IsLocal = true;
776 }
777
778 // If advancing cfa.
779 if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
780 if (!Src.isRegister()) {
781 if (Src.getRegister() == MachineLocation::VirtualFP) {
782 ++FinalSize;
783 } else {
784 ++FinalSize;
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000785 unsigned RegNum = RI->getDwarfRegNum(Src.getRegister(), true);
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000786 FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000787 }
788
789 int Offset = -Src.getOffset();
790
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000791 FinalSize += TargetAsmInfo::getULEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000792 } else {
793 assert(0 && "Machine move no supported yet.");
794 }
795 } else if (Src.isRegister() &&
796 Src.getRegister() == MachineLocation::VirtualFP) {
797 if (Dst.isRegister()) {
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000798 ++FinalSize;
799 unsigned RegNum = RI->getDwarfRegNum(Dst.getRegister(), true);
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000800 FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000801 } else {
802 assert(0 && "Machine move no supported yet.");
803 }
804 } else {
805 unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
806 int Offset = Dst.getOffset() / stackGrowth;
807
808 if (Offset < 0) {
809 ++FinalSize;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000810 FinalSize += TargetAsmInfo::getULEB128Size(Reg);
811 FinalSize += TargetAsmInfo::getSLEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000812 } else if (Reg < 64) {
813 ++FinalSize;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000814 FinalSize += TargetAsmInfo::getULEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000815 } else {
816 ++FinalSize;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000817 FinalSize += TargetAsmInfo::getULEB128Size(Reg);
818 FinalSize += TargetAsmInfo::getULEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000819 }
820 }
821 }
822 return FinalSize;
823}
824
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000825unsigned
826JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000827 unsigned FinalSize = 0;
828
829 // Map all labels and get rid of any dead landing pads.
830 MMI->TidyLandingPads();
831
832 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
833 const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
834 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
835 if (PadInfos.empty()) return 0;
836
837 // Sort the landing pads in order of their type ids. This is used to fold
838 // duplicate actions.
839 SmallVector<const LandingPadInfo *, 64> LandingPads;
840 LandingPads.reserve(PadInfos.size());
841 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
842 LandingPads.push_back(&PadInfos[i]);
843 std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
844
845 // Negative type ids index into FilterIds, positive type ids index into
846 // TypeInfos. The value written for a positive type id is just the type
847 // id itself. For a negative type id, however, the value written is the
848 // (negative) byte offset of the corresponding FilterIds entry. The byte
849 // offset is usually equal to the type id, because the FilterIds entries
850 // are written using a variable width encoding which outputs one byte per
851 // entry as long as the value written is not too large, but can differ.
852 // This kind of complication does not occur for positive type ids because
853 // type infos are output using a fixed width encoding.
854 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
855 SmallVector<int, 16> FilterOffsets;
856 FilterOffsets.reserve(FilterIds.size());
857 int Offset = -1;
858 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
859 E = FilterIds.end(); I != E; ++I) {
860 FilterOffsets.push_back(Offset);
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000861 Offset -= TargetAsmInfo::getULEB128Size(*I);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000862 }
863
864 // Compute the actions table and gather the first action index for each
865 // landing pad site.
866 SmallVector<ActionEntry, 32> Actions;
867 SmallVector<unsigned, 64> FirstActions;
868 FirstActions.reserve(LandingPads.size());
869
870 int FirstAction = 0;
871 unsigned SizeActions = 0;
872 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
873 const LandingPadInfo *LP = LandingPads[i];
874 const std::vector<int> &TypeIds = LP->TypeIds;
875 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
876 unsigned SizeSiteActions = 0;
877
878 if (NumShared < TypeIds.size()) {
879 unsigned SizeAction = 0;
880 ActionEntry *PrevAction = 0;
881
882 if (NumShared) {
883 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
884 assert(Actions.size());
885 PrevAction = &Actions.back();
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000886 SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
887 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000888 for (unsigned j = NumShared; j != SizePrevIds; ++j) {
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000889 SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000890 SizeAction += -PrevAction->NextAction;
891 PrevAction = PrevAction->Previous;
892 }
893 }
894
895 // Compute the actions.
896 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
897 int TypeID = TypeIds[I];
898 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
899 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000900 unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000901
902 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
Anton Korobeynikovffe31d72008-08-16 12:57:46 +0000903 SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000904 SizeSiteActions += SizeAction;
905
906 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
907 Actions.push_back(Action);
908
909 PrevAction = &Actions.back();
910 }
911
912 // Record the first action of the landing pad site.
913 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
914 } // else identical - re-use previous FirstAction
915
916 FirstActions.push_back(FirstAction);
917
918 // Compute this sites contribution to size.
919 SizeActions += SizeSiteActions;
920 }
921
922 // Compute the call-site table. Entries must be ordered by address.
923 SmallVector<CallSiteEntry, 64> CallSites;
924
925 RangeMapType PadMap;
926 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
927 const LandingPadInfo *LandingPad = LandingPads[i];
928 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
929 unsigned BeginLabel = LandingPad->BeginLabels[j];
930 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
931 PadRange P = { i, j };
932 PadMap[BeginLabel] = P;
933 }
934 }
935
936 bool MayThrow = false;
937 unsigned LastLabel = 0;
938 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
939 I != E; ++I) {
940 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
941 MI != E; ++MI) {
Dan Gohman44066042008-07-01 00:05:16 +0000942 if (!MI->isLabel()) {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000943 MayThrow |= MI->getDesc().isCall();
944 continue;
945 }
946
947 unsigned BeginLabel = MI->getOperand(0).getImm();
948 assert(BeginLabel && "Invalid label!");
949
950 if (BeginLabel == LastLabel)
951 MayThrow = false;
952
953 RangeMapType::iterator L = PadMap.find(BeginLabel);
954
955 if (L == PadMap.end())
956 continue;
957
958 PadRange P = L->second;
959 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
960
961 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
962 "Inconsistent landing pad map!");
963
964 // If some instruction between the previous try-range and this one may
965 // throw, create a call-site entry with no landing pad for the region
966 // between the try-ranges.
967 if (MayThrow) {
968 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
969 CallSites.push_back(Site);
970 }
971
972 LastLabel = LandingPad->EndLabels[P.RangeIndex];
973 CallSiteEntry Site = {BeginLabel, LastLabel,
974 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
975
976 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
977 "Invalid landing pad!");
978
979 // Try to merge with the previous call-site.
980 if (CallSites.size()) {
Dan Gohman719de532008-06-21 22:00:54 +0000981 CallSiteEntry &Prev = CallSites.back();
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000982 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
983 // Extend the range of the previous entry.
984 Prev.EndLabel = Site.EndLabel;
985 continue;
986 }
987 }
988
989 // Otherwise, create a new call-site.
990 CallSites.push_back(Site);
991 }
992 }
993 // If some instruction between the previous try-range and the end of the
994 // function may throw, create a call-site entry with no landing pad for the
995 // region following the try-range.
996 if (MayThrow) {
997 CallSiteEntry Site = {LastLabel, 0, 0, 0};
998 CallSites.push_back(Site);
999 }
1000
1001 // Final tallies.
1002 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
1003 sizeof(int32_t) + // Site length.
1004 sizeof(int32_t)); // Landing pad.
1005 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001006 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001007
1008 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
1009
1010 unsigned TypeOffset = sizeof(int8_t) + // Call site format
1011 // Call-site table length
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001012 TargetAsmInfo::getULEB128Size(SizeSites) +
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001013 SizeSites + SizeActions + SizeTypes;
1014
1015 unsigned TotalSize = sizeof(int8_t) + // LPStart format
1016 sizeof(int8_t) + // TType format
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001017 TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001018 TypeOffset;
1019
1020 unsigned SizeAlign = (4 - TotalSize) & 3;
1021
1022 // Begin the exception table.
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +00001023 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001024 for (unsigned i = 0; i != SizeAlign; ++i) {
1025 ++FinalSize;
1026 }
1027
1028 unsigned PointerSize = TD->getPointerSize();
1029
1030 // Emit the header.
1031 ++FinalSize;
1032 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
1033 ++FinalSize;
1034 // Asm->EOL("TType format (DW_EH_PE_absptr)");
1035 ++FinalSize;
1036 // Asm->EOL("TType base offset");
1037 ++FinalSize;
1038 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1039 ++FinalSize;
1040 // Asm->EOL("Call-site table length");
1041
1042 // Emit the landing pad site information.
1043 for (unsigned i = 0; i < CallSites.size(); ++i) {
1044 CallSiteEntry &S = CallSites[i];
1045
1046 // Asm->EOL("Region start");
1047 FinalSize += PointerSize;
1048
1049 //Asm->EOL("Region length");
1050 FinalSize += PointerSize;
1051
1052 // Asm->EOL("Landing pad");
1053 FinalSize += PointerSize;
1054
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001055 FinalSize += TargetAsmInfo::getULEB128Size(S.Action);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001056 // Asm->EOL("Action");
1057 }
1058
1059 // Emit the actions.
1060 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
1061 ActionEntry &Action = Actions[I];
1062
1063 //Asm->EOL("TypeInfo index");
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001064 FinalSize += TargetAsmInfo::getSLEB128Size(Action.ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001065 //Asm->EOL("Next action");
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001066 FinalSize += TargetAsmInfo::getSLEB128Size(Action.NextAction);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001067 }
1068
1069 // Emit the type ids.
1070 for (unsigned M = TypeInfos.size(); M; --M) {
1071 // Asm->EOL("TypeInfo");
1072 FinalSize += PointerSize;
1073 }
1074
1075 // Emit the filter typeids.
1076 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
1077 unsigned TypeID = FilterIds[j];
Anton Korobeynikovffe31d72008-08-16 12:57:46 +00001078 FinalSize += TargetAsmInfo::getULEB128Size(TypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001079 //Asm->EOL("Filter TypeInfo index");
1080 }
1081
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +00001082 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001083
1084 return FinalSize;
1085}