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/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"
33 JITDwarfEmitter::JITDwarfEmitter(JIT
& theJit
) : Jit(theJit
) {}
36 unsigned 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();
47 unsigned char* ExceptionTable
= EmitExceptionTable(&F
, StartFunction
,
50 unsigned char* Result
= 0;
51 unsigned char* EHFramePtr
= 0;
53 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
54 EHFramePtr
= EmitCommonEHFrame(Personalities
[MMI
->getPersonalityIndex()]);
56 Result
= EmitEHFrame(Personalities
[MMI
->getPersonalityIndex()], EHFramePtr
,
57 StartFunction
, EndFunction
, ExceptionTable
);
64 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr
,
65 const std::vector
<MachineMove
> &Moves
) const {
66 unsigned PointerSize
= TD
->getPointerSize();
67 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
68 PointerSize
: -PointerSize
;
70 unsigned BaseLabelID
= 0;
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
&& (BaseLabelID
!= LabelID
|| !IsLocal
)) {
91 MCE
->emitByte(dwarf::DW_CFA_advance_loc4
);
92 MCE
->emitInt32(LabelPtr
- BaseLabelPtr
);
94 BaseLabelID
= LabelID
;
95 BaseLabelPtr
= LabelPtr
;
100 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
102 if (Src
.getReg() == MachineLocation::VirtualFP
) {
103 MCE
->emitByte(dwarf::DW_CFA_def_cfa_offset
);
105 MCE
->emitByte(dwarf::DW_CFA_def_cfa
);
106 MCE
->emitULEB128Bytes(RI
->getDwarfRegNum(Src
.getReg(), true));
109 int Offset
= -Src
.getOffset();
111 MCE
->emitULEB128Bytes(Offset
);
113 assert(0 && "Machine move no supported yet.");
115 } else if (Src
.isReg() &&
116 Src
.getReg() == MachineLocation::VirtualFP
) {
118 MCE
->emitByte(dwarf::DW_CFA_def_cfa_register
);
119 MCE
->emitULEB128Bytes(RI
->getDwarfRegNum(Dst
.getReg(), true));
121 assert(0 && "Machine move no supported yet.");
124 unsigned Reg
= RI
->getDwarfRegNum(Src
.getReg(), true);
125 int Offset
= Dst
.getOffset() / stackGrowth
;
128 MCE
->emitByte(dwarf::DW_CFA_offset_extended_sf
);
129 MCE
->emitULEB128Bytes(Reg
);
130 MCE
->emitSLEB128Bytes(Offset
);
131 } else if (Reg
< 64) {
132 MCE
->emitByte(dwarf::DW_CFA_offset
+ Reg
);
133 MCE
->emitULEB128Bytes(Offset
);
135 MCE
->emitByte(dwarf::DW_CFA_offset_extended
);
136 MCE
->emitULEB128Bytes(Reg
);
137 MCE
->emitULEB128Bytes(Offset
);
143 /// SharedTypeIds - How many leading type ids two landing pads have in common.
144 static unsigned SharedTypeIds(const LandingPadInfo
*L
,
145 const LandingPadInfo
*R
) {
146 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
147 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
148 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
151 for (; Count
!= MinSize
; ++Count
)
152 if (LIds
[Count
] != RIds
[Count
])
159 /// PadLT - Order landing pads lexicographically by type id.
160 static bool PadLT(const LandingPadInfo
*L
, const LandingPadInfo
*R
) {
161 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
162 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
163 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
165 for (unsigned i
= 0; i
!= MinSize
; ++i
)
166 if (LIds
[i
] != RIds
[i
])
167 return LIds
[i
] < RIds
[i
];
169 return LSize
< RSize
;
175 static inline unsigned getEmptyKey() { return -1U; }
176 static inline unsigned getTombstoneKey() { return -2U; }
177 static unsigned getHashValue(const unsigned &Key
) { return Key
; }
178 static bool isEqual(unsigned LHS
, unsigned RHS
) { return LHS
== RHS
; }
179 static bool isPod() { return true; }
182 /// ActionEntry - Structure describing an entry in the actions table.
184 int ValueForTypeID
; // The value to write - may not be equal to the type id.
186 struct ActionEntry
*Previous
;
189 /// PadRange - Structure holding a try-range and the associated landing pad.
191 // The index of the landing pad.
193 // The index of the begin and end labels in the landing pad's label lists.
197 typedef DenseMap
<unsigned, PadRange
, KeyInfo
> RangeMapType
;
199 /// CallSiteEntry - Structure describing an entry in the call-site table.
200 struct CallSiteEntry
{
201 unsigned BeginLabel
; // zero indicates the start of the function.
202 unsigned EndLabel
; // zero indicates the end of the function.
203 unsigned PadLabel
; // zero indicates that there is no landing pad.
209 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction
* MF
,
210 unsigned char* StartFunction
,
211 unsigned char* EndFunction
) const {
212 // Map all labels and get rid of any dead landing pads.
213 MMI
->TidyLandingPads();
215 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
216 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
217 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
218 if (PadInfos
.empty()) return 0;
220 // Sort the landing pads in order of their type ids. This is used to fold
221 // duplicate actions.
222 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
223 LandingPads
.reserve(PadInfos
.size());
224 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
225 LandingPads
.push_back(&PadInfos
[i
]);
226 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
228 // Negative type ids index into FilterIds, positive type ids index into
229 // TypeInfos. The value written for a positive type id is just the type
230 // id itself. For a negative type id, however, the value written is the
231 // (negative) byte offset of the corresponding FilterIds entry. The byte
232 // offset is usually equal to the type id, because the FilterIds entries
233 // are written using a variable width encoding which outputs one byte per
234 // entry as long as the value written is not too large, but can differ.
235 // This kind of complication does not occur for positive type ids because
236 // type infos are output using a fixed width encoding.
237 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
238 SmallVector
<int, 16> FilterOffsets
;
239 FilterOffsets
.reserve(FilterIds
.size());
241 for(std::vector
<unsigned>::const_iterator I
= FilterIds
.begin(),
242 E
= FilterIds
.end(); I
!= E
; ++I
) {
243 FilterOffsets
.push_back(Offset
);
244 Offset
-= TargetAsmInfo::getULEB128Size(*I
);
247 // Compute the actions table and gather the first action index for each
249 SmallVector
<ActionEntry
, 32> Actions
;
250 SmallVector
<unsigned, 64> FirstActions
;
251 FirstActions
.reserve(LandingPads
.size());
254 unsigned SizeActions
= 0;
255 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
256 const LandingPadInfo
*LP
= LandingPads
[i
];
257 const std::vector
<int> &TypeIds
= LP
->TypeIds
;
258 const unsigned NumShared
= i
? SharedTypeIds(LP
, LandingPads
[i
-1]) : 0;
259 unsigned SizeSiteActions
= 0;
261 if (NumShared
< TypeIds
.size()) {
262 unsigned SizeAction
= 0;
263 ActionEntry
*PrevAction
= 0;
266 const unsigned SizePrevIds
= LandingPads
[i
-1]->TypeIds
.size();
267 assert(Actions
.size());
268 PrevAction
= &Actions
.back();
269 SizeAction
= TargetAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
270 TargetAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
271 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
272 SizeAction
-= TargetAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
273 SizeAction
+= -PrevAction
->NextAction
;
274 PrevAction
= PrevAction
->Previous
;
278 // Compute the actions.
279 for (unsigned I
= NumShared
, M
= TypeIds
.size(); I
!= M
; ++I
) {
280 int TypeID
= TypeIds
[I
];
281 assert(-1-TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
282 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
283 unsigned SizeTypeID
= TargetAsmInfo::getSLEB128Size(ValueForTypeID
);
285 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
286 SizeAction
= SizeTypeID
+ TargetAsmInfo::getSLEB128Size(NextAction
);
287 SizeSiteActions
+= SizeAction
;
289 ActionEntry Action
= {ValueForTypeID
, NextAction
, PrevAction
};
290 Actions
.push_back(Action
);
292 PrevAction
= &Actions
.back();
295 // Record the first action of the landing pad site.
296 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
297 } // else identical - re-use previous FirstAction
299 FirstActions
.push_back(FirstAction
);
301 // Compute this sites contribution to size.
302 SizeActions
+= SizeSiteActions
;
305 // Compute the call-site table. Entries must be ordered by address.
306 SmallVector
<CallSiteEntry
, 64> CallSites
;
309 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
310 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
311 for (unsigned j
=0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
312 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
313 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
314 PadRange P
= { i
, j
};
315 PadMap
[BeginLabel
] = P
;
319 bool MayThrow
= false;
320 unsigned LastLabel
= 0;
321 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
323 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
325 if (!MI
->isLabel()) {
326 MayThrow
|= MI
->getDesc().isCall();
330 unsigned BeginLabel
= MI
->getOperand(0).getImm();
331 assert(BeginLabel
&& "Invalid label!");
333 if (BeginLabel
== LastLabel
)
336 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
338 if (L
== PadMap
.end())
341 PadRange P
= L
->second
;
342 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
344 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
345 "Inconsistent landing pad map!");
347 // If some instruction between the previous try-range and this one may
348 // throw, create a call-site entry with no landing pad for the region
349 // between the try-ranges.
351 CallSiteEntry Site
= {LastLabel
, BeginLabel
, 0, 0};
352 CallSites
.push_back(Site
);
355 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
356 CallSiteEntry Site
= {BeginLabel
, LastLabel
,
357 LandingPad
->LandingPadLabel
, FirstActions
[P
.PadIndex
]};
359 assert(Site
.BeginLabel
&& Site
.EndLabel
&& Site
.PadLabel
&&
360 "Invalid landing pad!");
362 // Try to merge with the previous call-site.
363 if (CallSites
.size()) {
364 CallSiteEntry
&Prev
= CallSites
.back();
365 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
366 // Extend the range of the previous entry.
367 Prev
.EndLabel
= Site
.EndLabel
;
372 // Otherwise, create a new call-site.
373 CallSites
.push_back(Site
);
376 // If some instruction between the previous try-range and the end of the
377 // function may throw, create a call-site entry with no landing pad for the
378 // region following the try-range.
380 CallSiteEntry Site
= {LastLabel
, 0, 0, 0};
381 CallSites
.push_back(Site
);
385 unsigned SizeSites
= CallSites
.size() * (sizeof(int32_t) + // Site start.
386 sizeof(int32_t) + // Site length.
387 sizeof(int32_t)); // Landing pad.
388 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
)
389 SizeSites
+= TargetAsmInfo::getULEB128Size(CallSites
[i
].Action
);
391 unsigned SizeTypes
= TypeInfos
.size() * TD
->getPointerSize();
393 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
394 // Call-site table length
395 TargetAsmInfo::getULEB128Size(SizeSites
) +
396 SizeSites
+ SizeActions
+ SizeTypes
;
398 unsigned TotalSize
= sizeof(int8_t) + // LPStart format
399 sizeof(int8_t) + // TType format
400 TargetAsmInfo::getULEB128Size(TypeOffset
) + // TType base offset
403 unsigned SizeAlign
= (4 - TotalSize
) & 3;
405 // Begin the exception table.
406 MCE
->emitAlignment(4);
407 for (unsigned i
= 0; i
!= SizeAlign
; ++i
) {
409 // Asm->EOL("Padding");
412 unsigned char* DwarfExceptionTable
= (unsigned char*)MCE
->getCurrentPCValue();
415 MCE
->emitByte(dwarf::DW_EH_PE_omit
);
416 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
417 MCE
->emitByte(dwarf::DW_EH_PE_absptr
);
418 // Asm->EOL("TType format (DW_EH_PE_absptr)");
419 MCE
->emitULEB128Bytes(TypeOffset
);
420 // Asm->EOL("TType base offset");
421 MCE
->emitByte(dwarf::DW_EH_PE_udata4
);
422 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
423 MCE
->emitULEB128Bytes(SizeSites
);
424 // Asm->EOL("Call-site table length");
426 // Emit the landing pad site information.
427 for (unsigned i
= 0; i
< CallSites
.size(); ++i
) {
428 CallSiteEntry
&S
= CallSites
[i
];
429 intptr_t BeginLabelPtr
= 0;
430 intptr_t EndLabelPtr
= 0;
433 BeginLabelPtr
= (intptr_t)StartFunction
;
436 BeginLabelPtr
= MCE
->getLabelAddress(S
.BeginLabel
);
437 MCE
->emitInt32(BeginLabelPtr
- (intptr_t)StartFunction
);
440 // Asm->EOL("Region start");
443 EndLabelPtr
= (intptr_t)EndFunction
;
444 MCE
->emitInt32((intptr_t)EndFunction
- BeginLabelPtr
);
446 EndLabelPtr
= MCE
->getLabelAddress(S
.EndLabel
);
447 MCE
->emitInt32(EndLabelPtr
- BeginLabelPtr
);
449 //Asm->EOL("Region length");
454 unsigned PadLabelPtr
= MCE
->getLabelAddress(S
.PadLabel
);
455 MCE
->emitInt32(PadLabelPtr
- (intptr_t)StartFunction
);
457 // Asm->EOL("Landing pad");
459 MCE
->emitULEB128Bytes(S
.Action
);
460 // Asm->EOL("Action");
464 for (unsigned I
= 0, N
= Actions
.size(); I
!= N
; ++I
) {
465 ActionEntry
&Action
= Actions
[I
];
467 MCE
->emitSLEB128Bytes(Action
.ValueForTypeID
);
468 //Asm->EOL("TypeInfo index");
469 MCE
->emitSLEB128Bytes(Action
.NextAction
);
470 //Asm->EOL("Next action");
473 // Emit the type ids.
474 for (unsigned M
= TypeInfos
.size(); M
; --M
) {
475 GlobalVariable
*GV
= TypeInfos
[M
- 1];
478 if (TD
->getPointerSize() == sizeof(int32_t)) {
479 MCE
->emitInt32((intptr_t)Jit
.getOrEmitGlobalVariable(GV
));
481 MCE
->emitInt64((intptr_t)Jit
.getOrEmitGlobalVariable(GV
));
484 if (TD
->getPointerSize() == sizeof(int32_t))
489 // Asm->EOL("TypeInfo");
492 // Emit the filter typeids.
493 for (unsigned j
= 0, M
= FilterIds
.size(); j
< M
; ++j
) {
494 unsigned TypeID
= FilterIds
[j
];
495 MCE
->emitULEB128Bytes(TypeID
);
496 //Asm->EOL("Filter TypeInfo index");
499 MCE
->emitAlignment(4);
501 return DwarfExceptionTable
;
505 JITDwarfEmitter::EmitCommonEHFrame(const Function
* Personality
) const {
506 unsigned PointerSize
= TD
->getPointerSize();
507 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
508 PointerSize
: -PointerSize
;
510 unsigned char* StartCommonPtr
= (unsigned char*)MCE
->getCurrentPCValue();
511 // EH Common Frame header
512 MCE
->allocateSpace(4, 0);
513 unsigned char* FrameCommonBeginPtr
= (unsigned char*)MCE
->getCurrentPCValue();
514 MCE
->emitInt32((int)0);
515 MCE
->emitByte(dwarf::DW_CIE_VERSION
);
516 MCE
->emitString(Personality
? "zPLR" : "zR");
517 MCE
->emitULEB128Bytes(1);
518 MCE
->emitSLEB128Bytes(stackGrowth
);
519 MCE
->emitByte(RI
->getDwarfRegNum(RI
->getRARegister(), true));
522 // Augmentation Size: 3 small ULEBs of one byte each, and the personality
523 // function which size is PointerSize.
524 MCE
->emitULEB128Bytes(3 + PointerSize
);
526 // We set the encoding of the personality as direct encoding because we use
527 // the function pointer. The encoding is not relative because the current
528 // PC value may be bigger than the personality function pointer.
529 if (PointerSize
== 4) {
530 MCE
->emitByte(dwarf::DW_EH_PE_sdata4
);
531 MCE
->emitInt32(((intptr_t)Jit
.getPointerToGlobal(Personality
)));
533 MCE
->emitByte(dwarf::DW_EH_PE_sdata8
);
534 MCE
->emitInt64(((intptr_t)Jit
.getPointerToGlobal(Personality
)));
537 MCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
538 MCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
541 MCE
->emitULEB128Bytes(1);
542 MCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
545 std::vector
<MachineMove
> Moves
;
546 RI
->getInitialFrameState(Moves
);
547 EmitFrameMoves(0, Moves
);
548 MCE
->emitAlignment(PointerSize
);
550 MCE
->emitInt32At((uintptr_t*)StartCommonPtr
,
551 (uintptr_t)((unsigned char*)MCE
->getCurrentPCValue() -
552 FrameCommonBeginPtr
));
554 return StartCommonPtr
;
559 JITDwarfEmitter::EmitEHFrame(const Function
* Personality
,
560 unsigned char* StartCommonPtr
,
561 unsigned char* StartFunction
,
562 unsigned char* EndFunction
,
563 unsigned char* ExceptionTable
) const {
564 unsigned PointerSize
= TD
->getPointerSize();
567 unsigned char* StartEHPtr
= (unsigned char*)MCE
->getCurrentPCValue();
568 MCE
->allocateSpace(4, 0);
569 unsigned char* FrameBeginPtr
= (unsigned char*)MCE
->getCurrentPCValue();
571 MCE
->emitInt32(FrameBeginPtr
- StartCommonPtr
);
572 MCE
->emitInt32(StartFunction
- (unsigned char*)MCE
->getCurrentPCValue());
573 MCE
->emitInt32(EndFunction
- StartFunction
);
575 // If there is a personality and landing pads then point to the language
576 // specific data area in the exception table.
577 if (MMI
->getPersonalityIndex()) {
578 MCE
->emitULEB128Bytes(4);
580 if (!MMI
->getLandingPads().empty()) {
581 MCE
->emitInt32(ExceptionTable
- (unsigned char*)MCE
->getCurrentPCValue());
583 MCE
->emitInt32((int)0);
586 MCE
->emitULEB128Bytes(0);
589 // Indicate locations of function specific callee saved registers in
591 EmitFrameMoves((intptr_t)StartFunction
, MMI
->getFrameMoves());
593 MCE
->emitAlignment(PointerSize
);
595 // Indicate the size of the table
596 MCE
->emitInt32At((uintptr_t*)StartEHPtr
,
597 (uintptr_t)((unsigned char*)MCE
->getCurrentPCValue() -
600 // Double zeroes for the unwind runtime
601 if (PointerSize
== 8) {
613 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction
& F
,
614 MachineCodeEmitter
& mce
,
615 unsigned char* StartFunction
,
616 unsigned char* EndFunction
) {
617 const TargetMachine
& TM
= F
.getTarget();
618 TD
= TM
.getTargetData();
619 needsIndirectEncoding
= TM
.getTargetAsmInfo()->getNeedsIndirectEncoding();
620 stackGrowthDirection
= TM
.getFrameInfo()->getStackGrowthDirection();
621 RI
= TM
.getRegisterInfo();
623 unsigned FinalSize
= 0;
625 FinalSize
+= GetExceptionTableSizeInBytes(&F
);
627 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
629 GetCommonEHFrameSizeInBytes(Personalities
[MMI
->getPersonalityIndex()]);
631 FinalSize
+= GetEHFrameSizeInBytes(Personalities
[MMI
->getPersonalityIndex()],
637 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns
639 static unsigned RoundUpToAlign(unsigned FinalSize
, unsigned Alignment
) {
640 if (Alignment
== 0) Alignment
= 1;
641 // Since we do not know where the buffer will be allocated, be pessimistic.
642 return FinalSize
+ Alignment
;
646 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function
* Personality
,
647 unsigned char* StartFunction
) const {
648 unsigned PointerSize
= TD
->getPointerSize();
649 unsigned FinalSize
= 0;
651 FinalSize
+= PointerSize
;
653 FinalSize
+= 3 * PointerSize
;
654 // If there is a personality and landing pads then point to the language
655 // specific data area in the exception table.
656 if (MMI
->getPersonalityIndex()) {
657 FinalSize
+= TargetAsmInfo::getULEB128Size(4);
658 FinalSize
+= PointerSize
;
660 FinalSize
+= TargetAsmInfo::getULEB128Size(0);
663 // Indicate locations of function specific callee saved registers in
665 FinalSize
+= GetFrameMovesSizeInBytes((intptr_t)StartFunction
,
666 MMI
->getFrameMoves());
668 FinalSize
= RoundUpToAlign(FinalSize
, 4);
670 // Double zeroes for the unwind runtime
671 FinalSize
+= 2 * PointerSize
;
676 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function
* Personality
)
679 unsigned PointerSize
= TD
->getPointerSize();
680 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
681 PointerSize
: -PointerSize
;
682 unsigned FinalSize
= 0;
683 // EH Common Frame header
684 FinalSize
+= PointerSize
;
687 FinalSize
+= Personality
? 5 : 3; // "zPLR" or "zR"
688 FinalSize
+= TargetAsmInfo::getULEB128Size(1);
689 FinalSize
+= TargetAsmInfo::getSLEB128Size(stackGrowth
);
693 FinalSize
+= TargetAsmInfo::getULEB128Size(7);
698 FinalSize
+= PointerSize
;
700 FinalSize
+= TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel
);
701 FinalSize
+= TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel
);
704 FinalSize
+= TargetAsmInfo::getULEB128Size(1);
705 FinalSize
+= TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel
);
708 std::vector
<MachineMove
> Moves
;
709 RI
->getInitialFrameState(Moves
);
710 FinalSize
+= GetFrameMovesSizeInBytes(0, Moves
);
711 FinalSize
= RoundUpToAlign(FinalSize
, 4);
716 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr
,
717 const std::vector
<MachineMove
> &Moves
) const {
718 unsigned PointerSize
= TD
->getPointerSize();
719 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
720 PointerSize
: -PointerSize
;
721 bool IsLocal
= BaseLabelPtr
;
722 unsigned FinalSize
= 0;
724 for (unsigned i
= 0, N
= Moves
.size(); i
< N
; ++i
) {
725 const MachineMove
&Move
= Moves
[i
];
726 unsigned LabelID
= Move
.getLabelID();
729 LabelID
= MMI
->MappedLabel(LabelID
);
731 // Throw out move if the label is invalid.
732 if (!LabelID
) continue;
735 intptr_t LabelPtr
= 0;
736 if (LabelID
) LabelPtr
= MCE
->getLabelAddress(LabelID
);
738 const MachineLocation
&Dst
= Move
.getDestination();
739 const MachineLocation
&Src
= Move
.getSource();
741 // Advance row if new location.
742 if (BaseLabelPtr
&& LabelID
&& (BaseLabelPtr
!= LabelPtr
|| !IsLocal
)) {
744 FinalSize
+= PointerSize
;
745 BaseLabelPtr
= LabelPtr
;
750 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
752 if (Src
.getReg() == MachineLocation::VirtualFP
) {
756 unsigned RegNum
= RI
->getDwarfRegNum(Src
.getReg(), true);
757 FinalSize
+= TargetAsmInfo::getULEB128Size(RegNum
);
760 int Offset
= -Src
.getOffset();
762 FinalSize
+= TargetAsmInfo::getULEB128Size(Offset
);
764 assert(0 && "Machine move no supported yet.");
766 } else if (Src
.isReg() &&
767 Src
.getReg() == MachineLocation::VirtualFP
) {
770 unsigned RegNum
= RI
->getDwarfRegNum(Dst
.getReg(), true);
771 FinalSize
+= TargetAsmInfo::getULEB128Size(RegNum
);
773 assert(0 && "Machine move no supported yet.");
776 unsigned Reg
= RI
->getDwarfRegNum(Src
.getReg(), true);
777 int Offset
= Dst
.getOffset() / stackGrowth
;
781 FinalSize
+= TargetAsmInfo::getULEB128Size(Reg
);
782 FinalSize
+= TargetAsmInfo::getSLEB128Size(Offset
);
783 } else if (Reg
< 64) {
785 FinalSize
+= TargetAsmInfo::getULEB128Size(Offset
);
788 FinalSize
+= TargetAsmInfo::getULEB128Size(Reg
);
789 FinalSize
+= TargetAsmInfo::getULEB128Size(Offset
);
797 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction
* MF
) const {
798 unsigned FinalSize
= 0;
800 // Map all labels and get rid of any dead landing pads.
801 MMI
->TidyLandingPads();
803 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
804 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
805 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
806 if (PadInfos
.empty()) return 0;
808 // Sort the landing pads in order of their type ids. This is used to fold
809 // duplicate actions.
810 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
811 LandingPads
.reserve(PadInfos
.size());
812 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
813 LandingPads
.push_back(&PadInfos
[i
]);
814 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
816 // Negative type ids index into FilterIds, positive type ids index into
817 // TypeInfos. The value written for a positive type id is just the type
818 // id itself. For a negative type id, however, the value written is the
819 // (negative) byte offset of the corresponding FilterIds entry. The byte
820 // offset is usually equal to the type id, because the FilterIds entries
821 // are written using a variable width encoding which outputs one byte per
822 // entry as long as the value written is not too large, but can differ.
823 // This kind of complication does not occur for positive type ids because
824 // type infos are output using a fixed width encoding.
825 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
826 SmallVector
<int, 16> FilterOffsets
;
827 FilterOffsets
.reserve(FilterIds
.size());
829 for(std::vector
<unsigned>::const_iterator I
= FilterIds
.begin(),
830 E
= FilterIds
.end(); I
!= E
; ++I
) {
831 FilterOffsets
.push_back(Offset
);
832 Offset
-= TargetAsmInfo::getULEB128Size(*I
);
835 // Compute the actions table and gather the first action index for each
837 SmallVector
<ActionEntry
, 32> Actions
;
838 SmallVector
<unsigned, 64> FirstActions
;
839 FirstActions
.reserve(LandingPads
.size());
842 unsigned SizeActions
= 0;
843 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
844 const LandingPadInfo
*LP
= LandingPads
[i
];
845 const std::vector
<int> &TypeIds
= LP
->TypeIds
;
846 const unsigned NumShared
= i
? SharedTypeIds(LP
, LandingPads
[i
-1]) : 0;
847 unsigned SizeSiteActions
= 0;
849 if (NumShared
< TypeIds
.size()) {
850 unsigned SizeAction
= 0;
851 ActionEntry
*PrevAction
= 0;
854 const unsigned SizePrevIds
= LandingPads
[i
-1]->TypeIds
.size();
855 assert(Actions
.size());
856 PrevAction
= &Actions
.back();
857 SizeAction
= TargetAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
858 TargetAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
859 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
860 SizeAction
-= TargetAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
861 SizeAction
+= -PrevAction
->NextAction
;
862 PrevAction
= PrevAction
->Previous
;
866 // Compute the actions.
867 for (unsigned I
= NumShared
, M
= TypeIds
.size(); I
!= M
; ++I
) {
868 int TypeID
= TypeIds
[I
];
869 assert(-1-TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
870 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
871 unsigned SizeTypeID
= TargetAsmInfo::getSLEB128Size(ValueForTypeID
);
873 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
874 SizeAction
= SizeTypeID
+ TargetAsmInfo::getSLEB128Size(NextAction
);
875 SizeSiteActions
+= SizeAction
;
877 ActionEntry Action
= {ValueForTypeID
, NextAction
, PrevAction
};
878 Actions
.push_back(Action
);
880 PrevAction
= &Actions
.back();
883 // Record the first action of the landing pad site.
884 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
885 } // else identical - re-use previous FirstAction
887 FirstActions
.push_back(FirstAction
);
889 // Compute this sites contribution to size.
890 SizeActions
+= SizeSiteActions
;
893 // Compute the call-site table. Entries must be ordered by address.
894 SmallVector
<CallSiteEntry
, 64> CallSites
;
897 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
898 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
899 for (unsigned j
=0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
900 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
901 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
902 PadRange P
= { i
, j
};
903 PadMap
[BeginLabel
] = P
;
907 bool MayThrow
= false;
908 unsigned LastLabel
= 0;
909 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
911 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
913 if (!MI
->isLabel()) {
914 MayThrow
|= MI
->getDesc().isCall();
918 unsigned BeginLabel
= MI
->getOperand(0).getImm();
919 assert(BeginLabel
&& "Invalid label!");
921 if (BeginLabel
== LastLabel
)
924 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
926 if (L
== PadMap
.end())
929 PadRange P
= L
->second
;
930 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
932 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
933 "Inconsistent landing pad map!");
935 // If some instruction between the previous try-range and this one may
936 // throw, create a call-site entry with no landing pad for the region
937 // between the try-ranges.
939 CallSiteEntry Site
= {LastLabel
, BeginLabel
, 0, 0};
940 CallSites
.push_back(Site
);
943 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
944 CallSiteEntry Site
= {BeginLabel
, LastLabel
,
945 LandingPad
->LandingPadLabel
, FirstActions
[P
.PadIndex
]};
947 assert(Site
.BeginLabel
&& Site
.EndLabel
&& Site
.PadLabel
&&
948 "Invalid landing pad!");
950 // Try to merge with the previous call-site.
951 if (CallSites
.size()) {
952 CallSiteEntry
&Prev
= CallSites
.back();
953 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
954 // Extend the range of the previous entry.
955 Prev
.EndLabel
= Site
.EndLabel
;
960 // Otherwise, create a new call-site.
961 CallSites
.push_back(Site
);
964 // If some instruction between the previous try-range and the end of the
965 // function may throw, create a call-site entry with no landing pad for the
966 // region following the try-range.
968 CallSiteEntry Site
= {LastLabel
, 0, 0, 0};
969 CallSites
.push_back(Site
);
973 unsigned SizeSites
= CallSites
.size() * (sizeof(int32_t) + // Site start.
974 sizeof(int32_t) + // Site length.
975 sizeof(int32_t)); // Landing pad.
976 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
)
977 SizeSites
+= TargetAsmInfo::getULEB128Size(CallSites
[i
].Action
);
979 unsigned SizeTypes
= TypeInfos
.size() * TD
->getPointerSize();
981 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
982 // Call-site table length
983 TargetAsmInfo::getULEB128Size(SizeSites
) +
984 SizeSites
+ SizeActions
+ SizeTypes
;
986 unsigned TotalSize
= sizeof(int8_t) + // LPStart format
987 sizeof(int8_t) + // TType format
988 TargetAsmInfo::getULEB128Size(TypeOffset
) + // TType base offset
991 unsigned SizeAlign
= (4 - TotalSize
) & 3;
993 // Begin the exception table.
994 FinalSize
= RoundUpToAlign(FinalSize
, 4);
995 for (unsigned i
= 0; i
!= SizeAlign
; ++i
) {
999 unsigned PointerSize
= TD
->getPointerSize();
1003 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
1005 // Asm->EOL("TType format (DW_EH_PE_absptr)");
1007 // Asm->EOL("TType base offset");
1009 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1011 // Asm->EOL("Call-site table length");
1013 // Emit the landing pad site information.
1014 for (unsigned i
= 0; i
< CallSites
.size(); ++i
) {
1015 CallSiteEntry
&S
= CallSites
[i
];
1017 // Asm->EOL("Region start");
1018 FinalSize
+= PointerSize
;
1020 //Asm->EOL("Region length");
1021 FinalSize
+= PointerSize
;
1023 // Asm->EOL("Landing pad");
1024 FinalSize
+= PointerSize
;
1026 FinalSize
+= TargetAsmInfo::getULEB128Size(S
.Action
);
1027 // Asm->EOL("Action");
1030 // Emit the actions.
1031 for (unsigned I
= 0, N
= Actions
.size(); I
!= N
; ++I
) {
1032 ActionEntry
&Action
= Actions
[I
];
1034 //Asm->EOL("TypeInfo index");
1035 FinalSize
+= TargetAsmInfo::getSLEB128Size(Action
.ValueForTypeID
);
1036 //Asm->EOL("Next action");
1037 FinalSize
+= TargetAsmInfo::getSLEB128Size(Action
.NextAction
);
1040 // Emit the type ids.
1041 for (unsigned M
= TypeInfos
.size(); M
; --M
) {
1042 // Asm->EOL("TypeInfo");
1043 FinalSize
+= PointerSize
;
1046 // Emit the filter typeids.
1047 for (unsigned j
= 0, M
= FilterIds
.size(); j
< M
; ++j
) {
1048 unsigned TypeID
= FilterIds
[j
];
1049 FinalSize
+= TargetAsmInfo::getULEB128Size(TypeID
);
1050 //Asm->EOL("Filter TypeInfo index");
1053 FinalSize
= RoundUpToAlign(FinalSize
, 4);