Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(50)

Delta Between Two Patch Sets: lib/ExecutionEngine/JIT/JITEmitter.cpp

Issue 91042: Implement LLVM JIT side of GDB JIT debugging interface (Closed) SVN Base: http://llvm.org/svn/llvm-project/llvm/trunk/
Left Patch Set: Created 5 months ago
Right Patch Set: Synced with TOT. Created 2 months, 2 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 //===-- JITEmitter.cpp - Write machine code to executable memory ----------===// 1 //===-- JITEmitter.cpp - Write machine code to executable memory ----------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file defines a MachineCodeEmitter object that is used by the JIT to 10 // This file defines a MachineCodeEmitter object that is used by the JIT to
11 // write machine code to memory and remember where relocatable values are. 11 // write machine code to memory and remember where relocatable values are.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #define DEBUG_TYPE "jit" 15 #define DEBUG_TYPE "jit"
16 #include "JIT.h" 16 #include "JIT.h"
17 #include "JITDebugRegisterer.h" 17 #include "JITDebugRegisterer.h"
18 #include "JITDwarfEmitter.h" 18 #include "JITDwarfEmitter.h"
19 #include "llvm/ADT/OwningPtr.h"
19 #include "llvm/Constants.h" 20 #include "llvm/Constants.h"
20 #include "llvm/Function.h"
nlewycky 2009/07/04 01:27:07 Why did you add this #include? It doesn't look lik
Reid Kleckner 2009/07/06 21:07:01 On 2009/07/04 01:27:07, nlewycky wrote: > Why did
21 #include "llvm/Module.h" 21 #include "llvm/Module.h"
22 #include "llvm/DerivedTypes.h" 22 #include "llvm/DerivedTypes.h"
23 #include "llvm/CodeGen/JITCodeEmitter.h" 23 #include "llvm/CodeGen/JITCodeEmitter.h"
24 #include "llvm/CodeGen/MachineFunction.h" 24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineConstantPool.h" 25 #include "llvm/CodeGen/MachineConstantPool.h"
26 #include "llvm/CodeGen/MachineJumpTableInfo.h" 26 #include "llvm/CodeGen/MachineJumpTableInfo.h"
27 #include "llvm/CodeGen/MachineModuleInfo.h" 27 #include "llvm/CodeGen/MachineModuleInfo.h"
28 #include "llvm/CodeGen/MachineRelocation.h" 28 #include "llvm/CodeGen/MachineRelocation.h"
29 #include "llvm/ExecutionEngine/GenericValue.h" 29 #include "llvm/ExecutionEngine/GenericValue.h"
30 #include "llvm/ExecutionEngine/JITEventListener.h" 30 #include "llvm/ExecutionEngine/JITEventListener.h"
31 #include "llvm/ExecutionEngine/JITMemoryManager.h" 31 #include "llvm/ExecutionEngine/JITMemoryManager.h"
32 #include "llvm/CodeGen/MachineCodeInfo.h" 32 #include "llvm/CodeGen/MachineCodeInfo.h"
33 #include "llvm/Target/TargetData.h" 33 #include "llvm/Target/TargetData.h"
34 #include "llvm/Target/TargetJITInfo.h" 34 #include "llvm/Target/TargetJITInfo.h"
35 #include "llvm/Target/TargetMachine.h" 35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Target/TargetOptions.h" 36 #include "llvm/Target/TargetOptions.h"
37 #include "llvm/Support/Debug.h" 37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Support/MutexGuard.h" 39 #include "llvm/Support/MutexGuard.h"
39 #include "llvm/Support/ValueHandle.h" 40 #include "llvm/Support/ValueHandle.h"
41 #include "llvm/Support/raw_ostream.h"
40 #include "llvm/System/Disassembler.h" 42 #include "llvm/System/Disassembler.h"
41 #include "llvm/System/Memory.h" 43 #include "llvm/System/Memory.h"
42 #include "llvm/Target/TargetInstrInfo.h" 44 #include "llvm/Target/TargetInstrInfo.h"
43 #include "llvm/ADT/SmallPtrSet.h" 45 #include "llvm/ADT/SmallPtrSet.h"
44 #include "llvm/ADT/SmallVector.h" 46 #include "llvm/ADT/SmallVector.h"
45 #include "llvm/ADT/Statistic.h" 47 #include "llvm/ADT/Statistic.h"
46 #include <algorithm> 48 #include <algorithm>
47 #ifndef NDEBUG 49 #ifndef NDEBUG
48 #include <iomanip> 50 #include <iomanip>
49 #endif 51 #endif
50 using namespace llvm; 52 using namespace llvm;
51 53
52 STATISTIC(NumBytes, "Number of bytes of machine code compiled"); 54 STATISTIC(NumBytes, "Number of bytes of machine code compiled");
53 STATISTIC(NumRelos, "Number of relocations applied"); 55 STATISTIC(NumRelos, "Number of relocations applied");
56 STATISTIC(NumRetries, "Number of retries with more memory");
54 static JIT *TheJIT = 0; 57 static JIT *TheJIT = 0;
55 58
56 59
57 //===----------------------------------------------------------------------===// 60 //===----------------------------------------------------------------------===//
58 // JIT lazy compilation code. 61 // JIT lazy compilation code.
59 // 62 //
60 namespace { 63 namespace {
61 class JITResolverState { 64 class JITResolverState {
62 public: 65 public:
63 typedef std::map<AssertingVH<Function>, void*> FunctionToStubMapTy; 66 typedef std::map<AssertingVH<Function>, void*> FunctionToStubMapTy;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, 218 Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual,
216 *TheJIT->getCodeEmitter()); 219 *TheJIT->getCodeEmitter());
217 220
218 if (Actual != (void*)(intptr_t)LazyResolverFn) { 221 if (Actual != (void*)(intptr_t)LazyResolverFn) {
219 // If we are getting the stub for an external function, we really want the 222 // If we are getting the stub for an external function, we really want the
220 // address of the stub in the GlobalAddressMap for the JIT, not the address 223 // address of the stub in the GlobalAddressMap for the JIT, not the address
221 // of the external function. 224 // of the external function.
222 TheJIT->updateGlobalMapping(F, Stub); 225 TheJIT->updateGlobalMapping(F, Stub);
223 } 226 }
224 227
225 DOUT << "JIT: Stub emitted at [" << Stub << "] for function '" 228 DEBUG(errs() << "JIT: Stub emitted at [" << Stub << "] for function '"
226 << F->getName() << "'\n"; 229 << F->getName() << "'\n");
227 230
228 // Finally, keep track of the stub-to-Function mapping so that the 231 // Finally, keep track of the stub-to-Function mapping so that the
229 // JITCompilerFn knows which function to compile! 232 // JITCompilerFn knows which function to compile!
230 state.getStubToFunctionMap(locked)[Stub] = F; 233 state.getStubToFunctionMap(locked)[Stub] = F;
231 234
232 // If we are JIT'ing non-lazily but need to call a function that does not 235 // If we are JIT'ing non-lazily but need to call a function that does not
233 // exist yet, add it to the JIT's work list so that we can fill in the stub 236 // exist yet, add it to the JIT's work list so that we can fill in the stub
234 // address later. 237 // address later.
235 if (!Actual && TheJIT->isLazyCompilationDisabled()) 238 if (!Actual && TheJIT->isLazyCompilationDisabled())
236 if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode()) 239 if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode())
237 TheJIT->addPendingFunction(F); 240 TheJIT->addPendingFunction(F);
238 241
239 return Stub; 242 return Stub;
240 } 243 }
241 244
242 /// getGlobalValueIndirectSym - Return a lazy pointer containing the specified 245 /// getGlobalValueIndirectSym - Return a lazy pointer containing the specified
243 /// GV address. 246 /// GV address.
244 void *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) { 247 void *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) {
245 MutexGuard locked(TheJIT->lock); 248 MutexGuard locked(TheJIT->lock);
246 249
247 // If we already have a stub for this global variable, recycle it. 250 // If we already have a stub for this global variable, recycle it.
248 void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV]; 251 void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV];
249 if (IndirectSym) return IndirectSym; 252 if (IndirectSym) return IndirectSym;
250 253
251 // Otherwise, codegen a new indirect symbol. 254 // Otherwise, codegen a new indirect symbol.
252 IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress, 255 IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress,
253 *TheJIT->getCodeEmitter()); 256 *TheJIT->getCodeEmitter());
254 257
255 DOUT << "JIT: Indirect symbol emitted at [" << IndirectSym << "] for GV '" 258 DEBUG(errs() << "JIT: Indirect symbol emitted at [" << IndirectSym
256 << GV->getName() << "'\n"; 259 << "] for GV '" << GV->getName() << "'\n");
257 260
258 return IndirectSym; 261 return IndirectSym;
259 } 262 }
260 263
261 /// getExternalFunctionStub - Return a stub for the function at the 264 /// getExternalFunctionStub - Return a stub for the function at the
262 /// specified address, created lazily on demand. 265 /// specified address, created lazily on demand.
263 void *JITResolver::getExternalFunctionStub(void *FnAddr) { 266 void *JITResolver::getExternalFunctionStub(void *FnAddr) {
264 // If we already have a stub for this function, recycle it. 267 // If we already have a stub for this function, recycle it.
265 void *&Stub = ExternalFnToStubMap[FnAddr]; 268 void *&Stub = ExternalFnToStubMap[FnAddr];
266 if (Stub) return Stub; 269 if (Stub) return Stub;
267 270
268 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, 271 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr,
269 *TheJIT->getCodeEmitter()); 272 *TheJIT->getCodeEmitter());
270 273
271 DOUT << "JIT: Stub emitted at [" << Stub 274 DEBUG(errs() << "JIT: Stub emitted at [" << Stub
272 << "] for external function at '" << FnAddr << "'\n"; 275 << "] for external function at '" << FnAddr << "'\n");
273 return Stub; 276 return Stub;
274 } 277 }
275 278
276 unsigned JITResolver::getGOTIndexForAddr(void* addr) { 279 unsigned JITResolver::getGOTIndexForAddr(void* addr) {
277 unsigned idx = revGOTMap[addr]; 280 unsigned idx = revGOTMap[addr];
278 if (!idx) { 281 if (!idx) {
279 idx = ++nextGOTIndex; 282 idx = ++nextGOTIndex;
280 revGOTMap[addr] = idx; 283 revGOTMap[addr] = idx;
281 DOUT << "JIT: Adding GOT entry " << idx << " for addr [" << addr << "]\n"; 284 DEBUG(errs() << "JIT: Adding GOT entry " << idx << " for addr ["
285 << addr << "]\n");
282 } 286 }
283 return idx; 287 return idx;
284 } 288 }
285 289
286 void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs, 290 void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
287 SmallVectorImpl<void*> &Ptrs) { 291 SmallVectorImpl<void*> &Ptrs) {
288 MutexGuard locked(TheJIT->lock); 292 MutexGuard locked(TheJIT->lock);
289 293
290 FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked); 294 FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked);
291 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked); 295 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 } 372 }
369 373
370 // If we have already code generated the function, just return the address. 374 // If we have already code generated the function, just return the address.
371 void *Result = TheJIT->getPointerToGlobalIfAvailable(F); 375 void *Result = TheJIT->getPointerToGlobalIfAvailable(F);
372 376
373 if (!Result) { 377 if (!Result) {
374 // Otherwise we don't have it, do lazy compilation now. 378 // Otherwise we don't have it, do lazy compilation now.
375 379
376 // If lazy compilation is disabled, emit a useful error message and abort. 380 // If lazy compilation is disabled, emit a useful error message and abort.
377 if (TheJIT->isLazyCompilationDisabled()) { 381 if (TheJIT->isLazyCompilationDisabled()) {
378 cerr << "LLVM JIT requested to do lazy compilation of function '" 382 llvm_report_error("LLVM JIT requested to do lazy compilation of function ' "
379 << F->getName() << "' when lazy compiles are disabled!\n"; 383 + F->getName() + "' when lazy compiles are disabled!");
380 abort();
381 } 384 }
382 385
383 // We might like to remove the stub from the StubToFunction map. 386 // We might like to remove the stub from the StubToFunction map.
384 // We can't do that! Multiple threads could be stuck, waiting to acquire the 387 // We can't do that! Multiple threads could be stuck, waiting to acquire the
385 // lock above. As soon as the 1st function finishes compiling the function, 388 // lock above. As soon as the 1st function finishes compiling the function,
386 // the next one will be released, and needs to be able to find the function 389 // the next one will be released, and needs to be able to find the function
387 // it needs to call. 390 // it needs to call.
388 //JR.state.getStubToFunctionMap(locked).erase(I); 391 //JR.state.getStubToFunctionMap(locked).erase(I);
389 392
390 DOUT << "JIT: Lazily resolving function '" << F->getName() 393 DEBUG(errs() << "JIT: Lazily resolving function '" << F->getName()
391 << "' In stub ptr = " << Stub << " actual ptr = " 394 << "' In stub ptr = " << Stub << " actual ptr = "
392 << ActualPtr << "\n"; 395 << ActualPtr << "\n");
393 396
394 Result = TheJIT->getPointerToFunction(F); 397 Result = TheJIT->getPointerToFunction(F);
395 } 398 }
396 399
397 // Reacquire the lock to erase the stub in the map. 400 // Reacquire the lock to erase the stub in the map.
398 MutexGuard locked(TheJIT->lock); 401 MutexGuard locked(TheJIT->lock);
399 402
400 // We don't need to reuse this stub in the future, as F is now compiled. 403 // We don't need to reuse this stub in the future, as F is now compiled.
401 JR.state.getFunctionToStubMap(locked).erase(F); 404 JR.state.getFunctionToStubMap(locked).erase(F);
402 405
(...skipping 16 matching lines...) Expand all
419 namespace { 422 namespace {
420 /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is 423 /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is
421 /// used to output functions to memory for execution. 424 /// used to output functions to memory for execution.
422 class JITEmitter : public JITCodeEmitter { 425 class JITEmitter : public JITCodeEmitter {
423 JITMemoryManager *MemMgr; 426 JITMemoryManager *MemMgr;
424 427
425 // When outputting a function stub in the context of some other function, we 428 // When outputting a function stub in the context of some other function, we
426 // save BufferBegin/BufferEnd/CurBufferPtr here. 429 // save BufferBegin/BufferEnd/CurBufferPtr here.
427 uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; 430 uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
428 431
432 // When reattempting to JIT a function after running out of space, we store
433 // the estimated size of the function we're trying to JIT here, so we can
434 // ask the memory manager for at least this much space. When we
435 // successfully emit the function, we reset this back to zero.
436 uintptr_t SizeEstimate;
437
429 /// Relocations - These are the relocations that the function needs, as 438 /// Relocations - These are the relocations that the function needs, as
430 /// emitted. 439 /// emitted.
431 std::vector<MachineRelocation> Relocations; 440 std::vector<MachineRelocation> Relocations;
432 441
433 /// MBBLocations - This vector is a mapping from MBB ID's to their address. 442 /// MBBLocations - This vector is a mapping from MBB ID's to their address.
434 /// It is filled in by the StartMachineBasicBlock callback and queried by 443 /// It is filled in by the StartMachineBasicBlock callback and queried by
435 /// the getMachineBasicBlockAddress callback. 444 /// the getMachineBasicBlockAddress callback.
436 std::vector<uintptr_t> MBBLocations; 445 std::vector<uintptr_t> MBBLocations;
437 446
438 /// ConstantPool - The constant pool for the current function. 447 /// ConstantPool - The constant pool for the current function.
(...skipping 13 matching lines...) Expand all
452 MachineJumpTableInfo *JumpTable; 461 MachineJumpTableInfo *JumpTable;
453 462
454 /// JumpTableBase - A pointer to the first entry in the jump table. 463 /// JumpTableBase - A pointer to the first entry in the jump table.
455 /// 464 ///
456 void *JumpTableBase; 465 void *JumpTableBase;
457 466
458 /// Resolver - This contains info about the currently resolved functions. 467 /// Resolver - This contains info about the currently resolved functions.
459 JITResolver Resolver; 468 JITResolver Resolver;
460 469
461 /// DE - The dwarf emitter for the jit. 470 /// DE - The dwarf emitter for the jit.
462 JITDwarfEmitter *DE; 471 OwningPtr<JITDwarfEmitter> DE;
463 472
464 /// DR - The debug registerer for the jit. 473 /// DR - The debug registerer for the jit.
465 JITDebugRegisterer *DR; 474 OwningPtr<JITDebugRegisterer> DR;
466 475
467 /// LabelLocations - This vector is a mapping from Label ID's to their 476 /// LabelLocations - This vector is a mapping from Label ID's to their
468 /// address. 477 /// address.
469 std::vector<uintptr_t> LabelLocations; 478 std::vector<uintptr_t> LabelLocations;
470 479
471 /// MMI - Machine module info for exception informations 480 /// MMI - Machine module info for exception informations
472 MachineModuleInfo* MMI; 481 MachineModuleInfo* MMI;
473 482
474 // GVSet - a set to keep track of which globals have been seen 483 // GVSet - a set to keep track of which globals have been seen
475 SmallPtrSet<const GlobalVariable*, 8> GVSet; 484 SmallPtrSet<const GlobalVariable*, 8> GVSet;
476 485
477 // CurFn - The llvm function being emitted. Only valid during 486 // CurFn - The llvm function being emitted. Only valid during
478 // finishFunction(). 487 // finishFunction().
479 const Function *CurFn; 488 const Function *CurFn;
480 489
490 /// Information about emitted code, which is passed to the
491 /// JITEventListeners. This is reset in startFunction and used in
492 /// finishFunction.
493 JITEvent_EmittedFunctionDetails EmissionDetails;
494
481 // CurFnStubUses - For a given Function, a vector of stubs that it 495 // CurFnStubUses - For a given Function, a vector of stubs that it
482 // references. This facilitates the JIT detecting that a stub is no 496 // references. This facilitates the JIT detecting that a stub is no
483 // longer used, so that it may be deallocated. 497 // longer used, so that it may be deallocated.
484 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses; 498 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses;
485 499
486 // StubFnRefs - For a given pointer to a stub, a set of Functions which 500 // StubFnRefs - For a given pointer to a stub, a set of Functions which
487 // reference the stub. When the count of a stub's references drops to zero, 501 // reference the stub. When the count of a stub's references drops to zero,
488 // the stub is unused. 502 // the stub is unused.
489 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; 503 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
490 504
491 // ExtFnStubs - A map of external function names to stubs which have entries 505 // ExtFnStubs - A map of external function names to stubs which have entries
492 // in the JITResolver's ExternalFnToStubMap. 506 // in the JITResolver's ExternalFnToStubMap.
493 StringMap<void *> ExtFnStubs; 507 StringMap<void *> ExtFnStubs;
494 508
509 DebugLocTuple PrevDLT;
510
495 public: 511 public:
496 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) 512 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
497 : Resolver(jit), CurFn(0) { 513 : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0) {
498 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 514 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
499 if (jit.getJITInfo().needsGOT()) { 515 if (jit.getJITInfo().needsGOT()) {
500 MemMgr->AllocateGOT(); 516 MemMgr->AllocateGOT();
501 DOUT << "JIT is managing a GOT\n"; 517 DEBUG(errs() << "JIT is managing a GOT\n");
502 } 518 }
503 519
504 if (ExceptionHandling || JitEmitDebugInfo) { 520 if (DwarfExceptionHandling || JITEmitDebugInfo) {
505 DE = new JITDwarfEmitter(jit); 521 DE.reset(new JITDwarfEmitter(jit));
506 } 522 }
507 if (JitEmitDebugInfo) { 523 if (JITEmitDebugInfo) {
508 DR = new JITDebugRegisterer(TM); 524 DR.reset(new JITDebugRegisterer(TM));
509 } 525 }
510 } 526 }
511
512 ~JITEmitter() { 527 ~JITEmitter() {
513 delete MemMgr; 528 delete MemMgr;
514 if (ExceptionHandling || JitEmitDebugInfo) {
Jeffrey Yasskin 2009/07/03 22:01:52 I don't like that the conditions have to match her
Reid Kleckner 2009/07/06 21:07:01 On 2009/07/03 22:01:52, Jeffrey Yasskin wrote: > I
515 delete DE;
516 }
517 if (JitEmitDebugInfo) {
518 delete DR;
519 }
520 } 529 }
521 530
522 /// classof - Methods for support type inquiry through isa, cast, and 531 /// classof - Methods for support type inquiry through isa, cast, and
523 /// dyn_cast: 532 /// dyn_cast:
524 /// 533 ///
525 static inline bool classof(const JITEmitter*) { return true; } 534 static inline bool classof(const JITEmitter*) { return true; }
526 static inline bool classof(const MachineCodeEmitter*) { return true; } 535 static inline bool classof(const MachineCodeEmitter*) { return true; }
527 536
528 JITResolver &getJITResolver() { return Resolver; } 537 JITResolver &getJITResolver() { return Resolver; }
529 538
530 virtual void startFunction(MachineFunction &F); 539 virtual void startFunction(MachineFunction &F);
531 virtual bool finishFunction(MachineFunction &F); 540 virtual bool finishFunction(MachineFunction &F);
532 541
533 void emitConstantPool(MachineConstantPool *MCP); 542 void emitConstantPool(MachineConstantPool *MCP);
534 void initJumpTableInfo(MachineJumpTableInfo *MJTI); 543 void initJumpTableInfo(MachineJumpTableInfo *MJTI);
535 void emitJumpTableInfo(MachineJumpTableInfo *MJTI); 544 void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
536 545
537 virtual void startGVStub(const GlobalValue* GV, unsigned StubSize, 546 virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
538 unsigned Alignment = 1); 547 unsigned Alignment = 1);
539 virtual void startGVStub(const GlobalValue* GV, void *Buffer, 548 virtual void startGVStub(const GlobalValue* GV, void *Buffer,
540 unsigned StubSize); 549 unsigned StubSize);
541 virtual void* finishGVStub(const GlobalValue *GV); 550 virtual void* finishGVStub(const GlobalValue *GV);
542 551
543 /// allocateSpace - Reserves space in the current block if any, or 552 /// allocateSpace - Reserves space in the current block if any, or
544 /// allocate a new one of the given size. 553 /// allocate a new one of the given size.
545 virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); 554 virtual void *allocateSpace(uintptr_t Size, unsigned Alignment);
546 555
556 /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
557 /// this method does not allocate memory in the current output buffer,
558 /// because a global may live longer than the current function.
559 virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment);
560
547 virtual void addRelocation(const MachineRelocation &MR) { 561 virtual void addRelocation(const MachineRelocation &MR) {
548 Relocations.push_back(MR); 562 Relocations.push_back(MR);
549 } 563 }
550 564
551 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { 565 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
552 if (MBBLocations.size() <= (unsigned)MBB->getNumber()) 566 if (MBBLocations.size() <= (unsigned)MBB->getNumber())
553 MBBLocations.resize((MBB->getNumber()+1)*2); 567 MBBLocations.resize((MBB->getNumber()+1)*2);
554 MBBLocations[MBB->getNumber()] = getCurrentPCValue(); 568 MBBLocations[MBB->getNumber()] = getCurrentPCValue();
555 DOUT << "JIT: Emitting BB" << MBB->getNumber() << " at [" 569 DEBUG(errs() << "JIT: Emitting BB" << MBB->getNumber() << " at ["
556 << (void*) getCurrentPCValue() << "]\n"; 570 << (void*) getCurrentPCValue() << "]\n");
557 } 571 }
558 572
559 virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; 573 virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const;
560 virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; 574 virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const;
561 575
562 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { 576 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
563 assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 577 assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
564 MBBLocations[MBB->getNumber()] && "MBB not emitted!"); 578 MBBLocations[MBB->getNumber()] && "MBB not emitted!");
565 return MBBLocations[MBB->getNumber()]; 579 return MBBLocations[MBB->getNumber()];
566 } 580 }
567 581
582 /// retryWithMoreMemory - Log a retry and deallocate all memory for the
583 /// given function. Increase the minimum allocation size so that we get
584 /// more memory next time.
585 void retryWithMoreMemory(MachineFunction &F);
586
568 /// deallocateMemForFunction - Deallocate all memory for the specified 587 /// deallocateMemForFunction - Deallocate all memory for the specified
569 /// function body. 588 /// function body.
570 void deallocateMemForFunction(Function *F); 589 void deallocateMemForFunction(const Function *F);
571 590
572 /// AddStubToCurrentFunction - Mark the current function being JIT'd as 591 /// AddStubToCurrentFunction - Mark the current function being JIT'd as
573 /// using the stub at the specified address. Allows 592 /// using the stub at the specified address. Allows
574 /// deallocateMemForFunction to also remove stubs no longer referenced. 593 /// deallocateMemForFunction to also remove stubs no longer referenced.
575 void AddStubToCurrentFunction(void *Stub); 594 void AddStubToCurrentFunction(void *Stub);
576 595
577 /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for 596 /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for
578 /// MachineRelocations that reference external functions by name. 597 /// MachineRelocations that reference external functions by name.
579 const StringMap<void*> &getExternalFnStubs() const { return ExtFnStubs; } 598 const StringMap<void*> &getExternalFnStubs() const { return ExtFnStubs; }
580 599
600 virtual void processDebugLoc(DebugLoc DL);
601
581 virtual void emitLabel(uint64_t LabelID) { 602 virtual void emitLabel(uint64_t LabelID) {
582 if (LabelLocations.size() <= LabelID) 603 if (LabelLocations.size() <= LabelID)
583 LabelLocations.resize((LabelID+1)*2); 604 LabelLocations.resize((LabelID+1)*2);
584 LabelLocations[LabelID] = getCurrentPCValue(); 605 LabelLocations[LabelID] = getCurrentPCValue();
585 } 606 }
586 607
587 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { 608 virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
588 assert(LabelLocations.size() > (unsigned)LabelID && 609 assert(LabelLocations.size() > (unsigned)LabelID &&
589 LabelLocations[LabelID] && "Label not emitted!"); 610 LabelLocations[LabelID] && "Label not emitted!");
590 return LabelLocations[LabelID]; 611 return LabelLocations[LabelID];
591 } 612 }
592 613
593 virtual void setModuleInfo(MachineModuleInfo* Info) { 614 virtual void setModuleInfo(MachineModuleInfo* Info) {
594 MMI = Info; 615 MMI = Info;
595 if (ExceptionHandling || JitEmitDebugInfo) { 616 if (DE.get()) DE->setModuleInfo(Info);
596 DE->setModuleInfo(Info); 617 }
597 } 618
598 } 619 void setMemoryExecutable() {
599
600 void setMemoryExecutable(void) {
601 MemMgr->setMemoryExecutable(); 620 MemMgr->setMemoryExecutable();
602 } 621 }
603 622
604 JITMemoryManager *getMemMgr(void) const { return MemMgr; } 623 JITMemoryManager *getMemMgr() const { return MemMgr; }
605 624
606 private: 625 private:
607 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); 626 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
608 void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference, 627 void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference,
609 bool NoNeedStub); 628 bool NoNeedStub);
610 unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size); 629 unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size);
611 unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size); 630 unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size);
612 unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size); 631 unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size);
613 unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF); 632 unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF);
614 }; 633 };
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 701
683 assert(CurFn && "Stub added to current function, but current function is 0!"); 702 assert(CurFn && "Stub added to current function, but current function is 0!");
684 703
685 SmallVectorImpl<void*> &StubsUsed = CurFnStubUses[CurFn]; 704 SmallVectorImpl<void*> &StubsUsed = CurFnStubUses[CurFn];
686 StubsUsed.push_back(StubAddr); 705 StubsUsed.push_back(StubAddr);
687 706
688 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[StubAddr]; 707 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[StubAddr];
689 FnRefs.insert(CurFn); 708 FnRefs.insert(CurFn);
690 } 709 }
691 710
711 void JITEmitter::processDebugLoc(DebugLoc DL) {
712 if (!DL.isUnknown()) {
713 DebugLocTuple CurDLT = EmissionDetails.MF->getDebugLocTuple(DL);
714
715 if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT) {
716 JITEvent_EmittedFunctionDetails::LineStart NextLine;
717 NextLine.Address = getCurrentPCValue();
718 NextLine.Loc = DL;
719 EmissionDetails.LineStarts.push_back(NextLine);
720 }
721
722 PrevDLT = CurDLT;
723 }
724 }
725
692 static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, 726 static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP,
693 const TargetData *TD) { 727 const TargetData *TD) {
694 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 728 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
695 if (Constants.empty()) return 0; 729 if (Constants.empty()) return 0;
696 730
697 unsigned Size = 0; 731 unsigned Size = 0;
698 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 732 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
699 MachineConstantPoolEntry CPE = Constants[i]; 733 MachineConstantPoolEntry CPE = Constants[i];
700 unsigned AlignMask = CPE.getAlignment() - 1; 734 unsigned AlignMask = CPE.getAlignment() - 1;
701 Size = (Size + AlignMask) & ~AlignMask; 735 Size = (Size + AlignMask) & ~AlignMask;
(...skipping 23 matching lines...) Expand all
725 } 759 }
726 760
727 /// addSizeOfGlobal - add the size of the global (plus any alignment padding) 761 /// addSizeOfGlobal - add the size of the global (plus any alignment padding)
728 /// into the running total Size. 762 /// into the running total Size.
729 763
730 unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) { 764 unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) {
731 const Type *ElTy = GV->getType()->getElementType(); 765 const Type *ElTy = GV->getType()->getElementType();
732 size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy); 766 size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy);
733 size_t GVAlign = 767 size_t GVAlign =
734 (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); 768 (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV);
735 DOUT << "JIT: Adding in size " << GVSize << " alignment " << GVAlign; 769 DEBUG(errs() << "JIT: Adding in size " << GVSize << " alignment " << GVAlign);
736 DEBUG(GV->dump()); 770 DEBUG(GV->dump());
737 // Assume code section ends with worst possible alignment, so first 771 // Assume code section ends with worst possible alignment, so first
738 // variable needs maximal padding. 772 // variable needs maximal padding.
739 if (Size==0) 773 if (Size==0)
740 Size = 1; 774 Size = 1;
741 Size = ((Size+GVAlign-1)/GVAlign)*GVAlign; 775 Size = ((Size+GVAlign-1)/GVAlign)*GVAlign;
742 Size += GVSize; 776 Size += GVSize;
743 return Size; 777 return Size;
744 } 778 }
745 779
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 case Instruction::URem: 818 case Instruction::URem:
785 case Instruction::SRem: 819 case Instruction::SRem:
786 case Instruction::And: 820 case Instruction::And:
787 case Instruction::Or: 821 case Instruction::Or:
788 case Instruction::Xor: { 822 case Instruction::Xor: {
789 Size = addSizeOfGlobalsInConstantVal(Op0, Size); 823 Size = addSizeOfGlobalsInConstantVal(Op0, Size);
790 Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size); 824 Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size);
791 break; 825 break;
792 } 826 }
793 default: { 827 default: {
794 cerr << "ConstantExpr not handled: " << *CE << "\n"; 828 std::string msg;
795 abort(); 829 raw_string_ostream Msg(msg);
830 Msg << "ConstantExpr not handled: " << *CE;
831 llvm_report_error(Msg.str());
796 } 832 }
797 } 833 }
798 } 834 }
799 835
800 if (C->getType()->getTypeID() == Type::PointerTyID) 836 if (C->getType()->getTypeID() == Type::PointerTyID)
801 if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C)) 837 if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C))
802 if (GVSet.insert(GV)) 838 if (GVSet.insert(GV))
803 Size = addSizeOfGlobal(GV, Size); 839 Size = addSizeOfGlobal(GV, Size);
804 840
805 return Size; 841 return Size;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 // assuming the addresses of the new globals in this module 887 // assuming the addresses of the new globals in this module
852 // start at 0 (or something) and adjusting them after codegen 888 // start at 0 (or something) and adjusting them after codegen
853 // complete. Another possibility is to grab a marker bit in GV. 889 // complete. Another possibility is to grab a marker bit in GV.
854 if (GVSet.insert(GV)) 890 if (GVSet.insert(GV))
855 // A variable as yet unseen. Add in its size. 891 // A variable as yet unseen. Add in its size.
856 Size = addSizeOfGlobal(GV, Size); 892 Size = addSizeOfGlobal(GV, Size);
857 } 893 }
858 } 894 }
859 } 895 }
860 } 896 }
861 DOUT << "JIT: About to look through initializers\n"; 897 DEBUG(errs() << "JIT: About to look through initializers\n");
862 // Look for more globals that are referenced only from initializers. 898 // Look for more globals that are referenced only from initializers.
863 // GVSet.end is computed each time because the set can grow as we go. 899 // GVSet.end is computed each time because the set can grow as we go.
864 for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin(); 900 for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin();
865 I != GVSet.end(); I++) { 901 I != GVSet.end(); I++) {
866 const GlobalVariable* GV = *I; 902 const GlobalVariable* GV = *I;
867 if (GV->hasInitializer()) 903 if (GV->hasInitializer())
868 Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size); 904 Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size);
869 } 905 }
870 906
871 return Size; 907 return Size;
872 } 908 }
873 909
874 void JITEmitter::startFunction(MachineFunction &F) { 910 void JITEmitter::startFunction(MachineFunction &F) {
875 DOUT << "JIT: Starting CodeGen of Function " 911 DEBUG(errs() << "JIT: Starting CodeGen of Function "
876 << F.getFunction()->getName() << "\n"; 912 << F.getFunction()->getName() << "\n");
877 913
878 uintptr_t ActualSize = 0; 914 uintptr_t ActualSize = 0;
879 // Set the memory writable, if it's not already 915 // Set the memory writable, if it's not already
880 MemMgr->setMemoryWritable(); 916 MemMgr->setMemoryWritable();
881 if (MemMgr->NeedsExactSize()) { 917 if (MemMgr->NeedsExactSize()) {
882 DOUT << "JIT: ExactSize\n"; 918 DEBUG(errs() << "JIT: ExactSize\n");
883 const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); 919 const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
884 MachineJumpTableInfo *MJTI = F.getJumpTableInfo(); 920 MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
885 MachineConstantPool *MCP = F.getConstantPool(); 921 MachineConstantPool *MCP = F.getConstantPool();
886 922
887 // Ensure the constant pool/jump table info is at least 4-byte aligned. 923 // Ensure the constant pool/jump table info is at least 4-byte aligned.
888 ActualSize = RoundUpToAlign(ActualSize, 16); 924 ActualSize = RoundUpToAlign(ActualSize, 16);
889 925
890 // Add the alignment of the constant pool 926 // Add the alignment of the constant pool
891 ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment()); 927 ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment());
892 928
893 // Add the constant pool size 929 // Add the constant pool size
894 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); 930 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
895 931
896 // Add the aligment of the jump table info 932 // Add the aligment of the jump table info
897 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); 933 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment());
898 934
899 // Add the jump table size 935 // Add the jump table size
900 ActualSize += GetJumpTableSizeInBytes(MJTI); 936 ActualSize += GetJumpTableSizeInBytes(MJTI);
901 937
902 // Add the alignment for the function 938 // Add the alignment for the function
903 ActualSize = RoundUpToAlign(ActualSize, 939 ActualSize = RoundUpToAlign(ActualSize,
904 std::max(F.getFunction()->getAlignment(), 8U)); 940 std::max(F.getFunction()->getAlignment(), 8U));
905 941
906 // Add the function size 942 // Add the function size
907 ActualSize += TII->GetFunctionSizeInBytes(F); 943 ActualSize += TII->GetFunctionSizeInBytes(F);
908 944
909 DOUT << "JIT: ActualSize before globals " << ActualSize << "\n"; 945 DEBUG(errs() << "JIT: ActualSize before globals " << ActualSize << "\n");
910 // Add the size of the globals that will be allocated after this function. 946 // Add the size of the globals that will be allocated after this function.
911 // These are all the ones referenced from this function that were not 947 // These are all the ones referenced from this function that were not
912 // previously allocated. 948 // previously allocated.
913 ActualSize += GetSizeOfGlobalsInBytes(F); 949 ActualSize += GetSizeOfGlobalsInBytes(F);
914 DOUT << "JIT: ActualSize after globals " << ActualSize << "\n"; 950 DEBUG(errs() << "JIT: ActualSize after globals " << ActualSize << "\n");
951 } else if (SizeEstimate > 0) {
952 // SizeEstimate will be non-zero on reallocation attempts.
953 ActualSize = SizeEstimate;
915 } 954 }
916 955
917 BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), 956 BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
918 ActualSize); 957 ActualSize);
919 BufferEnd = BufferBegin+ActualSize; 958 BufferEnd = BufferBegin+ActualSize;
920 959
921 // Ensure the constant pool/jump table info is at least 4-byte aligned. 960 // Ensure the constant pool/jump table info is at least 4-byte aligned.
922 emitAlignment(16); 961 emitAlignment(16);
923 962
924 emitConstantPool(F.getConstantPool()); 963 emitConstantPool(F.getConstantPool());
925 initJumpTableInfo(F.getJumpTableInfo()); 964 initJumpTableInfo(F.getJumpTableInfo());
926 965
927 // About to start emitting the machine code for the function. 966 // About to start emitting the machine code for the function.
928 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); 967 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
929 TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); 968 TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
930 969
931 MBBLocations.clear(); 970 MBBLocations.clear();
971
972 EmissionDetails.MF = &F;
973 EmissionDetails.LineStarts.clear();
932 } 974 }
933 975
934 bool JITEmitter::finishFunction(MachineFunction &F) { 976 bool JITEmitter::finishFunction(MachineFunction &F) {
935 if (CurBufferPtr == BufferEnd) { 977 if (CurBufferPtr == BufferEnd) {
936 // FIXME: Allocate more space, then try again. 978 // We must call endFunctionBody before retrying, because
937 cerr << "JIT: Ran out of space for generated machine code!\n"; 979 // deallocateMemForFunction requires it.
938 abort(); 980 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
939 } 981 retryWithMoreMemory(F);
940 982 return true;
983 }
984
941 emitJumpTableInfo(F.getJumpTableInfo()); 985 emitJumpTableInfo(F.getJumpTableInfo());
942 986
943 // FnStart is the start of the text, not the start of the constant pool and 987 // FnStart is the start of the text, not the start of the constant pool and
944 // other per-function data. 988 // other per-function data.
945 uint8_t *FnStart = 989 uint8_t *FnStart =
946 (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); 990 (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction());
947 991
948 // FnEnd is the end of the function's machine code. 992 // FnEnd is the end of the function's machine code.
949 uint8_t *FnEnd = CurBufferPtr; 993 uint8_t *FnEnd = CurBufferPtr;
950 994
951 if (!Relocations.empty()) { 995 if (!Relocations.empty()) {
952 CurFn = F.getFunction(); 996 CurFn = F.getFunction();
953 NumRelos += Relocations.size(); 997 NumRelos += Relocations.size();
954 998
955 // Resolve the relocations to concrete pointers. 999 // Resolve the relocations to concrete pointers.
956 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { 1000 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
957 MachineRelocation &MR = Relocations[i]; 1001 MachineRelocation &MR = Relocations[i];
958 void *ResultPtr = 0; 1002 void *ResultPtr = 0;
959 if (!MR.letTargetResolve()) { 1003 if (!MR.letTargetResolve()) {
960 if (MR.isExternalSymbol()) { 1004 if (MR.isExternalSymbol()) {
961 ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(), 1005 ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(),
962 false); 1006 false);
963 DOUT << "JIT: Map \'" << MR.getExternalSymbol() << "\' to [" 1007 DEBUG(errs() << "JIT: Map \'" << MR.getExternalSymbol() << "\' to ["
964 << ResultPtr << "]\n"; 1008 << ResultPtr << "]\n");
965 1009
966 // If the target REALLY wants a stub for this function, emit it now. 1010 // If the target REALLY wants a stub for this function, emit it now.
967 if (!MR.doesntNeedStub()) { 1011 if (!MR.doesntNeedStub()) {
968 if (!TheJIT->areDlsymStubsEnabled()) { 1012 if (!TheJIT->areDlsymStubsEnabled()) {
969 ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); 1013 ResultPtr = Resolver.getExternalFunctionStub(ResultPtr);
970 } else { 1014 } else {
971 void *&Stub = ExtFnStubs[MR.getExternalSymbol()]; 1015 void *&Stub = ExtFnStubs[MR.getExternalSymbol()];
972 if (!Stub) { 1016 if (!Stub) {
973 Stub = Resolver.getExternalFunctionStub((void *)&Stub); 1017 Stub = Resolver.getExternalFunctionStub((void *)&Stub);
974 AddStubToCurrentFunction(Stub); 1018 AddStubToCurrentFunction(Stub);
(...skipping 20 matching lines...) Expand all
995 1039
996 MR.setResultPointer(ResultPtr); 1040 MR.setResultPointer(ResultPtr);
997 } 1041 }
998 1042
999 // if we are managing the GOT and the relocation wants an index, 1043 // if we are managing the GOT and the relocation wants an index,
1000 // give it one 1044 // give it one
1001 if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { 1045 if (MR.isGOTRelative() && MemMgr->isManagingGOT()) {
1002 unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); 1046 unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr);
1003 MR.setGOTIndex(idx); 1047 MR.setGOTIndex(idx);
1004 if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { 1048 if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) {
1005 DOUT << "JIT: GOT was out of date for " << ResultPtr 1049 DEBUG(errs() << "JIT: GOT was out of date for " << ResultPtr
1006 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 1050 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx]
1007 << "\n"; 1051 << "\n");
1008 ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; 1052 ((void**)MemMgr->getGOTBase())[idx] = ResultPtr;
1009 } 1053 }
1010 } 1054 }
1011 } 1055 }
1012 1056
1013 CurFn = 0; 1057 CurFn = 0;
1014 TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], 1058 TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0],
1015 Relocations.size(), MemMgr->getGOTBase()); 1059 Relocations.size(), MemMgr->getGOTBase());
1016 } 1060 }
1017 1061
1018 // Update the GOT entry for F to point to the new code. 1062 // Update the GOT entry for F to point to the new code.
1019 if (MemMgr->isManagingGOT()) { 1063 if (MemMgr->isManagingGOT()) {
1020 unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); 1064 unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin);
1021 if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { 1065 if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) {
1022 DOUT << "JIT: GOT was out of date for " << (void*)BufferBegin 1066 DEBUG(errs() << "JIT: GOT was out of date for " << (void*)BufferBegin
1023 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n"; 1067 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx]
1068 << "\n");
1024 ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; 1069 ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin;
1025 } 1070 }
1026 } 1071 }
1027 1072
1028 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for 1073 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
1029 // global variables that were referenced in the relocations. 1074 // global variables that were referenced in the relocations.
1030 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); 1075 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
1031 1076
1032 if (CurBufferPtr == BufferEnd) { 1077 if (CurBufferPtr == BufferEnd) {
1033 // FIXME: Allocate more space, then try again. 1078 retryWithMoreMemory(F);
1034 cerr << "JIT: Ran out of space for generated machine code!\n"; 1079 return true;
1035 abort(); 1080 } else {
1081 // Now that we've succeeded in emitting the function, reset the
1082 // SizeEstimate back down to zero.
1083 SizeEstimate = 0;
1036 } 1084 }
1037 1085
1038 BufferBegin = CurBufferPtr = 0; 1086 BufferBegin = CurBufferPtr = 0;
1039 NumBytes += FnEnd-FnStart; 1087 NumBytes += FnEnd-FnStart;
1040 1088
1041 // Invalidate the icache if necessary. 1089 // Invalidate the icache if necessary.
1042 sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart); 1090 sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart);
1043 1091
1044 JITEvent_EmittedFunctionDetails Details;
1045 TheJIT->NotifyFunctionEmitted(*F.getFunction(), FnStart, FnEnd-FnStart, 1092 TheJIT->NotifyFunctionEmitted(*F.getFunction(), FnStart, FnEnd-FnStart,
1046 Details); 1093 EmissionDetails);
1047 1094
1048 DOUT << "JIT: Finished CodeGen of [" << (void*)FnStart 1095 DEBUG(errs() << "JIT: Finished CodeGen of [" << (void*)FnStart
1049 << "] Function: " << F.getFunction()->getName() 1096 << "] Function: " << F.getFunction()->getName()
1050 << ": " << (FnEnd-FnStart) << " bytes of text, " 1097 << ": " << (FnEnd-FnStart) << " bytes of text, "
1051 << Relocations.size() << " relocations\n"; 1098 << Relocations.size() << " relocations\n");
1052 1099
1053 Relocations.clear(); 1100 Relocations.clear();
1054 ConstPoolAddresses.clear(); 1101 ConstPoolAddresses.clear();
1055 1102
1056 // Mark code region readable and executable if it's not so already. 1103 // Mark code region readable and executable if it's not so already.
1057 MemMgr->setMemoryExecutable(); 1104 MemMgr->setMemoryExecutable();
1058 1105
1059 #ifndef NDEBUG 1106 DEBUG(
1060 {
1061 if (sys::hasDisassembler()) { 1107 if (sys::hasDisassembler()) {
1062 DOUT << "JIT: Disassembled code:\n"; 1108 errs() << "JIT: Disassembled code:\n";
1063 DOUT << sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart) ; 1109 errs() << sys::disassembleBuffer(FnStart, FnEnd-FnStart,
1110 (uintptr_t)FnStart);
1064 } else { 1111 } else {
1065 DOUT << "JIT: Binary code:\n"; 1112 errs() << "JIT: Binary code:\n";
1066 DOUT << std::hex;
1067 uint8_t* q = FnStart; 1113 uint8_t* q = FnStart;
1068 for (int i = 0; q < FnEnd; q += 4, ++i) { 1114 for (int i = 0; q < FnEnd; q += 4, ++i) {
1069 if (i == 4) 1115 if (i == 4)
1070 i = 0; 1116 i = 0;
1071 if (i == 0) 1117 if (i == 0)
1072 DOUT << "JIT: " << std::setw(8) << std::setfill('0') 1118 errs() << "JIT: " << (long)(q - FnStart) << ": ";
1073 << (long)(q - FnStart) << ": ";
1074 bool Done = false; 1119 bool Done = false;
1075 for (int j = 3; j >= 0; --j) { 1120 for (int j = 3; j >= 0; --j) {
1076 if (q + j >= FnEnd) 1121 if (q + j >= FnEnd)
1077 Done = true; 1122 Done = true;
1078 else 1123 else
1079 DOUT << std::setw(2) << std::setfill('0') << (unsigned short)q[j]; 1124 errs() << (unsigned short)q[j];
1080 } 1125 }
1081 if (Done) 1126 if (Done)
1082 break; 1127 break;
1083 DOUT << ' '; 1128 errs() << ' ';
1084 if (i == 3) 1129 if (i == 3)
1085 DOUT << '\n'; 1130 errs() << '\n';
1086 } 1131 }
1087 DOUT << std::dec; 1132 errs()<< '\n';
1088 DOUT<< '\n'; 1133 }
1089 } 1134 );
1090 } 1135
1091 #endif 1136 if (DwarfExceptionHandling || JITEmitDebugInfo) {
1092 if (ExceptionHandling || JitEmitDebugInfo) {
Jeffrey Yasskin 2009/07/03 22:01:52 It'd be nice to put this into a JITEventListener,
Reid Kleckner 2009/07/06 21:07:01 On 2009/07/03 22:01:52, Jeffrey Yasskin wrote: > I
Jeffrey Yasskin 2009/07/08 00:40:45 On 2009/07/06 21:07:01, Reid Kleckner wrote: > On
1093 uintptr_t ActualSize = 0; 1137 uintptr_t ActualSize = 0;
1094 SavedBufferBegin = BufferBegin; 1138 SavedBufferBegin = BufferBegin;
1095 SavedBufferEnd = BufferEnd; 1139 SavedBufferEnd = BufferEnd;
1096 SavedCurBufferPtr = CurBufferPtr; 1140 SavedCurBufferPtr = CurBufferPtr;
1097 1141
1098 if (MemMgr->NeedsExactSize()) { 1142 if (MemMgr->NeedsExactSize()) {
1099 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); 1143 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
1100 } 1144 }
1101 1145
1102 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 1146 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
1103 ActualSize); 1147 ActualSize);
1104 BufferEnd = BufferBegin+ActualSize; 1148 BufferEnd = BufferBegin+ActualSize;
1105 uint8_t* EhStart = BufferBegin; 1149 uint8_t *EhStart;
1106 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); 1150 uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd,
1151 EhStart);
1107 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 1152 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
1108 FrameRegister); 1153 FrameRegister);
1109 uint8_t* EhEnd = CurBufferPtr; 1154 uint8_t *EhEnd = CurBufferPtr;
1110 BufferBegin = SavedBufferBegin; 1155 BufferBegin = SavedBufferBegin;
1111 BufferEnd = SavedBufferEnd; 1156 BufferEnd = SavedBufferEnd;
1112 CurBufferPtr = SavedCurBufferPtr; 1157 CurBufferPtr = SavedCurBufferPtr;
1113 1158
1114 if (ExceptionHandling) { 1159 if (DwarfExceptionHandling) {
1115 TheJIT->RegisterTable(FrameRegister); 1160 TheJIT->RegisterTable(FrameRegister);
1116 } 1161 }
1117 1162
1118 if (JitEmitDebugInfo) { 1163 if (JITEmitDebugInfo) {
1119 DR->RegisterDebugInfo(F.getFunction(), FnStart, FnEnd, EhStart, EhEnd); 1164 DebugInfo I;
1165 I.FnStart = FnStart;
1166 I.FnEnd = FnEnd;
1167 I.EhStart = EhStart;
1168 I.EhEnd = EhEnd;
1169 DR->RegisterFunction(F.getFunction(), I);
1120 } 1170 }
1121 } 1171 }
1122 1172
1123 if (MMI) 1173 if (MMI)
1124 MMI->EndFunction(); 1174 MMI->EndFunction();
1125 1175
1126 return false; 1176 return false;
1127 } 1177 }
1128 1178
1179 void JITEmitter::retryWithMoreMemory(MachineFunction &F) {
1180 DEBUG(errs() << "JIT: Ran out of space for native code. Reattempting.\n");
1181 Relocations.clear(); // Clear the old relocations or we'll reapply them.
1182 ConstPoolAddresses.clear();
1183 ++NumRetries;
1184 deallocateMemForFunction(F.getFunction());
1185 // Try again with at least twice as much free space.
1186 SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin));
1187 }
1188
1129 /// deallocateMemForFunction - Deallocate all memory for the specified 1189 /// deallocateMemForFunction - Deallocate all memory for the specified
1130 /// function body. Also drop any references the function has to stubs. 1190 /// function body. Also drop any references the function has to stubs.
1131 void JITEmitter::deallocateMemForFunction(Function *F) { 1191 void JITEmitter::deallocateMemForFunction(const Function *F) {
1132 MemMgr->deallocateMemForFunction(F); 1192 MemMgr->deallocateMemForFunction(F);
1193
1194 // Do we need to unregister exception handling information from libgcc here?
1195
1196 if (JITEmitDebugInfo) {
1197 DR->UnregisterFunction(F);
1198 }
1133 1199
1134 // If the function did not reference any stubs, return. 1200 // If the function did not reference any stubs, return.
1135 if (CurFnStubUses.find(F) == CurFnStubUses.end()) 1201 if (CurFnStubUses.find(F) == CurFnStubUses.end())
1136 return; 1202 return;
1137 1203
1138 // For each referenced stub, erase the reference to this function, and then 1204 // For each referenced stub, erase the reference to this function, and then
1139 // erase the list of referenced stubs. 1205 // erase the list of referenced stubs.
1140 SmallVectorImpl<void *> &StubList = CurFnStubUses[F]; 1206 SmallVectorImpl<void *> &StubList = CurFnStubUses[F];
1141 for (unsigned i = 0, e = StubList.size(); i != e; ++i) { 1207 for (unsigned i = 0, e = StubList.size(); i != e; ++i) {
1142 void *Stub = StubList[i]; 1208 void *Stub = StubList[i];
1143 1209
1144 // If we already invalidated this stub for this function, continue. 1210 // If we already invalidated this stub for this function, continue.
1145 if (StubFnRefs.count(Stub) == 0) 1211 if (StubFnRefs.count(Stub) == 0)
1146 continue; 1212 continue;
1147 1213
1148 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub]; 1214 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub];
1149 FnRefs.erase(F); 1215 FnRefs.erase(F);
1150 1216
1151 // If this function was the last reference to the stub, invalidate the stub 1217 // If this function was the last reference to the stub, invalidate the stub
1152 // in the JITResolver. Were there a memory manager deallocateStub routine, 1218 // in the JITResolver. Were there a memory manager deallocateStub routine,
1153 // we could call that at this point too. 1219 // we could call that at this point too.
1154 if (FnRefs.empty()) { 1220 if (FnRefs.empty()) {
1155 DOUT << "\nJIT: Invalidated Stub at [" << Stub << "]\n"; 1221 DEBUG(errs() << "\nJIT: Invalidated Stub at [" << Stub << "]\n");
1156 StubFnRefs.erase(Stub); 1222 StubFnRefs.erase(Stub);
1157 1223
1158 // Invalidate the stub. If it is a GV stub, update the JIT's global 1224 // Invalidate the stub. If it is a GV stub, update the JIT's global
1159 // mapping for that GV to zero, otherwise, search the string map of 1225 // mapping for that GV to zero, otherwise, search the string map of
1160 // external function names to stubs and remove the entry for this stub. 1226 // external function names to stubs and remove the entry for this stub.
1161 GlobalValue *GV = Resolver.invalidateStub(Stub); 1227 GlobalValue *GV = Resolver.invalidateStub(Stub);
1162 if (GV) { 1228 if (GV) {
1163 TheJIT->updateGlobalMapping(GV, 0); 1229 TheJIT->updateGlobalMapping(GV, 0);
1164 } else { 1230 } else {
1165 for (StringMapIterator<void*> i = ExtFnStubs.begin(), 1231 for (StringMapIterator<void*> i = ExtFnStubs.begin(),
(...skipping 15 matching lines...) Expand all
1181 return JITCodeEmitter::allocateSpace(Size, Alignment); 1247 return JITCodeEmitter::allocateSpace(Size, Alignment);
1182 1248
1183 // create a new memory block if there is no active one. 1249 // create a new memory block if there is no active one.
1184 // care must be taken so that BufferBegin is invalidated when a 1250 // care must be taken so that BufferBegin is invalidated when a
1185 // block is trimmed 1251 // block is trimmed
1186 BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment); 1252 BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment);
1187 BufferEnd = BufferBegin+Size; 1253 BufferEnd = BufferBegin+Size;
1188 return CurBufferPtr; 1254 return CurBufferPtr;
1189 } 1255 }
1190 1256
1257 void* JITEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) {
1258 // Delegate this call through the memory manager.
1259 return MemMgr->allocateGlobal(Size, Alignment);
1260 }
1261
1191 void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { 1262 void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
1192 if (TheJIT->getJITInfo().hasCustomConstantPool()) 1263 if (TheJIT->getJITInfo().hasCustomConstantPool())
1193 return; 1264 return;
1194 1265
1195 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 1266 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
1196 if (Constants.empty()) return; 1267 if (Constants.empty()) return;
1197 1268
1198 unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); 1269 unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
1199 unsigned Align = MCP->getConstantPoolAlignment(); 1270 unsigned Align = MCP->getConstantPoolAlignment();
1200 ConstantPoolBase = allocateSpace(Size, Align); 1271 ConstantPoolBase = allocateSpace(Size, Align);
1201 ConstantPool = MCP; 1272 ConstantPool = MCP;
1202 1273
1203 if (ConstantPoolBase == 0) return; // Buffer overflow. 1274 if (ConstantPoolBase == 0) return; // Buffer overflow.
1204 1275
1205 DOUT << "JIT: Emitted constant pool at [" << ConstantPoolBase 1276 DEBUG(errs() << "JIT: Emitted constant pool at [" << ConstantPoolBase
1206 << "] (size: " << Size << ", alignment: " << Align << ")\n"; 1277 << "] (size: " << Size << ", alignment: " << Align << ")\n");
1207 1278
1208 // Initialize the memory for all of the constant pool entries. 1279 // Initialize the memory for all of the constant pool entries.
1209 unsigned Offset = 0; 1280 unsigned Offset = 0;
1210 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 1281 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
1211 MachineConstantPoolEntry CPE = Constants[i]; 1282 MachineConstantPoolEntry CPE = Constants[i];
1212 unsigned AlignMask = CPE.getAlignment() - 1; 1283 unsigned AlignMask = CPE.getAlignment() - 1;
1213 Offset = (Offset + AlignMask) & ~AlignMask; 1284 Offset = (Offset + AlignMask) & ~AlignMask;
1214 1285
1215 uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; 1286 uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset;
1216 ConstPoolAddresses.push_back(CAddr); 1287 ConstPoolAddresses.push_back(CAddr);
1217 if (CPE.isMachineConstantPoolEntry()) { 1288 if (CPE.isMachineConstantPoolEntry()) {
1218 // FIXME: add support to lower machine constant pool values into bytes! 1289 // FIXME: add support to lower machine constant pool values into bytes!
1219 cerr << "Initialize memory with machine specific constant pool entry" 1290 llvm_report_error("Initialize memory with machine specific constant pool"
1220 << " has not been implemented!\n"; 1291 "entry has not been implemented!");
1221 abort();
1222 } 1292 }
1223 TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); 1293 TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr);
1224 DOUT << "JIT: CP" << i << " at [0x" 1294 DEBUG(errs() << "JIT: CP" << i << " at [0x";
1225 << std::hex << CAddr << std::dec << "]\n"; 1295 errs().write_hex(CAddr) << "]\n");
1226 1296
1227 const Type *Ty = CPE.Val.ConstVal->getType(); 1297 const Type *Ty = CPE.Val.ConstVal->getType();
1228 Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); 1298 Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty);
1229 } 1299 }
1230 } 1300 }
1231 1301
1232 void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { 1302 void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
1233 if (TheJIT->getJITInfo().hasCustomJumpTables()) 1303 if (TheJIT->getJITInfo().hasCustomJumpTables())
1234 return; 1304 return;
1235 1305
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 void *CurTable = JE->getMemMgr()->getDlsymTable(); 1487 void *CurTable = JE->getMemMgr()->getDlsymTable();
1418 if (CurTable && (*(unsigned *)CurTable == nStubs)) 1488 if (CurTable && (*(unsigned *)CurTable == nStubs))
1419 return; 1489 return;
1420 1490
1421 // Calculate the size of the stub info 1491 // Calculate the size of the stub info
1422 unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs; 1492 unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs;
1423 1493
1424 SmallVector<unsigned, 8> Offsets; 1494 SmallVector<unsigned, 8> Offsets;
1425 for (unsigned i = 0; i != GVs.size(); ++i) { 1495 for (unsigned i = 0; i != GVs.size(); ++i) {
1426 Offsets.push_back(offset); 1496 Offsets.push_back(offset);
1427 offset += GVs[i]->getName().length() + 1; 1497 offset += GVs[i]->getName().size() + 1;
1428 } 1498 }
1429 for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end(); 1499 for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
1430 i != e; ++i) { 1500 i != e; ++i) {
1431 Offsets.push_back(offset); 1501 Offsets.push_back(offset);
1432 offset += strlen(i->first()) + 1; 1502 offset += strlen(i->first()) + 1;
1433 } 1503 }
1434 1504
1435 // Allocate space for the new "stub", which contains the dlsym table. 1505 // Allocate space for the new "stub", which contains the dlsym table.
1436 JE->startGVStub(0, offset, 4); 1506 JE->startGVStub(0, offset, 4);
1437 1507
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 // retranslated next time it is used. 1558 // retranslated next time it is used.
1489 void *OldPtr = updateGlobalMapping(F, 0); 1559 void *OldPtr = updateGlobalMapping(F, 0);
1490 1560
1491 if (OldPtr) 1561 if (OldPtr)
1492 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); 1562 TheJIT->NotifyFreeingMachineCode(*F, OldPtr);
1493 1563
1494 // Free the actual memory for the function body and related stuff. 1564 // Free the actual memory for the function body and related stuff.
1495 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1565 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?");
1496 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); 1566 cast<JITEmitter>(JCE)->deallocateMemForFunction(F);
1497 } 1567 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld r497