llvm.org GIT mirror llvm / afe6c2b
Enable exception handling int JIT git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47079 91177308-0d34-0410-b5e6-96231b3b80d8 Nicolas Geoffray 12 years ago
13 changed file(s) with 961 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
2525 class MachineConstantPool;
2626 class MachineJumpTableInfo;
2727 class MachineFunction;
28 class MachineModuleInfo;
2829 class MachineRelocation;
2930 class Value;
3031 class GlobalValue;
135136 CurBufferPtr = BufferEnd;
136137 }
137138
139
140 /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
141 /// written to the output stream.
142 void emitULEB128Bytes(unsigned Value) {
143 do {
144 unsigned char Byte = Value & 0x7f;
145 Value >>= 7;
146 if (Value) Byte |= 0x80;
147 emitByte(Byte);
148 } while (Value);
149 }
150
151 /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
152 /// written to the output stream.
153 void emitSLEB128Bytes(int Value) {
154 int Sign = Value >> (8 * sizeof(Value) - 1);
155 bool IsMore;
156
157 do {
158 unsigned char Byte = Value & 0x7f;
159 Value >>= 7;
160 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
161 if (IsMore) Byte |= 0x80;
162 emitByte(Byte);
163 } while (IsMore);
164 }
165
166 /// emitString - This callback is invoked when a String needs to be
167 /// written to the output stream.
168 void emitString(const std::string &String) {
169 for (unsigned i = 0, N = String.size(); i < N; ++i) {
170 unsigned char C = String[i];
171 emitByte(C);
172 }
173 emitByte(0);
174 }
175
176 /// emitInt32 - Emit a int32 directive.
177 void emitInt32(int Value) {
178 if (CurBufferPtr+4 <= BufferEnd) {
179 *((uint32_t*)CurBufferPtr) = Value;
180 CurBufferPtr += 4;
181 } else {
182 CurBufferPtr = BufferEnd;
183 }
184 }
185
186 /// emitInt64 - Emit a int64 directive.
187 void emitInt64(uint64_t Value) {
188 if (CurBufferPtr+8 <= BufferEnd) {
189 *((uint64_t*)CurBufferPtr) = Value;
190 CurBufferPtr += 8;
191 } else {
192 CurBufferPtr = BufferEnd;
193 }
194 }
195
196 /// emitAt - Emit Value in Addr
197 void emitAt(uintptr_t *Addr, uintptr_t Value) {
198 if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
199 (*Addr) = Value;
200 }
201
202 /// emitLabel - Emits a label
203 virtual void emitLabel(uint64_t LabelID) = 0;
204
138205 /// allocateSpace - Allocate a block of space in the current output buffer,
139206 /// returning null (and setting conditions to indicate buffer overflow) on
140207 /// failure. Alignment is the alignment in bytes of the buffer desired.
193260 /// emitted.
194261 ///
195262 virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
263
264 /// getLabelAddress - Return the address of the specified LabelID, only usable
265 /// after the LabelID has been emitted.
266 ///
267 virtual intptr_t getLabelAddress(uint64_t LabelID) const = 0;
268
269 /// Specifies the MachineModuleInfo object. This is used for exception handling
270 /// purposes.
271 virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
196272 };
197273
198274 } // End llvm namespace
8484 /// pointer is invoked to create it. If this returns null, the JIT will abort.
8585 void* (*LazyFunctionCreator)(const std::string &);
8686
87 /// ExceptionTableRegister - If Exception Handling is set, the JIT will
88 /// register dwarf tables with this function
89 typedef void (*EERegisterFn)(void*);
90 static EERegisterFn ExceptionTableRegister;
91
8792 public:
8893 /// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and
8994 /// JITEmitter classes. It must be held while changing the internal state of
245250 void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
246251 LazyFunctionCreator = P;
247252 }
253
254 /// InstallExceptionTableRegister - The JIT will use the given function
255 /// to register the exception tables it generates.
256 static void InstallExceptionTableRegister(void (*F)(void*)) {
257 ExceptionTableRegister = F;
258 }
259
260 /// RegisterTable - Registers the given pointer as an exception table. It uses
261 /// the ExceptionTableRegister function.
262 static void RegisterTable(void* res) {
263 if (ExceptionTableRegister)
264 ExceptionTableRegister(res);
265 }
248266
249267 protected:
250268 explicit ExecutionEngine(ModuleProvider *P);
8888 /// deallocateMemForFunction - Free JIT memory for the specified function.
8989 /// This is never called when the JIT is currently emitting a function.
9090 virtual void deallocateMemForFunction(const Function *F) = 0;
91
92 /// startExceptionTable - When we finished JITing the function, if exception
93 /// handling is set, we emit the exception table.
94 virtual unsigned char* startExceptionTable(const Function* F,
95 uintptr_t &ActualSize) = 0;
96
97 /// endExceptionTable - This method is called when the JIT is done emitting
98 /// the exception table.
99 virtual void endExceptionTable(const Function *F, unsigned char *TableStart,
100 unsigned char *TableEnd,
101 unsigned char* FrameRegister) = 0;
91102 };
92103
93104 } // end namespace llvm.
9696 assert(0 && "JT not implementated yet!");
9797 return 0;
9898 }
99
100 virtual intptr_t getLabelAddress(uint64_t Label) const {
101 assert(0 && "Label address not implementated yet!");
102 abort();
103 return 0;
104 }
105
106 virtual void emitLabel(uint64_t LabelID) {
107 assert(0 && "emit Label not implementated yet!");
108 abort();
109 }
110
111
112 virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
113
99114
100115 /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
101116 void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
185185
186186 PM.add(createGCLoweringPass());
187187
188 // FIXME: Implement the invoke/unwind instructions!
189 PM.add(createLowerInvokePass(getTargetLowering()));
188 if (!ExceptionHandling)
189 PM.add(createLowerInvokePass(getTargetLowering()));
190190
191191 // Make sure that no unreachable blocks are instruction selected.
192192 PM.add(createUnreachableBlockEliminationPass());
123123 MBBLocations[MBB->getNumber()] && "MBB not emitted!");
124124 return MBBLocations[MBB->getNumber()];
125125 }
126
127 virtual intptr_t getLabelAddress(uint64_t Label) const {
128 assert(0 && "get Label not implemented");
129 abort();
130 return 0;
131 }
132
133 virtual void emitLabel(uint64_t LabelID) {
134 assert(0 && "emit Label not implemented");
135 abort();
136 }
137
138
139 virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
126140
127141 /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
128142 virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
3333
3434 ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0;
3535 ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0;
36 ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
37
3638
3739 ExecutionEngine::ExecutionEngine(ModuleProvider *P) : LazyFunctionCreator(0) {
3840 LazyCompilationDisabled = false;
0 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a JITDwarfEmitter object that is used by the JIT to
10 // write dwarf tables to memory.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "JIT.h"
15 #include "JITDwarfEmitter.h"
16 #include "llvm/Function.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/CodeGen/AsmPrinter.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"
30
31 using namespace llvm;
32
33 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
34
35
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();
45 MCE = &mce;
46
47 unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
48 EndFunction);
49
50 unsigned char* Result = 0;
51 unsigned char* EHFramePtr = 0;
52
53 const std::vector Personalities = MMI->getPersonalities();
54 EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
55
56 Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
57 StartFunction, EndFunction, ExceptionTable);
58
59 return Result;
60 }
61
62
63 void JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
64 const std::vector &Moves) {
65 unsigned PointerSize = TD->getPointerSize();
66 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
67 PointerSize : -PointerSize;
68 bool IsLocal = BaseLabelPtr;
69
70 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
71 const MachineMove &Move = Moves[i];
72 unsigned LabelID = Move.getLabelID();
73
74 if (LabelID) {
75 LabelID = MMI->MappedLabel(LabelID);
76
77 // Throw out move if the label is invalid.
78 if (!LabelID) continue;
79 }
80
81 intptr_t LabelPtr = 0;
82 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
83
84 const MachineLocation &Dst = Move.getDestination();
85 const MachineLocation &Src = Move.getSource();
86
87 // Advance row if new location.
88 if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
89 MCE->emitByte(dwarf::DW_CFA_advance_loc4);
90 if (PointerSize == 8) {
91 MCE->emitInt64(LabelPtr - BaseLabelPtr);
92 } else {
93 MCE->emitInt32(LabelPtr - BaseLabelPtr);
94 }
95
96 BaseLabelPtr = LabelPtr;
97 IsLocal = true;
98 }
99
100 // If advancing cfa.
101 if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
102 if (!Src.isRegister()) {
103 if (Src.getRegister() == MachineLocation::VirtualFP) {
104 MCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
105 } else {
106 MCE->emitByte(dwarf::DW_CFA_def_cfa);
107 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), true));
108 }
109
110 int Offset = -Src.getOffset();
111
112 MCE->emitULEB128Bytes(Offset);
113 } else {
114 assert(0 && "Machine move no supported yet.");
115 }
116 } else if (Src.isRegister() &&
117 Src.getRegister() == MachineLocation::VirtualFP) {
118 if (Dst.isRegister()) {
119 MCE->emitByte(dwarf::DW_CFA_def_cfa_register);
120 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister(), true));
121 } else {
122 assert(0 && "Machine move no supported yet.");
123 }
124 } else {
125 unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
126 int Offset = Dst.getOffset() / stackGrowth;
127
128 if (Offset < 0) {
129 MCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
130 MCE->emitULEB128Bytes(Reg);
131 MCE->emitSLEB128Bytes(Offset);
132 } else if (Reg < 64) {
133 MCE->emitByte(dwarf::DW_CFA_offset + Reg);
134 MCE->emitULEB128Bytes(Offset);
135 } else {
136 MCE->emitByte(dwarf::DW_CFA_offset_extended);
137 MCE->emitULEB128Bytes(Reg);
138 MCE->emitULEB128Bytes(Offset);
139 }
140 }
141 }
142 }
143
144 /// SharedTypeIds - How many leading type ids two landing pads have in common.
145 static unsigned SharedTypeIds(const LandingPadInfo *L,
146 const LandingPadInfo *R) {
147 const std::vector &LIds = L->TypeIds, &RIds = R->TypeIds;
148 unsigned LSize = LIds.size(), RSize = RIds.size();
149 unsigned MinSize = LSize < RSize ? LSize : RSize;
150 unsigned Count = 0;
151
152 for (; Count != MinSize; ++Count)
153 if (LIds[Count] != RIds[Count])
154 return Count;
155
156 return Count;
157 }
158
159
160 /// PadLT - Order landing pads lexicographically by type id.
161 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
162 const std::vector &LIds = L->TypeIds, &RIds = R->TypeIds;
163 unsigned LSize = LIds.size(), RSize = RIds.size();
164 unsigned MinSize = LSize < RSize ? LSize : RSize;
165
166 for (unsigned i = 0; i != MinSize; ++i)
167 if (LIds[i] != RIds[i])
168 return LIds[i] < RIds[i];
169
170 return LSize < RSize;
171 }
172
173 struct KeyInfo {
174 static inline unsigned getEmptyKey() { return -1U; }
175 static inline unsigned getTombstoneKey() { return -2U; }
176 static unsigned getHashValue(const unsigned &Key) { return Key; }
177 static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
178 static bool isPod() { return true; }
179 };
180
181 /// ActionEntry - Structure describing an entry in the actions table.
182 struct ActionEntry {
183 int ValueForTypeID; // The value to write - may not be equal to the type id.
184 int NextAction;
185 struct ActionEntry *Previous;
186 };
187
188 /// PadRange - Structure holding a try-range and the associated landing pad.
189 struct PadRange {
190 // The index of the landing pad.
191 unsigned PadIndex;
192 // The index of the begin and end labels in the landing pad's label lists.
193 unsigned RangeIndex;
194 };
195
196 typedef DenseMap RangeMapType;
197
198 /// CallSiteEntry - Structure describing an entry in the call-site table.
199 struct CallSiteEntry {
200 unsigned BeginLabel; // zero indicates the start of the function.
201 unsigned EndLabel; // zero indicates the end of the function.
202 unsigned PadLabel; // zero indicates that there is no landing pad.
203 unsigned Action;
204 };
205
206 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
207 unsigned char* StartFunction,
208 unsigned char* EndFunction) {
209 // Map all labels and get rid of any dead landing pads.
210 MMI->TidyLandingPads();
211
212 const std::vector &TypeInfos = MMI->getTypeInfos();
213 const std::vector &FilterIds = MMI->getFilterIds();
214 const std::vector &PadInfos = MMI->getLandingPads();
215 if (PadInfos.empty()) return 0;
216
217 // Sort the landing pads in order of their type ids. This is used to fold
218 // duplicate actions.
219 SmallVector LandingPads;
220 LandingPads.reserve(PadInfos.size());
221 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
222 LandingPads.push_back(&PadInfos[i]);
223 std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
224
225 // Negative type ids index into FilterIds, positive type ids index into
226 // TypeInfos. The value written for a positive type id is just the type
227 // id itself. For a negative type id, however, the value written is the
228 // (negative) byte offset of the corresponding FilterIds entry. The byte
229 // offset is usually equal to the type id, because the FilterIds entries
230 // are written using a variable width encoding which outputs one byte per
231 // entry as long as the value written is not too large, but can differ.
232 // This kind of complication does not occur for positive type ids because
233 // type infos are output using a fixed width encoding.
234 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
235 SmallVector FilterOffsets;
236 FilterOffsets.reserve(FilterIds.size());
237 int Offset = -1;
238 for(std::vector::const_iterator I = FilterIds.begin(),
239 E = FilterIds.end(); I != E; ++I) {
240 FilterOffsets.push_back(Offset);
241 Offset -= AsmPrinter::SizeULEB128(*I);
242 }
243
244 // Compute the actions table and gather the first action index for each
245 // landing pad site.
246 SmallVector Actions;
247 SmallVector FirstActions;
248 FirstActions.reserve(LandingPads.size());
249
250 int FirstAction = 0;
251 unsigned SizeActions = 0;
252 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
253 const LandingPadInfo *LP = LandingPads[i];
254 const std::vector &TypeIds = LP->TypeIds;
255 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
256 unsigned SizeSiteActions = 0;
257
258 if (NumShared < TypeIds.size()) {
259 unsigned SizeAction = 0;
260 ActionEntry *PrevAction = 0;
261
262 if (NumShared) {
263 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
264 assert(Actions.size());
265 PrevAction = &Actions.back();
266 SizeAction = AsmPrinter::SizeSLEB128(PrevAction->NextAction) +
267 AsmPrinter::SizeSLEB128(PrevAction->ValueForTypeID);
268 for (unsigned j = NumShared; j != SizePrevIds; ++j) {
269 SizeAction -= AsmPrinter::SizeSLEB128(PrevAction->ValueForTypeID);
270 SizeAction += -PrevAction->NextAction;
271 PrevAction = PrevAction->Previous;
272 }
273 }
274
275 // Compute the actions.
276 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
277 int TypeID = TypeIds[I];
278 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
279 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
280 unsigned SizeTypeID = AsmPrinter::SizeSLEB128(ValueForTypeID);
281
282 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
283 SizeAction = SizeTypeID + AsmPrinter::SizeSLEB128(NextAction);
284 SizeSiteActions += SizeAction;
285
286 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
287 Actions.push_back(Action);
288
289 PrevAction = &Actions.back();
290 }
291
292 // Record the first action of the landing pad site.
293 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
294 } // else identical - re-use previous FirstAction
295
296 FirstActions.push_back(FirstAction);
297
298 // Compute this sites contribution to size.
299 SizeActions += SizeSiteActions;
300 }
301
302 // Compute the call-site table. Entries must be ordered by address.
303 SmallVector CallSites;
304
305 RangeMapType PadMap;
306 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
307 const LandingPadInfo *LandingPad = LandingPads[i];
308 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
309 unsigned BeginLabel = LandingPad->BeginLabels[j];
310 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
311 PadRange P = { i, j };
312 PadMap[BeginLabel] = P;
313 }
314 }
315
316 bool MayThrow = false;
317 unsigned LastLabel = 0;
318 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
319 I != E; ++I) {
320 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
321 MI != E; ++MI) {
322 if (MI->getOpcode() != TargetInstrInfo::LABEL) {
323 MayThrow |= MI->getDesc().isCall();
324 continue;
325 }
326
327 unsigned BeginLabel = MI->getOperand(0).getImm();
328 assert(BeginLabel && "Invalid label!");
329
330 if (BeginLabel == LastLabel)
331 MayThrow = false;
332
333 RangeMapType::iterator L = PadMap.find(BeginLabel);
334
335 if (L == PadMap.end())
336 continue;
337
338 PadRange P = L->second;
339 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
340
341 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
342 "Inconsistent landing pad map!");
343
344 // If some instruction between the previous try-range and this one may
345 // throw, create a call-site entry with no landing pad for the region
346 // between the try-ranges.
347 if (MayThrow) {
348 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
349 CallSites.push_back(Site);
350 }
351
352 LastLabel = LandingPad->EndLabels[P.RangeIndex];
353 CallSiteEntry Site = {BeginLabel, LastLabel,
354 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
355
356 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
357 "Invalid landing pad!");
358
359 // Try to merge with the previous call-site.
360 if (CallSites.size()) {
361 CallSiteEntry &Prev = CallSites[CallSites.size()-1];
362 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
363 // Extend the range of the previous entry.
364 Prev.EndLabel = Site.EndLabel;
365 continue;
366 }
367 }
368
369 // Otherwise, create a new call-site.
370 CallSites.push_back(Site);
371 }
372 }
373 // If some instruction between the previous try-range and the end of the
374 // function may throw, create a call-site entry with no landing pad for the
375 // region following the try-range.
376 if (MayThrow) {
377 CallSiteEntry Site = {LastLabel, 0, 0, 0};
378 CallSites.push_back(Site);
379 }
380
381 // Final tallies.
382 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
383 sizeof(int32_t) + // Site length.
384 sizeof(int32_t)); // Landing pad.
385 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
386 SizeSites += AsmPrinter::SizeULEB128(CallSites[i].Action);
387
388 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
389
390 unsigned TypeOffset = sizeof(int8_t) + // Call site format
391 // Call-site table length
392 AsmPrinter::SizeULEB128(SizeSites) +
393 SizeSites + SizeActions + SizeTypes;
394
395 unsigned TotalSize = sizeof(int8_t) + // LPStart format
396 sizeof(int8_t) + // TType format
397 AsmPrinter::SizeULEB128(TypeOffset) + // TType base offset
398 TypeOffset;
399
400 unsigned SizeAlign = (4 - TotalSize) & 3;
401
402 // Begin the exception table.
403 MCE->emitAlignment(4);
404 for (unsigned i = 0; i != SizeAlign; ++i) {
405 MCE->emitByte(0);
406 // Asm->EOL("Padding");
407 }
408
409 unsigned char* DwarfExceptionTable = (unsigned char*)MCE->getCurrentPCValue();
410
411 // Emit the header.
412 MCE->emitByte(dwarf::DW_EH_PE_omit);
413 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
414 MCE->emitByte(dwarf::DW_EH_PE_absptr);
415 // Asm->EOL("TType format (DW_EH_PE_absptr)");
416 MCE->emitULEB128Bytes(TypeOffset);
417 // Asm->EOL("TType base offset");
418 MCE->emitByte(dwarf::DW_EH_PE_udata4);
419 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
420 MCE->emitULEB128Bytes(SizeSites);
421 // Asm->EOL("Call-site table length");
422
423 // Emit the landing pad site information.
424 for (unsigned i = 0; i < CallSites.size(); ++i) {
425 CallSiteEntry &S = CallSites[i];
426 intptr_t BeginLabelPtr = 0;
427 intptr_t EndLabelPtr = 0;
428
429 if (!S.BeginLabel) {
430 BeginLabelPtr = (intptr_t)StartFunction;
431 if (TD->getPointerSize() == sizeof(int32_t))
432 MCE->emitInt32(0);
433 else
434 MCE->emitInt64(0);
435 } else {
436 BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel);
437 if (TD->getPointerSize() == sizeof(int32_t))
438 MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
439 else
440 MCE->emitInt64(BeginLabelPtr - (intptr_t)StartFunction);
441 }
442
443 // Asm->EOL("Region start");
444
445 if (!S.EndLabel) {
446 EndLabelPtr = (intptr_t)EndFunction;
447 if (TD->getPointerSize() == sizeof(int32_t))
448 MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
449 else
450 MCE->emitInt64((intptr_t)EndFunction - BeginLabelPtr);
451 } else {
452 EndLabelPtr = MCE->getLabelAddress(S.EndLabel);
453 if (TD->getPointerSize() == sizeof(int32_t))
454 MCE->emitInt32(EndLabelPtr - BeginLabelPtr);
455 else
456 MCE->emitInt64(EndLabelPtr - BeginLabelPtr);
457 }
458 //Asm->EOL("Region length");
459
460 if (!S.PadLabel) {
461 if (TD->getPointerSize() == sizeof(int32_t))
462 MCE->emitInt32(0);
463 else
464 MCE->emitInt64(0);
465 } else {
466 unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel);
467 if (TD->getPointerSize() == sizeof(int32_t))
468 MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
469 else
470 MCE->emitInt64(PadLabelPtr - (intptr_t)StartFunction);
471 }
472 // Asm->EOL("Landing pad");
473
474 MCE->emitULEB128Bytes(S.Action);
475 // Asm->EOL("Action");
476 }
477
478 // Emit the actions.
479 for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
480 ActionEntry &Action = Actions[I];
481
482 MCE->emitSLEB128Bytes(Action.ValueForTypeID);
483 //Asm->EOL("TypeInfo index");
484 MCE->emitSLEB128Bytes(Action.NextAction);
485 //Asm->EOL("Next action");
486 }
487
488 // Emit the type ids.
489 for (unsigned M = TypeInfos.size(); M; --M) {
490 GlobalVariable *GV = TypeInfos[M - 1];
491
492 if (GV) {
493 if (TD->getPointerSize() == sizeof(int32_t)) {
494 MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
495 } else {
496 MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
497 }
498 } else {
499 if (TD->getPointerSize() == sizeof(int32_t))
500 MCE->emitInt32(0);
501 else
502 MCE->emitInt64(0);
503 }
504 // Asm->EOL("TypeInfo");
505 }
506
507 // Emit the filter typeids.
508 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
509 unsigned TypeID = FilterIds[j];
510 MCE->emitULEB128Bytes(TypeID);
511 //Asm->EOL("Filter TypeInfo index");
512 }
513
514 MCE->emitAlignment(4);
515
516 return DwarfExceptionTable;
517 }
518
519 unsigned char* JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) {
520 unsigned PointerSize = TD->getPointerSize();
521 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
522 PointerSize : -PointerSize;
523
524 unsigned char* StartCommonPtr = (unsigned char*)MCE->getCurrentPCValue();
525 // EH Common Frame header
526 MCE->allocateSpace(PointerSize, 0);
527 unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
528 MCE->emitInt32((int)0);
529 MCE->emitByte(dwarf::DW_CIE_VERSION);
530 MCE->emitString(Personality ? "zPLR" : "zR");
531 MCE->emitULEB128Bytes(1);
532 MCE->emitSLEB128Bytes(stackGrowth);
533 MCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
534
535 if (Personality) {
536 MCE->emitULEB128Bytes(7);
537
538 if (needsIndirectEncoding)
539 MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
540 dwarf::DW_EH_PE_indirect);
541 else
542 MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
543
544 if (PointerSize == 8)
545 MCE->emitInt64((intptr_t)Jit.getPointerToGlobal(Personality) -
546 MCE->getCurrentPCValue());
547 else
548 MCE->emitInt32((intptr_t)Jit.getPointerToGlobal(Personality) -
549 MCE->getCurrentPCValue());
550
551 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
552 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
553
554 } else {
555 MCE->emitULEB128Bytes(1);
556 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
557 }
558
559 std::vector Moves;
560 RI->getInitialFrameState(Moves);
561 EmitFrameMoves(0, Moves);
562 MCE->emitAlignment(4);
563
564 MCE->emitAt((uintptr_t*)StartCommonPtr,
565 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
566 FrameCommonBeginPtr));
567
568 return StartCommonPtr;
569 }
570
571
572 unsigned char* JITDwarfEmitter::EmitEHFrame(const Function* Personality,
573 unsigned char* StartCommonPtr,
574 unsigned char* StartFunction,
575 unsigned char* EndFunction,
576 unsigned char* ExceptionTable) {
577 unsigned PointerSize = TD->getPointerSize();
578
579 // EH frame header.
580 unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue();
581 MCE->allocateSpace(PointerSize, 0);
582 unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
583 // FDE CIE Offset
584 if (PointerSize == 8) {
585 MCE->emitInt64(FrameBeginPtr - StartCommonPtr);
586 MCE->emitInt64(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
587 MCE->emitInt64(EndFunction - StartFunction);
588 } else {
589 MCE->emitInt32(FrameBeginPtr - StartCommonPtr);
590 MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
591 MCE->emitInt32(EndFunction - StartFunction);
592 }
593
594 // If there is a personality and landing pads then point to the language
595 // specific data area in the exception table.
596 if (MMI->getPersonalityIndex()) {
597 MCE->emitULEB128Bytes(4);
598
599 if (!MMI->getLandingPads().empty()) {
600 if (PointerSize == 8)
601 MCE->emitInt64(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
602 else
603 MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
604 } else if (PointerSize == 8) {
605 MCE->emitInt64((int)0);
606 } else {
607 MCE->emitInt32((int)0);
608 }
609 } else {
610 MCE->emitULEB128Bytes(0);
611 }
612
613 // Indicate locations of function specific callee saved registers in
614 // frame.
615 EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
616
617 MCE->emitAlignment(4);
618
619 // Indicate the size of the table
620 MCE->emitAt((uintptr_t*)StartEHPtr,
621 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
622 StartEHPtr));
623
624 // Double zeroes for the unwind runtime
625 if (PointerSize == 8) {
626 MCE->emitInt64(0);
627 MCE->emitInt64(0);
628 } else {
629 MCE->emitInt32(0);
630 MCE->emitInt32(0);
631 }
632
633
634 return StartEHPtr;
635 }
0 //===------ JITDwarfEmitter.h - Write dwarf tables into memory ------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a JITDwarfEmitter object that is used by the JIT to
10 // write dwarf tables to memory.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
15 #define LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
16
17 namespace llvm {
18
19 class Function;
20 class MachineCodeEmitter;
21 class MachineFunction;
22 class MachineModuleInfo;
23 class MachineMove;
24 class TargetData;
25 class TargetMachine;
26 class TargetRegisterInfo;
27
28 class JITDwarfEmitter {
29 const TargetData* TD;
30 MachineCodeEmitter* MCE;
31 const TargetRegisterInfo* RI;
32 MachineModuleInfo* MMI;
33 JIT& Jit;
34 bool needsIndirectEncoding;
35 bool stackGrowthDirection;
36
37 public:
38 JITDwarfEmitter(JIT& jit);
39
40 unsigned char* EmitExceptionTable(MachineFunction* MF,
41 unsigned char* StartFunction,
42 unsigned char* EndFunction);
43
44 void EmitFrameMoves(intptr_t BaseLabelPtr,
45 const std::vector &Moves);
46
47 unsigned char* EmitCommonEHFrame(const Function* Personality);
48
49 unsigned char* EmitEHFrame(const Function* Personality,
50 unsigned char* StartBufferPtr,
51 unsigned char* StartFunction,
52 unsigned char* EndFunction,
53 unsigned char* ExceptionTable);
54
55
56 unsigned char* EmitDwarfTable(MachineFunction& F,
57 MachineCodeEmitter& MCE,
58 unsigned char* StartFunction,
59 unsigned char* EndFunction);
60
61 void setModuleInfo(MachineModuleInfo* Info) {
62 MMI = Info;
63 }
64 };
65
66 } // end namespace llvm
67
68 #endif // LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
1313
1414 #define DEBUG_TYPE "jit"
1515 #include "JIT.h"
16 #include "JITDwarfEmitter.h"
1617 #include "llvm/Constant.h"
1718 #include "llvm/Module.h"
1819 #include "llvm/Type.h"
2021 #include "llvm/CodeGen/MachineFunction.h"
2122 #include "llvm/CodeGen/MachineConstantPool.h"
2223 #include "llvm/CodeGen/MachineJumpTableInfo.h"
24 #include "llvm/CodeGen/MachineModuleInfo.h"
2325 #include "llvm/CodeGen/MachineRelocation.h"
2426 #include "llvm/ExecutionEngine/JITMemoryManager.h"
2527 #include "llvm/Target/TargetData.h"
2628 #include "llvm/Target/TargetJITInfo.h"
2729 #include "llvm/Target/TargetMachine.h"
30 #include "llvm/Target/TargetOptions.h"
2831 #include "llvm/Support/Debug.h"
2932 #include "llvm/Support/MutexGuard.h"
3033 #include "llvm/System/Disassembler.h"
335338
336339 /// Resolver - This contains info about the currently resolved functions.
337340 JITResolver Resolver;
341
342 /// DE - The dwarf emitter for the jit.
343 JITDwarfEmitter *DE;
344
345 /// LabelLocations - This vector is a mapping from Label ID's to their
346 /// address.
347 std::vector LabelLocations;
348
349 /// MMI - Machine module info for exception informations
350 MachineModuleInfo* MMI;
351
338352 public:
339353 JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit) {
340354 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
342356 MemMgr->AllocateGOT();
343357 DOUT << "JIT is managing a GOT\n";
344358 }
359
360 if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
345361 }
346362 ~JITEmitter() {
347363 delete MemMgr;
364 if (ExceptionHandling) delete DE;
348365 }
349366
350367 JITResolver &getJITResolver() { return Resolver; }
383400 void deallocateMemForFunction(Function *F) {
384401 MemMgr->deallocateMemForFunction(F);
385402 }
403
404 virtual void emitLabel(uint64_t LabelID) {
405 if (LabelLocations.size() <= LabelID)
406 LabelLocations.resize((LabelID+1)*2);
407 LabelLocations[LabelID] = getCurrentPCValue();
408 }
409
410 virtual intptr_t getLabelAddress(uint64_t LabelID) const {
411 assert(LabelLocations.size() > (unsigned)LabelID &&
412 LabelLocations[LabelID] && "Label not emitted!");
413 return LabelLocations[LabelID];
414 }
415
416 virtual void setModuleInfo(MachineModuleInfo* Info) {
417 MMI = Info;
418 if (ExceptionHandling) DE->setModuleInfo(Info);
419 }
420
386421 private:
387422 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
388423 void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
543578 DOUT << "Disassembled code:\n"
544579 << sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart);
545580 #endif
546
581 if (ExceptionHandling) {
582 uintptr_t ActualSize;
583 SavedBufferBegin = BufferBegin;
584 SavedBufferEnd = BufferEnd;
585 SavedCurBufferPtr = CurBufferPtr;
586
587 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
588 ActualSize);
589 BufferEnd = BufferBegin+ActualSize;
590 unsigned char* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd);
591 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, FrameRegister);
592 BufferBegin = SavedBufferBegin;
593 BufferEnd = SavedBufferEnd;
594 CurBufferPtr = SavedCurBufferPtr;
595
596 TheJIT->RegisterTable(FrameRegister);
597 }
598 MMI->EndFunction();
599
547600 return false;
548601 }
549602
255255 sys::MemoryBlock getNewMemoryBlock(unsigned size);
256256
257257 std::map FunctionBlocks;
258 std::map TableBlocks;
258259 public:
259260 DefaultJITMemoryManager();
260261 ~DefaultJITMemoryManager();
289290 FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
290291 }
291292
293 /// startExceptionTable - Use startFunctionBody to allocate memory for the
294 /// function's exception table.
295 unsigned char* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
296 return startFunctionBody(F, ActualSize);
297 }
298
299 /// endExceptionTable - The exception table of F is now allocated,
300 /// and takes the memory in the range [TableStart,TableEnd).
301 void endExceptionTable(const Function *F, unsigned char *TableStart,
302 unsigned char *TableEnd,
303 unsigned char* FrameRegister) {
304 assert(TableEnd > TableStart);
305 assert(TableStart == (unsigned char *)(CurBlock+1) &&
306 "Mismatched table start/end!");
307
308 uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock;
309 TableBlocks[F] = CurBlock;
310
311 // Release the memory at the end of this block that isn't needed.
312 FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
313 }
314
292315 unsigned char *getGOTBase() const {
293316 return GOTBase;
294317 }
314337
315338 // Finally, remove this entry from FunctionBlocks.
316339 FunctionBlocks.erase(I);
340
341 I = TableBlocks.find(F);
342 if (I == TableBlocks.end()) return;
343
344 // Find the block that is allocated for this function.
345 MemRange = I->second;
346 assert(MemRange->ThisAllocated && "Block isn't allocated!");
347
348 // Fill the buffer with garbage!
349 #ifndef NDEBUG
350 memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange));
351 #endif
352
353 // Free the memory.
354 FreeMemoryList = MemRange->FreeBlock(FreeMemoryList);
355
356 // Finally, remove this entry from TableBlocks.
357 TableBlocks.erase(I);
317358 }
318359 };
319360 }
1919 #include "llvm/CodeGen/MachineCodeEmitter.h"
2020 #include "llvm/CodeGen/MachineFunctionPass.h"
2121 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
2223 #include "llvm/CodeGen/Passes.h"
2324 #include "llvm/Support/Debug.h"
2425 #include "llvm/Support/Compiler.h"
3738 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
3839 ///
3940 int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
41
42 void getAnalysisUsage(AnalysisUsage &AU) const {
43 AU.addRequired();
44 MachineFunctionPass::getAnalysisUsage(AU);
45 }
4046
4147 public:
4248 static char ID;
8187 assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
8288 MF.getTarget().getRelocationModel() != Reloc::Static) &&
8389 "JIT relocation model must be set to static or default!");
90
91 MCE.setModuleInfo(&getAnalysis());
8492 do {
8593 MovePCtoLROffset = 0;
8694 MCE.startFunction(MF);
99107 switch (MI.getOpcode()) {
100108 default:
101109 MCE.emitWordBE(getBinaryCodeForInstr(*I));
110 break;
111 case TargetInstrInfo::LABEL:
112 MCE.emitLabel(MI.getOperand(0).getImm());
102113 break;
103114 case PPC::IMPLICIT_DEF_GPRC:
104115 case PPC::IMPLICIT_DEF_G8RC:
2222 #include "llvm/CodeGen/MachineCodeEmitter.h"
2323 #include "llvm/CodeGen/MachineFunctionPass.h"
2424 #include "llvm/CodeGen/MachineInstr.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
2526 #include "llvm/CodeGen/Passes.h"
2627 #include "llvm/Function.h"
2728 #include "llvm/ADT/Statistic.h"
6061
6162 void emitInstruction(const MachineInstr &MI,
6263 const TargetInstrDesc *Desc);
64
65 void getAnalysisUsage(AnalysisUsage &AU) const {
66 AU.addRequired();
67 MachineFunctionPass::getAnalysisUsage(AU);
68 }
6369
6470 private:
6571 void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
103109 assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
104110 MF.getTarget().getRelocationModel() != Reloc::Static) &&
105111 "JIT relocation model must be set to static or default!");
112
113 MCE.setModuleInfo(&getAnalysis());
114
106115 II = ((X86TargetMachine&)TM).getInstrInfo();
107116 TD = ((X86TargetMachine&)TM).getTargetData();
108117 Is64BitMode = TM.getSubtarget().is64Bit();
109
118
110119 do {
111120 MCE.startFunction(MF);
112121 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
595604 // Remember the current PC offset, this is the PIC relocation
596605 // base address.
597606 switch (Opcode) {
598 #ifndef NDEBUG
599607 default:
600608 assert(0 && "psuedo instructions should be removed before code emission");
601609 case TargetInstrInfo::INLINEASM:
602610 assert(0 && "JIT does not support inline asm!\n");
603611 case TargetInstrInfo::LABEL:
604 assert(0 && "JIT does not support meta labels!\n");
612 MCE.emitLabel(MI.getOperand(0).getImm());
613 break;
605614 case X86::IMPLICIT_DEF_GR8:
606615 case X86::IMPLICIT_DEF_GR16:
607616 case X86::IMPLICIT_DEF_GR32:
612621 case X86::IMPLICIT_DEF_VR128:
613622 case X86::FP_REG_KILL:
614623 break;
615 #endif
616624 case X86::MOVPC32r: {
617625 // This emits the "call" portion of this pseudo instruction.
618626 MCE.emitByte(BaseOpcode);
626634 }
627635 CurOp = NumOps;
628636 break;
629
630637 case X86II::RawFrm:
631638 MCE.emitByte(BaseOpcode);
632639