blob: ee1ec72cb0f7927cd452be97b8841d4a9847e7e5 [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"
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +000019#include "llvm/CodeGen/JITCodeEmitter.h"
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000020#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineLocation.h"
22#include "llvm/CodeGen/MachineModuleInfo.h"
23#include "llvm/ExecutionEngine/JITMemoryManager.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000024#include "llvm/Support/ErrorHandling.h"
Chris Lattneraf76e592009-08-22 20:48:53 +000025#include "llvm/MC/MCAsmInfo.h"
Chris Lattner16112732010-03-14 01:41:15 +000026#include "llvm/MC/MCSymbol.h"
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000027#include "llvm/Target/TargetData.h"
28#include "llvm/Target/TargetInstrInfo.h"
29#include "llvm/Target/TargetFrameInfo.h"
30#include "llvm/Target/TargetMachine.h"
31#include "llvm/Target/TargetRegisterInfo.h"
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000032using namespace llvm;
33
Daniel Dunbar003de662009-09-21 05:58:35 +000034JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : MMI(0), Jit(theJit) {}
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000035
36
37unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +000038 JITCodeEmitter& jce,
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000039 unsigned char* StartFunction,
Reid Kleckner27632172009-09-20 23:52:43 +000040 unsigned char* EndFunction,
41 unsigned char* &EHFramePtr) {
Daniel Dunbar003de662009-09-21 05:58:35 +000042 assert(MMI && "MachineModuleInfo not registered!");
43
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000044 const TargetMachine& TM = F.getTarget();
45 TD = TM.getTargetData();
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000046 stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
47 RI = TM.getRegisterInfo();
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +000048 JCE = &jce;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000049
50 unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
51 EndFunction);
52
53 unsigned char* Result = 0;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000054
55 const std::vector<Function *> Personalities = MMI->getPersonalities();
56 EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
57
58 Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
59 StartFunction, EndFunction, ExceptionTable);
Bill Wendling9d48b552009-09-09 00:11:02 +000060
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000061 return Result;
62}
63
64
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +000065void
66JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
67 const std::vector<MachineMove> &Moves) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000068 unsigned PointerSize = TD->getPointerSize();
69 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
70 PointerSize : -PointerSize;
Nicolas Geoffray2d450eb2008-08-19 14:48:14 +000071 bool IsLocal = false;
72 unsigned BaseLabelID = 0;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000073
74 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
75 const MachineMove &Move = Moves[i];
76 unsigned LabelID = Move.getLabelID();
Chris Lattner16112732010-03-14 01:41:15 +000077 MCSymbol *Label = LabelID ? MMI->getLabelSym(LabelID) : 0;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000078
Chris Lattner16112732010-03-14 01:41:15 +000079 // Throw out move if the label is invalid.
80 if (Label && !Label->isDefined())
81 continue;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000082
83 intptr_t LabelPtr = 0;
Chris Lattner16112732010-03-14 01:41:15 +000084 if (LabelID) LabelPtr = JCE->getLabelAddress(Label);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000085
86 const MachineLocation &Dst = Move.getDestination();
87 const MachineLocation &Src = Move.getSource();
88
89 // Advance row if new location.
Nicolas Geoffray2d450eb2008-08-19 14:48:14 +000090 if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +000091 JCE->emitByte(dwarf::DW_CFA_advance_loc4);
92 JCE->emitInt32(LabelPtr - BaseLabelPtr);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000093
Nicolas Geoffray2d450eb2008-08-19 14:48:14 +000094 BaseLabelID = LabelID;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +000095 BaseLabelPtr = LabelPtr;
96 IsLocal = true;
97 }
98
99 // If advancing cfa.
Daniel Dunbar489032a2008-10-03 17:11:57 +0000100 if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
101 if (!Src.isReg()) {
102 if (Src.getReg() == MachineLocation::VirtualFP) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000103 JCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000104 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000105 JCE->emitByte(dwarf::DW_CFA_def_cfa);
106 JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true));
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000107 }
108
Bill Wendling9d48b552009-09-09 00:11:02 +0000109 JCE->emitULEB128Bytes(-Src.getOffset());
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000110 } else {
Bill Wendling9d48b552009-09-09 00:11:02 +0000111 llvm_unreachable("Machine move not supported yet.");
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000112 }
Daniel Dunbar489032a2008-10-03 17:11:57 +0000113 } else if (Src.isReg() &&
114 Src.getReg() == MachineLocation::VirtualFP) {
115 if (Dst.isReg()) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000116 JCE->emitByte(dwarf::DW_CFA_def_cfa_register);
117 JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true));
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000118 } else {
Bill Wendling9d48b552009-09-09 00:11:02 +0000119 llvm_unreachable("Machine move not supported yet.");
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000120 }
121 } else {
Daniel Dunbar489032a2008-10-03 17:11:57 +0000122 unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000123 int Offset = Dst.getOffset() / stackGrowth;
124
125 if (Offset < 0) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000126 JCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
127 JCE->emitULEB128Bytes(Reg);
128 JCE->emitSLEB128Bytes(Offset);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000129 } else if (Reg < 64) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000130 JCE->emitByte(dwarf::DW_CFA_offset + Reg);
131 JCE->emitULEB128Bytes(Offset);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000132 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000133 JCE->emitByte(dwarf::DW_CFA_offset_extended);
134 JCE->emitULEB128Bytes(Reg);
135 JCE->emitULEB128Bytes(Offset);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000136 }
137 }
138 }
139}
140
141/// SharedTypeIds - How many leading type ids two landing pads have in common.
142static unsigned SharedTypeIds(const LandingPadInfo *L,
143 const LandingPadInfo *R) {
144 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
145 unsigned LSize = LIds.size(), RSize = RIds.size();
146 unsigned MinSize = LSize < RSize ? LSize : RSize;
147 unsigned Count = 0;
148
149 for (; Count != MinSize; ++Count)
150 if (LIds[Count] != RIds[Count])
151 return Count;
152
153 return Count;
154}
155
156
157/// PadLT - Order landing pads lexicographically by type id.
158static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
159 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
160 unsigned LSize = LIds.size(), RSize = RIds.size();
161 unsigned MinSize = LSize < RSize ? LSize : RSize;
162
163 for (unsigned i = 0; i != MinSize; ++i)
164 if (LIds[i] != RIds[i])
165 return LIds[i] < RIds[i];
166
167 return LSize < RSize;
168}
169
Dan Gohman844731a2008-05-13 00:00:25 +0000170namespace {
171
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000172/// ActionEntry - Structure describing an entry in the actions table.
173struct ActionEntry {
174 int ValueForTypeID; // The value to write - may not be equal to the type id.
175 int NextAction;
176 struct ActionEntry *Previous;
177};
178
179/// PadRange - Structure holding a try-range and the associated landing pad.
180struct PadRange {
181 // The index of the landing pad.
182 unsigned PadIndex;
183 // The index of the begin and end labels in the landing pad's label lists.
184 unsigned RangeIndex;
185};
186
Chris Lattner16112732010-03-14 01:41:15 +0000187typedef DenseMap<MCSymbol*, PadRange> RangeMapType;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000188
189/// CallSiteEntry - Structure describing an entry in the call-site table.
190struct CallSiteEntry {
Chris Lattner16112732010-03-14 01:41:15 +0000191 MCSymbol *BeginLabel; // zero indicates the start of the function.
192 MCSymbol *EndLabel; // zero indicates the end of the function.
193 MCSymbol *PadLabel; // zero indicates that there is no landing pad.
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000194 unsigned Action;
195};
196
Dan Gohman844731a2008-05-13 00:00:25 +0000197}
198
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000199unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
200 unsigned char* StartFunction,
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000201 unsigned char* EndFunction) const {
Daniel Dunbar003de662009-09-21 05:58:35 +0000202 assert(MMI && "MachineModuleInfo not registered!");
203
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000204 // Map all labels and get rid of any dead landing pads.
205 MMI->TidyLandingPads();
206
207 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
208 const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
209 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
210 if (PadInfos.empty()) return 0;
211
212 // Sort the landing pads in order of their type ids. This is used to fold
213 // duplicate actions.
214 SmallVector<const LandingPadInfo *, 64> LandingPads;
215 LandingPads.reserve(PadInfos.size());
216 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
217 LandingPads.push_back(&PadInfos[i]);
218 std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
219
220 // Negative type ids index into FilterIds, positive type ids index into
221 // TypeInfos. The value written for a positive type id is just the type
222 // id itself. For a negative type id, however, the value written is the
223 // (negative) byte offset of the corresponding FilterIds entry. The byte
224 // offset is usually equal to the type id, because the FilterIds entries
225 // are written using a variable width encoding which outputs one byte per
226 // entry as long as the value written is not too large, but can differ.
227 // This kind of complication does not occur for positive type ids because
228 // type infos are output using a fixed width encoding.
229 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
230 SmallVector<int, 16> FilterOffsets;
231 FilterOffsets.reserve(FilterIds.size());
232 int Offset = -1;
233 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
234 E = FilterIds.end(); I != E; ++I) {
235 FilterOffsets.push_back(Offset);
Chris Lattneraf76e592009-08-22 20:48:53 +0000236 Offset -= MCAsmInfo::getULEB128Size(*I);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000237 }
238
239 // Compute the actions table and gather the first action index for each
240 // landing pad site.
241 SmallVector<ActionEntry, 32> Actions;
242 SmallVector<unsigned, 64> FirstActions;
243 FirstActions.reserve(LandingPads.size());
244
245 int FirstAction = 0;
246 unsigned SizeActions = 0;
247 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
248 const LandingPadInfo *LP = LandingPads[i];
249 const std::vector<int> &TypeIds = LP->TypeIds;
250 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
251 unsigned SizeSiteActions = 0;
252
253 if (NumShared < TypeIds.size()) {
254 unsigned SizeAction = 0;
255 ActionEntry *PrevAction = 0;
256
257 if (NumShared) {
258 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
259 assert(Actions.size());
260 PrevAction = &Actions.back();
Chris Lattneraf76e592009-08-22 20:48:53 +0000261 SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
262 MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000263 for (unsigned j = NumShared; j != SizePrevIds; ++j) {
Chris Lattneraf76e592009-08-22 20:48:53 +0000264 SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000265 SizeAction += -PrevAction->NextAction;
266 PrevAction = PrevAction->Previous;
267 }
268 }
269
270 // Compute the actions.
271 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
272 int TypeID = TypeIds[I];
273 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
274 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
Chris Lattneraf76e592009-08-22 20:48:53 +0000275 unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000276
277 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
Chris Lattneraf76e592009-08-22 20:48:53 +0000278 SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000279 SizeSiteActions += SizeAction;
280
281 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
282 Actions.push_back(Action);
283
284 PrevAction = &Actions.back();
285 }
286
287 // Record the first action of the landing pad site.
288 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
289 } // else identical - re-use previous FirstAction
290
291 FirstActions.push_back(FirstAction);
292
293 // Compute this sites contribution to size.
294 SizeActions += SizeSiteActions;
295 }
296
297 // Compute the call-site table. Entries must be ordered by address.
298 SmallVector<CallSiteEntry, 64> CallSites;
299
300 RangeMapType PadMap;
301 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
302 const LandingPadInfo *LandingPad = LandingPads[i];
303 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
Chris Lattner16112732010-03-14 01:41:15 +0000304 MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000305 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
306 PadRange P = { i, j };
307 PadMap[BeginLabel] = P;
308 }
309 }
310
311 bool MayThrow = false;
Chris Lattner16112732010-03-14 01:41:15 +0000312 MCSymbol *LastLabel = 0;
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000313 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
314 I != E; ++I) {
315 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
316 MI != E; ++MI) {
Dan Gohman44066042008-07-01 00:05:16 +0000317 if (!MI->isLabel()) {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000318 MayThrow |= MI->getDesc().isCall();
319 continue;
320 }
321
Chris Lattner16112732010-03-14 01:41:15 +0000322 unsigned BeginLabelID = MI->getOperand(0).getImm();
323 MCSymbol *BeginLabel = MMI->getLabelSym(BeginLabelID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000324 assert(BeginLabel && "Invalid label!");
325
326 if (BeginLabel == LastLabel)
327 MayThrow = false;
328
329 RangeMapType::iterator L = PadMap.find(BeginLabel);
330
331 if (L == PadMap.end())
332 continue;
333
334 PadRange P = L->second;
335 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
336
337 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
338 "Inconsistent landing pad map!");
339
340 // If some instruction between the previous try-range and this one may
341 // throw, create a call-site entry with no landing pad for the region
342 // between the try-ranges.
343 if (MayThrow) {
344 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
345 CallSites.push_back(Site);
346 }
347
348 LastLabel = LandingPad->EndLabels[P.RangeIndex];
349 CallSiteEntry Site = {BeginLabel, LastLabel,
350 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
351
352 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
353 "Invalid landing pad!");
354
355 // Try to merge with the previous call-site.
356 if (CallSites.size()) {
Dan Gohman719de532008-06-21 22:00:54 +0000357 CallSiteEntry &Prev = CallSites.back();
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000358 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
359 // Extend the range of the previous entry.
360 Prev.EndLabel = Site.EndLabel;
361 continue;
362 }
363 }
364
365 // Otherwise, create a new call-site.
366 CallSites.push_back(Site);
367 }
368 }
369 // If some instruction between the previous try-range and the end of the
370 // function may throw, create a call-site entry with no landing pad for the
371 // region following the try-range.
372 if (MayThrow) {
373 CallSiteEntry Site = {LastLabel, 0, 0, 0};
374 CallSites.push_back(Site);
375 }
376
377 // Final tallies.
378 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
379 sizeof(int32_t) + // Site length.
380 sizeof(int32_t)); // Landing pad.
381 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
Chris Lattneraf76e592009-08-22 20:48:53 +0000382 SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000383
384 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
385
386 unsigned TypeOffset = sizeof(int8_t) + // Call site format
387 // Call-site table length
Chris Lattneraf76e592009-08-22 20:48:53 +0000388 MCAsmInfo::getULEB128Size(SizeSites) +
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000389 SizeSites + SizeActions + SizeTypes;
390
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000391 // Begin the exception table.
Reid Kleckner01248e62009-08-21 21:03:57 +0000392 JCE->emitAlignmentWithFill(4, 0);
393 // Asm->EOL("Padding");
394
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000395 unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000396
397 // Emit the header.
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000398 JCE->emitByte(dwarf::DW_EH_PE_omit);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000399 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000400 JCE->emitByte(dwarf::DW_EH_PE_absptr);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000401 // Asm->EOL("TType format (DW_EH_PE_absptr)");
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000402 JCE->emitULEB128Bytes(TypeOffset);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000403 // Asm->EOL("TType base offset");
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000404 JCE->emitByte(dwarf::DW_EH_PE_udata4);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000405 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000406 JCE->emitULEB128Bytes(SizeSites);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000407 // Asm->EOL("Call-site table length");
408
409 // Emit the landing pad site information.
410 for (unsigned i = 0; i < CallSites.size(); ++i) {
411 CallSiteEntry &S = CallSites[i];
412 intptr_t BeginLabelPtr = 0;
413 intptr_t EndLabelPtr = 0;
414
415 if (!S.BeginLabel) {
416 BeginLabelPtr = (intptr_t)StartFunction;
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000417 JCE->emitInt32(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000418 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000419 BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel);
420 JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000421 }
422
423 // Asm->EOL("Region start");
424
Bill Wendlingabeca442009-12-28 01:53:00 +0000425 if (!S.EndLabel)
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000426 EndLabelPtr = (intptr_t)EndFunction;
Bill Wendlingabeca442009-12-28 01:53:00 +0000427 else
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000428 EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
Bill Wendlingabeca442009-12-28 01:53:00 +0000429
430 JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000431 //Asm->EOL("Region length");
432
433 if (!S.PadLabel) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000434 JCE->emitInt32(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000435 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000436 unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
437 JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000438 }
439 // Asm->EOL("Landing pad");
440
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000441 JCE->emitULEB128Bytes(S.Action);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000442 // Asm->EOL("Action");
443 }
444
445 // Emit the actions.
446 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
447 ActionEntry &Action = Actions[I];
448
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000449 JCE->emitSLEB128Bytes(Action.ValueForTypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000450 //Asm->EOL("TypeInfo index");
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000451 JCE->emitSLEB128Bytes(Action.NextAction);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000452 //Asm->EOL("Next action");
453 }
454
455 // Emit the type ids.
456 for (unsigned M = TypeInfos.size(); M; --M) {
457 GlobalVariable *GV = TypeInfos[M - 1];
458
459 if (GV) {
Bill Wendling9d48b552009-09-09 00:11:02 +0000460 if (TD->getPointerSize() == sizeof(int32_t))
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000461 JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
Bill Wendling9d48b552009-09-09 00:11:02 +0000462 else
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000463 JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000464 } else {
465 if (TD->getPointerSize() == sizeof(int32_t))
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000466 JCE->emitInt32(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000467 else
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000468 JCE->emitInt64(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000469 }
470 // Asm->EOL("TypeInfo");
471 }
472
473 // Emit the filter typeids.
474 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
475 unsigned TypeID = FilterIds[j];
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000476 JCE->emitULEB128Bytes(TypeID);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000477 //Asm->EOL("Filter TypeInfo index");
478 }
Reid Kleckner01248e62009-08-21 21:03:57 +0000479
480 JCE->emitAlignmentWithFill(4, 0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000481
482 return DwarfExceptionTable;
483}
484
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000485unsigned char*
486JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000487 unsigned PointerSize = TD->getPointerSize();
488 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
489 PointerSize : -PointerSize;
490
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000491 unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue();
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000492 // EH Common Frame header
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000493 JCE->allocateSpace(4, 0);
494 unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
495 JCE->emitInt32((int)0);
496 JCE->emitByte(dwarf::DW_CIE_VERSION);
497 JCE->emitString(Personality ? "zPLR" : "zR");
498 JCE->emitULEB128Bytes(1);
499 JCE->emitSLEB128Bytes(stackGrowth);
500 JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
Bill Wendling9d48b552009-09-09 00:11:02 +0000501
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000502 if (Personality) {
Nicolas Geoffray42cc8f12009-02-15 20:49:23 +0000503 // Augmentation Size: 3 small ULEBs of one byte each, and the personality
504 // function which size is PointerSize.
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000505 JCE->emitULEB128Bytes(3 + PointerSize);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000506
Nicolas Geoffray42cc8f12009-02-15 20:49:23 +0000507 // We set the encoding of the personality as direct encoding because we use
508 // the function pointer. The encoding is not relative because the current
509 // PC value may be bigger than the personality function pointer.
510 if (PointerSize == 4) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000511 JCE->emitByte(dwarf::DW_EH_PE_sdata4);
512 JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
Nicolas Geoffray42cc8f12009-02-15 20:49:23 +0000513 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000514 JCE->emitByte(dwarf::DW_EH_PE_sdata8);
515 JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
Nicolas Geoffray42cc8f12009-02-15 20:49:23 +0000516 }
Bill Wendling9d48b552009-09-09 00:11:02 +0000517
Bill Wendling89ee7062010-02-16 00:58:02 +0000518 // LSDA encoding: This must match the encoding used in EmitEHFrame ()
519 if (PointerSize == 4)
520 JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
521 else
522 JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000523 JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000524 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000525 JCE->emitULEB128Bytes(1);
526 JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000527 }
528
529 std::vector<MachineMove> Moves;
530 RI->getInitialFrameState(Moves);
531 EmitFrameMoves(0, Moves);
Reid Kleckner01248e62009-08-21 21:03:57 +0000532
533 JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
534
535 JCE->emitInt32At((uintptr_t*)StartCommonPtr,
536 (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
537 FrameCommonBeginPtr));
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000538
539 return StartCommonPtr;
540}
541
542
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000543unsigned char*
544JITDwarfEmitter::EmitEHFrame(const Function* Personality,
545 unsigned char* StartCommonPtr,
546 unsigned char* StartFunction,
547 unsigned char* EndFunction,
548 unsigned char* ExceptionTable) const {
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000549 unsigned PointerSize = TD->getPointerSize();
550
551 // EH frame header.
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000552 unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue();
553 JCE->allocateSpace(4, 0);
554 unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000555 // FDE CIE Offset
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000556 JCE->emitInt32(FrameBeginPtr - StartCommonPtr);
557 JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue());
558 JCE->emitInt32(EndFunction - StartFunction);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000559
560 // If there is a personality and landing pads then point to the language
561 // specific data area in the exception table.
Bill Wendling9d48b552009-09-09 00:11:02 +0000562 if (Personality) {
563 JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000564
Bill Wendling9d48b552009-09-09 00:11:02 +0000565 if (PointerSize == 4) {
566 if (!MMI->getLandingPads().empty())
567 JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
568 else
569 JCE->emitInt32((int)0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000570 } else {
Bill Wendling9d48b552009-09-09 00:11:02 +0000571 if (!MMI->getLandingPads().empty())
572 JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
573 else
574 JCE->emitInt64((int)0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000575 }
576 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000577 JCE->emitULEB128Bytes(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000578 }
579
580 // Indicate locations of function specific callee saved registers in
581 // frame.
582 EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
Reid Kleckner01248e62009-08-21 21:03:57 +0000583
584 JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
585
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000586 // Indicate the size of the table
Reid Kleckner01248e62009-08-21 21:03:57 +0000587 JCE->emitInt32At((uintptr_t*)StartEHPtr,
588 (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
589 StartEHPtr));
590
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000591 // Double zeroes for the unwind runtime
592 if (PointerSize == 8) {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000593 JCE->emitInt64(0);
594 JCE->emitInt64(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000595 } else {
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000596 JCE->emitInt32(0);
597 JCE->emitInt32(0);
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000598 }
Nicolas Geoffrayafe6c2b2008-02-13 18:39:37 +0000599
600 return StartEHPtr;
601}
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000602
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000603unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000604 JITCodeEmitter& jce,
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000605 unsigned char* StartFunction,
606 unsigned char* EndFunction) {
607 const TargetMachine& TM = F.getTarget();
608 TD = TM.getTargetData();
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000609 stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
610 RI = TM.getRegisterInfo();
Bruno Cardoso Lopesa3f99f92009-05-30 20:51:52 +0000611 JCE = &jce;
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000612 unsigned FinalSize = 0;
613
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000614 FinalSize += GetExceptionTableSizeInBytes(&F);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000615
616 const std::vector<Function *> Personalities = MMI->getPersonalities();
Nicolas Geoffray67c8c4c2008-11-18 10:44:46 +0000617 FinalSize +=
618 GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000619
Nicolas Geoffray67c8c4c2008-11-18 10:44:46 +0000620 FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()],
621 StartFunction);
Bill Wendling9d48b552009-09-09 00:11:02 +0000622
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000623 return FinalSize;
624}
625
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000626/// RoundUpToAlign - Add the specified alignment to FinalSize and returns
627/// the new value.
628static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000629 if (Alignment == 0) Alignment = 1;
Nicolas Geoffray580631a2008-04-20 23:39:44 +0000630 // Since we do not know where the buffer will be allocated, be pessimistic.
631 return FinalSize + Alignment;
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000632}
633
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000634unsigned
635JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
636 unsigned char* StartFunction) const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000637 unsigned PointerSize = TD->getPointerSize();
638 unsigned FinalSize = 0;
639 // EH frame header.
640 FinalSize += PointerSize;
641 // FDE CIE Offset
642 FinalSize += 3 * PointerSize;
643 // If there is a personality and landing pads then point to the language
644 // specific data area in the exception table.
Bill Wendling9d48b552009-09-09 00:11:02 +0000645 if (Personality) {
Chris Lattneraf76e592009-08-22 20:48:53 +0000646 FinalSize += MCAsmInfo::getULEB128Size(4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000647 FinalSize += PointerSize;
648 } else {
Chris Lattneraf76e592009-08-22 20:48:53 +0000649 FinalSize += MCAsmInfo::getULEB128Size(0);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000650 }
651
652 // Indicate locations of function specific callee saved registers in
653 // frame.
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000654 FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
655 MMI->getFrameMoves());
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000656
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000657 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000658
659 // Double zeroes for the unwind runtime
660 FinalSize += 2 * PointerSize;
661
662 return FinalSize;
663}
664
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000665unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality)
666 const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000667
668 unsigned PointerSize = TD->getPointerSize();
669 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
670 PointerSize : -PointerSize;
671 unsigned FinalSize = 0;
672 // EH Common Frame header
673 FinalSize += PointerSize;
674 FinalSize += 4;
675 FinalSize += 1;
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000676 FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
Chris Lattneraf76e592009-08-22 20:48:53 +0000677 FinalSize += MCAsmInfo::getULEB128Size(1);
678 FinalSize += MCAsmInfo::getSLEB128Size(stackGrowth);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000679 FinalSize += 1;
680
681 if (Personality) {
Chris Lattneraf76e592009-08-22 20:48:53 +0000682 FinalSize += MCAsmInfo::getULEB128Size(7);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000683
684 // Encoding
685 FinalSize+= 1;
686 //Personality
687 FinalSize += PointerSize;
688
Chris Lattneraf76e592009-08-22 20:48:53 +0000689 FinalSize += MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
690 FinalSize += MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000691
692 } else {
Chris Lattneraf76e592009-08-22 20:48:53 +0000693 FinalSize += MCAsmInfo::getULEB128Size(1);
694 FinalSize += MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000695 }
696
697 std::vector<MachineMove> Moves;
698 RI->getInitialFrameState(Moves);
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000699 FinalSize += GetFrameMovesSizeInBytes(0, Moves);
700 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000701 return FinalSize;
702}
703
704unsigned
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000705JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
706 const std::vector<MachineMove> &Moves) const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000707 unsigned PointerSize = TD->getPointerSize();
708 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
709 PointerSize : -PointerSize;
710 bool IsLocal = BaseLabelPtr;
711 unsigned FinalSize = 0;
712
713 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
714 const MachineMove &Move = Moves[i];
715 unsigned LabelID = Move.getLabelID();
Chris Lattner16112732010-03-14 01:41:15 +0000716 MCSymbol *Label = LabelID ? MMI->getLabelSym(LabelID) : 0;
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000717
Chris Lattner16112732010-03-14 01:41:15 +0000718 // Throw out move if the label is invalid.
719 if (Label && !Label->isDefined())
720 continue;
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000721
722 intptr_t LabelPtr = 0;
Chris Lattner16112732010-03-14 01:41:15 +0000723 if (LabelID) LabelPtr = JCE->getLabelAddress(Label);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000724
725 const MachineLocation &Dst = Move.getDestination();
726 const MachineLocation &Src = Move.getSource();
727
728 // Advance row if new location.
729 if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
730 FinalSize++;
731 FinalSize += PointerSize;
732 BaseLabelPtr = LabelPtr;
733 IsLocal = true;
734 }
735
736 // If advancing cfa.
Daniel Dunbar489032a2008-10-03 17:11:57 +0000737 if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
738 if (!Src.isReg()) {
739 if (Src.getReg() == MachineLocation::VirtualFP) {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000740 ++FinalSize;
741 } else {
742 ++FinalSize;
Daniel Dunbar489032a2008-10-03 17:11:57 +0000743 unsigned RegNum = RI->getDwarfRegNum(Src.getReg(), true);
Chris Lattneraf76e592009-08-22 20:48:53 +0000744 FinalSize += MCAsmInfo::getULEB128Size(RegNum);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000745 }
746
747 int Offset = -Src.getOffset();
748
Chris Lattneraf76e592009-08-22 20:48:53 +0000749 FinalSize += MCAsmInfo::getULEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000750 } else {
Torok Edwinc23197a2009-07-14 16:55:14 +0000751 llvm_unreachable("Machine move no supported yet.");
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000752 }
Daniel Dunbar489032a2008-10-03 17:11:57 +0000753 } else if (Src.isReg() &&
754 Src.getReg() == MachineLocation::VirtualFP) {
755 if (Dst.isReg()) {
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000756 ++FinalSize;
Daniel Dunbar489032a2008-10-03 17:11:57 +0000757 unsigned RegNum = RI->getDwarfRegNum(Dst.getReg(), true);
Chris Lattneraf76e592009-08-22 20:48:53 +0000758 FinalSize += MCAsmInfo::getULEB128Size(RegNum);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000759 } else {
Torok Edwinc23197a2009-07-14 16:55:14 +0000760 llvm_unreachable("Machine move no supported yet.");
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000761 }
762 } else {
Daniel Dunbar489032a2008-10-03 17:11:57 +0000763 unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000764 int Offset = Dst.getOffset() / stackGrowth;
765
766 if (Offset < 0) {
767 ++FinalSize;
Chris Lattneraf76e592009-08-22 20:48:53 +0000768 FinalSize += MCAsmInfo::getULEB128Size(Reg);
769 FinalSize += MCAsmInfo::getSLEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000770 } else if (Reg < 64) {
771 ++FinalSize;
Chris Lattneraf76e592009-08-22 20:48:53 +0000772 FinalSize += MCAsmInfo::getULEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000773 } else {
774 ++FinalSize;
Chris Lattneraf76e592009-08-22 20:48:53 +0000775 FinalSize += MCAsmInfo::getULEB128Size(Reg);
776 FinalSize += MCAsmInfo::getULEB128Size(Offset);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000777 }
778 }
779 }
780 return FinalSize;
781}
782
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000783unsigned
784JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000785 unsigned FinalSize = 0;
786
787 // Map all labels and get rid of any dead landing pads.
788 MMI->TidyLandingPads();
789
790 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
791 const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
792 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
793 if (PadInfos.empty()) return 0;
794
795 // Sort the landing pads in order of their type ids. This is used to fold
796 // duplicate actions.
797 SmallVector<const LandingPadInfo *, 64> LandingPads;
798 LandingPads.reserve(PadInfos.size());
799 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
800 LandingPads.push_back(&PadInfos[i]);
801 std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
802
803 // Negative type ids index into FilterIds, positive type ids index into
804 // TypeInfos. The value written for a positive type id is just the type
805 // id itself. For a negative type id, however, the value written is the
806 // (negative) byte offset of the corresponding FilterIds entry. The byte
807 // offset is usually equal to the type id, because the FilterIds entries
808 // are written using a variable width encoding which outputs one byte per
809 // entry as long as the value written is not too large, but can differ.
810 // This kind of complication does not occur for positive type ids because
811 // type infos are output using a fixed width encoding.
812 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
813 SmallVector<int, 16> FilterOffsets;
814 FilterOffsets.reserve(FilterIds.size());
815 int Offset = -1;
816 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
817 E = FilterIds.end(); I != E; ++I) {
818 FilterOffsets.push_back(Offset);
Chris Lattneraf76e592009-08-22 20:48:53 +0000819 Offset -= MCAsmInfo::getULEB128Size(*I);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000820 }
821
822 // Compute the actions table and gather the first action index for each
823 // landing pad site.
824 SmallVector<ActionEntry, 32> Actions;
825 SmallVector<unsigned, 64> FirstActions;
826 FirstActions.reserve(LandingPads.size());
827
828 int FirstAction = 0;
829 unsigned SizeActions = 0;
830 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
831 const LandingPadInfo *LP = LandingPads[i];
832 const std::vector<int> &TypeIds = LP->TypeIds;
833 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
834 unsigned SizeSiteActions = 0;
835
836 if (NumShared < TypeIds.size()) {
837 unsigned SizeAction = 0;
838 ActionEntry *PrevAction = 0;
839
840 if (NumShared) {
841 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
842 assert(Actions.size());
843 PrevAction = &Actions.back();
Chris Lattneraf76e592009-08-22 20:48:53 +0000844 SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
845 MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000846 for (unsigned j = NumShared; j != SizePrevIds; ++j) {
Chris Lattneraf76e592009-08-22 20:48:53 +0000847 SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000848 SizeAction += -PrevAction->NextAction;
849 PrevAction = PrevAction->Previous;
850 }
851 }
852
853 // Compute the actions.
854 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
855 int TypeID = TypeIds[I];
856 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
857 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
Chris Lattneraf76e592009-08-22 20:48:53 +0000858 unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000859
860 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
Chris Lattneraf76e592009-08-22 20:48:53 +0000861 SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000862 SizeSiteActions += SizeAction;
863
864 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
865 Actions.push_back(Action);
866
867 PrevAction = &Actions.back();
868 }
869
870 // Record the first action of the landing pad site.
871 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
872 } // else identical - re-use previous FirstAction
873
874 FirstActions.push_back(FirstAction);
875
876 // Compute this sites contribution to size.
877 SizeActions += SizeSiteActions;
878 }
879
880 // Compute the call-site table. Entries must be ordered by address.
881 SmallVector<CallSiteEntry, 64> CallSites;
882
883 RangeMapType PadMap;
884 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
885 const LandingPadInfo *LandingPad = LandingPads[i];
886 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
Chris Lattner16112732010-03-14 01:41:15 +0000887 MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000888 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
889 PadRange P = { i, j };
890 PadMap[BeginLabel] = P;
891 }
892 }
893
894 bool MayThrow = false;
Chris Lattner16112732010-03-14 01:41:15 +0000895 MCSymbol *LastLabel = 0;
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000896 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
897 I != E; ++I) {
898 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
899 MI != E; ++MI) {
Dan Gohman44066042008-07-01 00:05:16 +0000900 if (!MI->isLabel()) {
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000901 MayThrow |= MI->getDesc().isCall();
902 continue;
903 }
904
Chris Lattner16112732010-03-14 01:41:15 +0000905 unsigned BeginLabelID = MI->getOperand(0).getImm();
906 assert(BeginLabelID && "Invalid label!");
907 MCSymbol *BeginLabel = MMI->getLabelSym(BeginLabelID);
908
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000909 if (BeginLabel == LastLabel)
910 MayThrow = false;
911
912 RangeMapType::iterator L = PadMap.find(BeginLabel);
913
914 if (L == PadMap.end())
915 continue;
916
917 PadRange P = L->second;
918 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
919
920 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
921 "Inconsistent landing pad map!");
922
923 // If some instruction between the previous try-range and this one may
924 // throw, create a call-site entry with no landing pad for the region
925 // between the try-ranges.
926 if (MayThrow) {
927 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
928 CallSites.push_back(Site);
929 }
930
931 LastLabel = LandingPad->EndLabels[P.RangeIndex];
932 CallSiteEntry Site = {BeginLabel, LastLabel,
933 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
934
935 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
936 "Invalid landing pad!");
937
938 // Try to merge with the previous call-site.
939 if (CallSites.size()) {
Dan Gohman719de532008-06-21 22:00:54 +0000940 CallSiteEntry &Prev = CallSites.back();
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000941 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
942 // Extend the range of the previous entry.
943 Prev.EndLabel = Site.EndLabel;
944 continue;
945 }
946 }
947
948 // Otherwise, create a new call-site.
949 CallSites.push_back(Site);
950 }
951 }
952 // If some instruction between the previous try-range and the end of the
953 // function may throw, create a call-site entry with no landing pad for the
954 // region following the try-range.
955 if (MayThrow) {
956 CallSiteEntry Site = {LastLabel, 0, 0, 0};
957 CallSites.push_back(Site);
958 }
959
960 // Final tallies.
961 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
962 sizeof(int32_t) + // Site length.
963 sizeof(int32_t)); // Landing pad.
964 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
Chris Lattneraf76e592009-08-22 20:48:53 +0000965 SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000966
967 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
968
969 unsigned TypeOffset = sizeof(int8_t) + // Call site format
970 // Call-site table length
Chris Lattneraf76e592009-08-22 20:48:53 +0000971 MCAsmInfo::getULEB128Size(SizeSites) +
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000972 SizeSites + SizeActions + SizeTypes;
973
974 unsigned TotalSize = sizeof(int8_t) + // LPStart format
975 sizeof(int8_t) + // TType format
Chris Lattneraf76e592009-08-22 20:48:53 +0000976 MCAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000977 TypeOffset;
978
979 unsigned SizeAlign = (4 - TotalSize) & 3;
980
981 // Begin the exception table.
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +0000982 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +0000983 for (unsigned i = 0; i != SizeAlign; ++i) {
984 ++FinalSize;
985 }
986
987 unsigned PointerSize = TD->getPointerSize();
988
989 // Emit the header.
990 ++FinalSize;
991 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
992 ++FinalSize;
993 // Asm->EOL("TType format (DW_EH_PE_absptr)");
994 ++FinalSize;
995 // Asm->EOL("TType base offset");
996 ++FinalSize;
997 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
998 ++FinalSize;
999 // Asm->EOL("Call-site table length");
1000
1001 // Emit the landing pad site information.
1002 for (unsigned i = 0; i < CallSites.size(); ++i) {
1003 CallSiteEntry &S = CallSites[i];
1004
1005 // Asm->EOL("Region start");
1006 FinalSize += PointerSize;
1007
1008 //Asm->EOL("Region length");
1009 FinalSize += PointerSize;
1010
1011 // Asm->EOL("Landing pad");
1012 FinalSize += PointerSize;
1013
Chris Lattneraf76e592009-08-22 20:48:53 +00001014 FinalSize += MCAsmInfo::getULEB128Size(S.Action);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001015 // Asm->EOL("Action");
1016 }
1017
1018 // Emit the actions.
1019 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
1020 ActionEntry &Action = Actions[I];
1021
1022 //Asm->EOL("TypeInfo index");
Chris Lattneraf76e592009-08-22 20:48:53 +00001023 FinalSize += MCAsmInfo::getSLEB128Size(Action.ValueForTypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001024 //Asm->EOL("Next action");
Chris Lattneraf76e592009-08-22 20:48:53 +00001025 FinalSize += MCAsmInfo::getSLEB128Size(Action.NextAction);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001026 }
1027
1028 // Emit the type ids.
1029 for (unsigned M = TypeInfos.size(); M; --M) {
1030 // Asm->EOL("TypeInfo");
1031 FinalSize += PointerSize;
1032 }
1033
1034 // Emit the filter typeids.
1035 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
1036 unsigned TypeID = FilterIds[j];
Chris Lattneraf76e592009-08-22 20:48:53 +00001037 FinalSize += MCAsmInfo::getULEB128Size(TypeID);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001038 //Asm->EOL("Filter TypeInfo index");
1039 }
1040
Nicolas Geoffray5913e6c2008-04-20 17:44:19 +00001041 FinalSize = RoundUpToAlign(FinalSize, 4);
Nicolas Geoffraydc17ab22008-04-18 20:59:31 +00001042
1043 return FinalSize;
1044}