1 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a JITDwarfEmitter object that is used by the JIT to
11 // write dwarf tables to memory.
13 //===----------------------------------------------------------------------===//
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"
34 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
37 unsigned 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();
48 unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
51 unsigned char* Result = 0;
52 unsigned char* EHFramePtr = 0;
54 const std::vector<Function *> Personalities = MMI->getPersonalities();
55 EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
57 Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
58 StartFunction, EndFunction, ExceptionTable);
65 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
66 const std::vector<MachineMove> &Moves) const {
67 unsigned PointerSize = TD->getPointerSize();
68 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
69 PointerSize : -PointerSize;
70 bool IsLocal = BaseLabelPtr;
72 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
73 const MachineMove &Move = Moves[i];
74 unsigned LabelID = Move.getLabelID();
77 LabelID = MMI->MappedLabel(LabelID);
79 // Throw out move if the label is invalid.
80 if (!LabelID) continue;
83 intptr_t LabelPtr = 0;
84 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
86 const MachineLocation &Dst = Move.getDestination();
87 const MachineLocation &Src = Move.getSource();
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);
95 MCE->emitInt32(LabelPtr - BaseLabelPtr);
98 BaseLabelPtr = LabelPtr;
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);
108 MCE->emitByte(dwarf::DW_CFA_def_cfa);
109 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), true));
112 int Offset = -Src.getOffset();
114 MCE->emitULEB128Bytes(Offset);
116 assert(0 && "Machine move no supported yet.");
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));
124 assert(0 && "Machine move no supported yet.");
127 unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
128 int Offset = Dst.getOffset() / stackGrowth;
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);
138 MCE->emitByte(dwarf::DW_CFA_offset_extended);
139 MCE->emitULEB128Bytes(Reg);
140 MCE->emitULEB128Bytes(Offset);
146 /// SharedTypeIds - How many leading type ids two landing pads have in common.
147 static 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;
154 for (; Count != MinSize; ++Count)
155 if (LIds[Count] != RIds[Count])
162 /// PadLT - Order landing pads lexicographically by type id.
163 static 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;
168 for (unsigned i = 0; i != MinSize; ++i)
169 if (LIds[i] != RIds[i])
170 return LIds[i] < RIds[i];
172 return LSize < RSize;
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; }
185 /// ActionEntry - Structure describing an entry in the actions table.
187 int ValueForTypeID; // The value to write - may not be equal to the type id.
189 struct ActionEntry *Previous;
192 /// PadRange - Structure holding a try-range and the associated landing pad.
194 // The index of the landing pad.
196 // The index of the begin and end labels in the landing pad's label lists.
200 typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
202 /// CallSiteEntry - Structure describing an entry in the call-site table.
203 struct 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.
212 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
213 unsigned char* StartFunction,
214 unsigned char* EndFunction) const {
215 // Map all labels and get rid of any dead landing pads.
216 MMI->TidyLandingPads();
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;
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);
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());
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);
250 // Compute the actions table and gather the first action index for each
252 SmallVector<ActionEntry, 32> Actions;
253 SmallVector<unsigned, 64> FirstActions;
254 FirstActions.reserve(LandingPads.size());
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;
264 if (NumShared < TypeIds.size()) {
265 unsigned SizeAction = 0;
266 ActionEntry *PrevAction = 0;
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;
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);
288 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
289 SizeAction = SizeTypeID + AsmPrinter::SizeSLEB128(NextAction);
290 SizeSiteActions += SizeAction;
292 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
293 Actions.push_back(Action);
295 PrevAction = &Actions.back();
298 // Record the first action of the landing pad site.
299 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
300 } // else identical - re-use previous FirstAction
302 FirstActions.push_back(FirstAction);
304 // Compute this sites contribution to size.
305 SizeActions += SizeSiteActions;
308 // Compute the call-site table. Entries must be ordered by address.
309 SmallVector<CallSiteEntry, 64> CallSites;
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;
322 bool MayThrow = false;
323 unsigned LastLabel = 0;
324 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
326 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
328 if (MI->getOpcode() != TargetInstrInfo::LABEL) {
329 MayThrow |= MI->getDesc().isCall();
333 unsigned BeginLabel = MI->getOperand(0).getImm();
334 assert(BeginLabel && "Invalid label!");
336 if (BeginLabel == LastLabel)
339 RangeMapType::iterator L = PadMap.find(BeginLabel);
341 if (L == PadMap.end())
344 PadRange P = L->second;
345 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
347 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
348 "Inconsistent landing pad map!");
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.
354 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
355 CallSites.push_back(Site);
358 LastLabel = LandingPad->EndLabels[P.RangeIndex];
359 CallSiteEntry Site = {BeginLabel, LastLabel,
360 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
362 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
363 "Invalid landing pad!");
365 // Try to merge with the previous call-site.
366 if (CallSites.size()) {
367 CallSiteEntry &Prev = CallSites.back();
368 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
369 // Extend the range of the previous entry.
370 Prev.EndLabel = Site.EndLabel;
375 // Otherwise, create a new call-site.
376 CallSites.push_back(Site);
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.
383 CallSiteEntry Site = {LastLabel, 0, 0, 0};
384 CallSites.push_back(Site);
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);
394 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
396 unsigned TypeOffset = sizeof(int8_t) + // Call site format
397 // Call-site table length
398 AsmPrinter::SizeULEB128(SizeSites) +
399 SizeSites + SizeActions + SizeTypes;
401 unsigned TotalSize = sizeof(int8_t) + // LPStart format
402 sizeof(int8_t) + // TType format
403 AsmPrinter::SizeULEB128(TypeOffset) + // TType base offset
406 unsigned SizeAlign = (4 - TotalSize) & 3;
408 // Begin the exception table.
409 MCE->emitAlignment(4);
410 for (unsigned i = 0; i != SizeAlign; ++i) {
412 // Asm->EOL("Padding");
415 unsigned char* DwarfExceptionTable = (unsigned char*)MCE->getCurrentPCValue();
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");
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;
436 BeginLabelPtr = (intptr_t)StartFunction;
437 if (TD->getPointerSize() == sizeof(int32_t))
442 BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel);
443 if (TD->getPointerSize() == sizeof(int32_t))
444 MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
446 MCE->emitInt64(BeginLabelPtr - (intptr_t)StartFunction);
449 // Asm->EOL("Region start");
452 EndLabelPtr = (intptr_t)EndFunction;
453 if (TD->getPointerSize() == sizeof(int32_t))
454 MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
456 MCE->emitInt64((intptr_t)EndFunction - BeginLabelPtr);
458 EndLabelPtr = MCE->getLabelAddress(S.EndLabel);
459 if (TD->getPointerSize() == sizeof(int32_t))
460 MCE->emitInt32(EndLabelPtr - BeginLabelPtr);
462 MCE->emitInt64(EndLabelPtr - BeginLabelPtr);
464 //Asm->EOL("Region length");
467 if (TD->getPointerSize() == sizeof(int32_t))
472 unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel);
473 if (TD->getPointerSize() == sizeof(int32_t))
474 MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
476 MCE->emitInt64(PadLabelPtr - (intptr_t)StartFunction);
478 // Asm->EOL("Landing pad");
480 MCE->emitULEB128Bytes(S.Action);
481 // Asm->EOL("Action");
485 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
486 ActionEntry &Action = Actions[I];
488 MCE->emitSLEB128Bytes(Action.ValueForTypeID);
489 //Asm->EOL("TypeInfo index");
490 MCE->emitSLEB128Bytes(Action.NextAction);
491 //Asm->EOL("Next action");
494 // Emit the type ids.
495 for (unsigned M = TypeInfos.size(); M; --M) {
496 GlobalVariable *GV = TypeInfos[M - 1];
499 if (TD->getPointerSize() == sizeof(int32_t)) {
500 MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
502 MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
505 if (TD->getPointerSize() == sizeof(int32_t))
510 // Asm->EOL("TypeInfo");
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");
520 MCE->emitAlignment(4);
522 return DwarfExceptionTable;
526 JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
527 unsigned PointerSize = TD->getPointerSize();
528 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
529 PointerSize : -PointerSize;
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));
543 MCE->emitULEB128Bytes(7);
545 if (needsIndirectEncoding)
546 MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
547 dwarf::DW_EH_PE_indirect);
549 MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
551 if (PointerSize == 8)
552 MCE->emitInt64((intptr_t)Jit.getPointerToGlobal(Personality) -
553 MCE->getCurrentPCValue());
555 MCE->emitInt32((intptr_t)Jit.getPointerToGlobal(Personality) -
556 MCE->getCurrentPCValue());
558 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
559 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
562 MCE->emitULEB128Bytes(1);
563 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
566 std::vector<MachineMove> Moves;
567 RI->getInitialFrameState(Moves);
568 EmitFrameMoves(0, Moves);
569 MCE->emitAlignment(4);
571 MCE->emitAt((uintptr_t*)StartCommonPtr,
572 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
573 FrameCommonBeginPtr));
575 return StartCommonPtr;
580 JITDwarfEmitter::EmitEHFrame(const Function* Personality,
581 unsigned char* StartCommonPtr,
582 unsigned char* StartFunction,
583 unsigned char* EndFunction,
584 unsigned char* ExceptionTable) const {
585 unsigned PointerSize = TD->getPointerSize();
588 unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue();
589 MCE->allocateSpace(PointerSize, 0);
590 unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
592 if (PointerSize == 8) {
593 MCE->emitInt64(FrameBeginPtr - StartCommonPtr);
594 MCE->emitInt64(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
595 MCE->emitInt64(EndFunction - StartFunction);
597 MCE->emitInt32(FrameBeginPtr - StartCommonPtr);
598 MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
599 MCE->emitInt32(EndFunction - StartFunction);
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);
607 if (!MMI->getLandingPads().empty()) {
608 if (PointerSize == 8)
609 MCE->emitInt64(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
611 MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
612 } else if (PointerSize == 8) {
613 MCE->emitInt64((int)0);
615 MCE->emitInt32((int)0);
618 MCE->emitULEB128Bytes(0);
621 // Indicate locations of function specific callee saved registers in
623 EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
625 MCE->emitAlignment(4);
627 // Indicate the size of the table
628 MCE->emitAt((uintptr_t*)StartEHPtr,
629 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
632 // Double zeroes for the unwind runtime
633 if (PointerSize == 8) {
645 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
646 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();
655 unsigned FinalSize = 0;
657 FinalSize += GetExceptionTableSizeInBytes(&F);
659 const std::vector<Function *> Personalities = MMI->getPersonalities();
660 FinalSize += GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
662 FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()], StartFunction);
667 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns
669 static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
670 if (Alignment == 0) Alignment = 1;
671 // Since we do not know where the buffer will be allocated, be pessimistic.
672 return FinalSize + Alignment;
676 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
677 unsigned char* StartFunction) const {
678 unsigned PointerSize = TD->getPointerSize();
679 unsigned FinalSize = 0;
681 FinalSize += PointerSize;
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()) {
687 FinalSize += AsmPrinter::SizeULEB128(4);
688 FinalSize += PointerSize;
690 FinalSize += AsmPrinter::SizeULEB128(0);
693 // Indicate locations of function specific callee saved registers in
695 FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
696 MMI->getFrameMoves());
698 FinalSize = RoundUpToAlign(FinalSize, 4);
700 // Double zeroes for the unwind runtime
701 FinalSize += 2 * PointerSize;
706 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality)
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;
717 FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
718 FinalSize += AsmPrinter::SizeULEB128(1);
719 FinalSize += AsmPrinter::SizeSLEB128(stackGrowth);
723 FinalSize += AsmPrinter::SizeULEB128(7);
728 FinalSize += PointerSize;
730 FinalSize += AsmPrinter::SizeULEB128(dwarf::DW_EH_PE_pcrel);
731 FinalSize += AsmPrinter::SizeULEB128(dwarf::DW_EH_PE_pcrel);
734 FinalSize += AsmPrinter::SizeULEB128(1);
735 FinalSize += AsmPrinter::SizeULEB128(dwarf::DW_EH_PE_pcrel);
738 std::vector<MachineMove> Moves;
739 RI->getInitialFrameState(Moves);
740 FinalSize += GetFrameMovesSizeInBytes(0, Moves);
741 FinalSize = RoundUpToAlign(FinalSize, 4);
746 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
747 const std::vector<MachineMove> &Moves) const {
748 unsigned PointerSize = TD->getPointerSize();
749 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
750 PointerSize : -PointerSize;
751 bool IsLocal = BaseLabelPtr;
752 unsigned FinalSize = 0;
754 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
755 const MachineMove &Move = Moves[i];
756 unsigned LabelID = Move.getLabelID();
759 LabelID = MMI->MappedLabel(LabelID);
761 // Throw out move if the label is invalid.
762 if (!LabelID) continue;
765 intptr_t LabelPtr = 0;
766 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
768 const MachineLocation &Dst = Move.getDestination();
769 const MachineLocation &Src = Move.getSource();
771 // Advance row if new location.
772 if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
774 FinalSize += PointerSize;
775 BaseLabelPtr = LabelPtr;
780 if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
781 if (!Src.isRegister()) {
782 if (Src.getRegister() == MachineLocation::VirtualFP) {
786 unsigned RegNum = RI->getDwarfRegNum(Src.getRegister(), true);
787 FinalSize += AsmPrinter::SizeULEB128(RegNum);
790 int Offset = -Src.getOffset();
792 FinalSize += AsmPrinter::SizeULEB128(Offset);
794 assert(0 && "Machine move no supported yet.");
796 } else if (Src.isRegister() &&
797 Src.getRegister() == MachineLocation::VirtualFP) {
798 if (Dst.isRegister()) {
800 unsigned RegNum = RI->getDwarfRegNum(Dst.getRegister(), true);
801 FinalSize += AsmPrinter::SizeULEB128(RegNum);
803 assert(0 && "Machine move no supported yet.");
806 unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
807 int Offset = Dst.getOffset() / stackGrowth;
811 FinalSize += AsmPrinter::SizeULEB128(Reg);
812 FinalSize += AsmPrinter::SizeSLEB128(Offset);
813 } else if (Reg < 64) {
815 FinalSize += AsmPrinter::SizeULEB128(Offset);
818 FinalSize += AsmPrinter::SizeULEB128(Reg);
819 FinalSize += AsmPrinter::SizeULEB128(Offset);
827 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
828 unsigned FinalSize = 0;
830 // Map all labels and get rid of any dead landing pads.
831 MMI->TidyLandingPads();
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;
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);
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());
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);
865 // Compute the actions table and gather the first action index for each
867 SmallVector<ActionEntry, 32> Actions;
868 SmallVector<unsigned, 64> FirstActions;
869 FirstActions.reserve(LandingPads.size());
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;
879 if (NumShared < TypeIds.size()) {
880 unsigned SizeAction = 0;
881 ActionEntry *PrevAction = 0;
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;
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);
903 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
904 SizeAction = SizeTypeID + AsmPrinter::SizeSLEB128(NextAction);
905 SizeSiteActions += SizeAction;
907 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
908 Actions.push_back(Action);
910 PrevAction = &Actions.back();
913 // Record the first action of the landing pad site.
914 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
915 } // else identical - re-use previous FirstAction
917 FirstActions.push_back(FirstAction);
919 // Compute this sites contribution to size.
920 SizeActions += SizeSiteActions;
923 // Compute the call-site table. Entries must be ordered by address.
924 SmallVector<CallSiteEntry, 64> CallSites;
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;
937 bool MayThrow = false;
938 unsigned LastLabel = 0;
939 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
941 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
943 if (MI->getOpcode() != TargetInstrInfo::LABEL) {
944 MayThrow |= MI->getDesc().isCall();
948 unsigned BeginLabel = MI->getOperand(0).getImm();
949 assert(BeginLabel && "Invalid label!");
951 if (BeginLabel == LastLabel)
954 RangeMapType::iterator L = PadMap.find(BeginLabel);
956 if (L == PadMap.end())
959 PadRange P = L->second;
960 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
962 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
963 "Inconsistent landing pad map!");
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.
969 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
970 CallSites.push_back(Site);
973 LastLabel = LandingPad->EndLabels[P.RangeIndex];
974 CallSiteEntry Site = {BeginLabel, LastLabel,
975 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
977 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
978 "Invalid landing pad!");
980 // Try to merge with the previous call-site.
981 if (CallSites.size()) {
982 CallSiteEntry &Prev = CallSites.back();
983 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
984 // Extend the range of the previous entry.
985 Prev.EndLabel = Site.EndLabel;
990 // Otherwise, create a new call-site.
991 CallSites.push_back(Site);
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.
998 CallSiteEntry Site = {LastLabel, 0, 0, 0};
999 CallSites.push_back(Site);
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);
1009 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
1011 unsigned TypeOffset = sizeof(int8_t) + // Call site format
1012 // Call-site table length
1013 AsmPrinter::SizeULEB128(SizeSites) +
1014 SizeSites + SizeActions + SizeTypes;
1016 unsigned TotalSize = sizeof(int8_t) + // LPStart format
1017 sizeof(int8_t) + // TType format
1018 AsmPrinter::SizeULEB128(TypeOffset) + // TType base offset
1021 unsigned SizeAlign = (4 - TotalSize) & 3;
1023 // Begin the exception table.
1024 FinalSize = RoundUpToAlign(FinalSize, 4);
1025 for (unsigned i = 0; i != SizeAlign; ++i) {
1029 unsigned PointerSize = TD->getPointerSize();
1033 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
1035 // Asm->EOL("TType format (DW_EH_PE_absptr)");
1037 // Asm->EOL("TType base offset");
1039 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1041 // Asm->EOL("Call-site table length");
1043 // Emit the landing pad site information.
1044 for (unsigned i = 0; i < CallSites.size(); ++i) {
1045 CallSiteEntry &S = CallSites[i];
1047 // Asm->EOL("Region start");
1048 FinalSize += PointerSize;
1050 //Asm->EOL("Region length");
1051 FinalSize += PointerSize;
1053 // Asm->EOL("Landing pad");
1054 FinalSize += PointerSize;
1056 FinalSize += AsmPrinter::SizeULEB128(S.Action);
1057 // Asm->EOL("Action");
1060 // Emit the actions.
1061 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
1062 ActionEntry &Action = Actions[I];
1064 //Asm->EOL("TypeInfo index");
1065 FinalSize += AsmPrinter::SizeSLEB128(Action.ValueForTypeID);
1066 //Asm->EOL("Next action");
1067 FinalSize += AsmPrinter::SizeSLEB128(Action.NextAction);
1070 // Emit the type ids.
1071 for (unsigned M = TypeInfos.size(); M; --M) {
1072 // Asm->EOL("TypeInfo");
1073 FinalSize += PointerSize;
1076 // Emit the filter typeids.
1077 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
1078 unsigned TypeID = FilterIds[j];
1079 FinalSize += AsmPrinter::SizeULEB128(TypeID);
1080 //Asm->EOL("Filter TypeInfo index");
1083 FinalSize = RoundUpToAlign(FinalSize, 4);