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

Side by Side Diff: lib/ExecutionEngine/JIT/JITEmitter.cpp

Issue 91042: Implement LLVM JIT side of GDB JIT debugging interface (Closed) Base URL: http://llvm.org/svn/llvm-project/llvm/trunk/
Patch Set: Created 14 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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 "JITDwarfEmitter.h" 18 #include "JITDwarfEmitter.h"
18 #include "llvm/Constants.h" 19 #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 I don't know. Gone.
19 #include "llvm/Module.h" 21 #include "llvm/Module.h"
20 #include "llvm/DerivedTypes.h" 22 #include "llvm/DerivedTypes.h"
21 #include "llvm/CodeGen/JITCodeEmitter.h" 23 #include "llvm/CodeGen/JITCodeEmitter.h"
22 #include "llvm/CodeGen/MachineFunction.h" 24 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineConstantPool.h" 25 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineJumpTableInfo.h" 26 #include "llvm/CodeGen/MachineJumpTableInfo.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h" 27 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/MachineRelocation.h" 28 #include "llvm/CodeGen/MachineRelocation.h"
27 #include "llvm/ExecutionEngine/GenericValue.h" 29 #include "llvm/ExecutionEngine/GenericValue.h"
28 #include "llvm/ExecutionEngine/JITEventListener.h" 30 #include "llvm/ExecutionEngine/JITEventListener.h"
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 /// JumpTable - The jump tables for the current function. 450 /// JumpTable - The jump tables for the current function.
449 /// 451 ///
450 MachineJumpTableInfo *JumpTable; 452 MachineJumpTableInfo *JumpTable;
451 ···· 453 ····
452 /// JumpTableBase - A pointer to the first entry in the jump table. 454 /// JumpTableBase - A pointer to the first entry in the jump table.
453 /// 455 ///
454 void *JumpTableBase; 456 void *JumpTableBase;
455 457
456 /// Resolver - This contains info about the currently resolved functions. 458 /// Resolver - This contains info about the currently resolved functions.
457 JITResolver Resolver; 459 JITResolver Resolver;
458 460
459 /// DE - The dwarf emitter for the jit. 461 /// DE - The dwarf emitter for the jit.
460 JITDwarfEmitter *DE; 462 JITDwarfEmitter *DE;
461 463
464 /// DR - The debug registerer for the jit.
465 JITDebugRegisterer *DR;
466
462 /// LabelLocations - This vector is a mapping from Label ID's to their· 467 /// LabelLocations - This vector is a mapping from Label ID's to their·
463 /// address. 468 /// address.
464 std::vector<uintptr_t> LabelLocations; 469 std::vector<uintptr_t> LabelLocations;
465 470
466 /// MMI - Machine module info for exception informations 471 /// MMI - Machine module info for exception informations
467 MachineModuleInfo* MMI; 472 MachineModuleInfo* MMI;
468 473
469 // GVSet - a set to keep track of which globals have been seen 474 // GVSet - a set to keep track of which globals have been seen
470 SmallPtrSet<const GlobalVariable*, 8> GVSet; 475 SmallPtrSet<const GlobalVariable*, 8> GVSet;
471 476
472 // CurFn - The llvm function being emitted. Only valid during· 477 // CurFn - The llvm function being emitted. Only valid during·
473 // finishFunction(). 478 // finishFunction().
474 const Function *CurFn; 479 const Function *CurFn;
475 ···· 480 ····
476 // CurFnStubUses - For a given Function, a vector of stubs that it 481 // CurFnStubUses - For a given Function, a vector of stubs that it
477 // references. This facilitates the JIT detecting that a stub is no 482 // references. This facilitates the JIT detecting that a stub is no
478 // longer used, so that it may be deallocated. 483 // longer used, so that it may be deallocated.
479 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses; 484 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses;
480 ···· 485 ····
481 // StubFnRefs - For a given pointer to a stub, a set of Functions which 486 // StubFnRefs - For a given pointer to a stub, a set of Functions which
482 // reference the stub. When the count of a stub's references drops to zero, 487 // reference the stub. When the count of a stub's references drops to zero,
483 // the stub is unused. 488 // the stub is unused.
484 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; 489 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
485 ···· 490 ····
486 // ExtFnStubs - A map of external function names to stubs which have entries 491 // ExtFnStubs - A map of external function names to stubs which have entries
487 // in the JITResolver's ExternalFnToStubMap. 492 // in the JITResolver's ExternalFnToStubMap.
488 StringMap<void *> ExtFnStubs; 493 StringMap<void *> ExtFnStubs;
489 494
490 public: 495 public:
491 JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit), CurFn(0) { 496 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
497 : Resolver(jit), CurFn(0) {
492 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 498 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
493 if (jit.getJITInfo().needsGOT()) { 499 if (jit.getJITInfo().needsGOT()) {
494 MemMgr->AllocateGOT(); 500 MemMgr->AllocateGOT();
495 DOUT << "JIT is managing a GOT\n"; 501 DOUT << "JIT is managing a GOT\n";
496 } 502 }
497 503
498 if (ExceptionHandling) DE = new JITDwarfEmitter(jit); 504 if (ExceptionHandling || JitEmitDebugInfo) {
505 DE = new JITDwarfEmitter(jit);
506 }
507 if (JitEmitDebugInfo) {
508 DR = new JITDebugRegisterer(TM);
509 }
499 } 510 }
511
500 ~JITEmitter() {· 512 ~JITEmitter() {·
501 delete MemMgr; 513 delete MemMgr;
502 if (ExceptionHandling) delete DE; 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 Done.
515 delete DE;
516 }
517 if (JitEmitDebugInfo) {
518 delete DR;
519 }
503 } 520 }
504 521
505 /// classof - Methods for support type inquiry through isa, cast, and 522 /// classof - Methods for support type inquiry through isa, cast, and
506 /// dyn_cast: 523 /// dyn_cast:
507 /// 524 ///
508 static inline bool classof(const JITEmitter*) { return true; } 525 static inline bool classof(const JITEmitter*) { return true; }
509 static inline bool classof(const MachineCodeEmitter*) { return true; } 526 static inline bool classof(const MachineCodeEmitter*) { return true; }
510 ···· 527 ····
511 JITResolver &getJITResolver() { return Resolver; } 528 JITResolver &getJITResolver() { return Resolver; }
512 529
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 } 585 }
569 586
570 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { 587 virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
571 assert(LabelLocations.size() > (unsigned)LabelID &&· 588 assert(LabelLocations.size() > (unsigned)LabelID &&·
572 LabelLocations[LabelID] && "Label not emitted!"); 589 LabelLocations[LabelID] && "Label not emitted!");
573 return LabelLocations[LabelID]; 590 return LabelLocations[LabelID];
574 } 591 }
575 · 592 ·
576 virtual void setModuleInfo(MachineModuleInfo* Info) { 593 virtual void setModuleInfo(MachineModuleInfo* Info) {
577 MMI = Info; 594 MMI = Info;
578 if (ExceptionHandling) DE->setModuleInfo(Info); 595 if (ExceptionHandling || JitEmitDebugInfo) {
596 DE->setModuleInfo(Info);
597 }
579 } 598 }
580 599
581 void setMemoryExecutable(void) { 600 void setMemoryExecutable(void) {
582 MemMgr->setMemoryExecutable(); 601 MemMgr->setMemoryExecutable();
583 } 602 }
584 ···· 603 ····
585 JITMemoryManager *getMemMgr(void) const { return MemMgr; } 604 JITMemoryManager *getMemMgr(void) const { return MemMgr; }
586 605
587 private: 606 private:
588 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); 607 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 break; 1082 break;
1064 DOUT << ' '; 1083 DOUT << ' ';
1065 if (i == 3) 1084 if (i == 3)
1066 DOUT << '\n'; 1085 DOUT << '\n';
1067 } 1086 }
1068 DOUT << std::dec; 1087 DOUT << std::dec;
1069 DOUT<< '\n'; 1088 DOUT<< '\n';
1070 } 1089 }
1071 } 1090 }
1072 #endif 1091 #endif
1073 if (ExceptionHandling) { 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 I could wrap both exception handling and debug inf
Jeffrey Yasskin 2009/07/08 00:40:45 That sounds good, actually. It makes sense becaus
1074 uintptr_t ActualSize = 0; 1093 uintptr_t ActualSize = 0;
1075 SavedBufferBegin = BufferBegin; 1094 SavedBufferBegin = BufferBegin;
1076 SavedBufferEnd = BufferEnd; 1095 SavedBufferEnd = BufferEnd;
1077 SavedCurBufferPtr = CurBufferPtr; 1096 SavedCurBufferPtr = CurBufferPtr;
1078 ···· 1097 ····
1079 if (MemMgr->NeedsExactSize()) { 1098 if (MemMgr->NeedsExactSize()) {
1080 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); 1099 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
1081 } 1100 }
1082 1101
1083 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 1102 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
1084 ActualSize); 1103 ActualSize);
1085 BufferEnd = BufferBegin+ActualSize; 1104 BufferEnd = BufferBegin+ActualSize;
1105 uint8_t* EhStart = BufferBegin;
1086 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); 1106 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd);
1087 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 1107 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
1088 FrameRegister); 1108 FrameRegister);
1109 uint8_t* EhEnd = CurBufferPtr;
1089 BufferBegin = SavedBufferBegin; 1110 BufferBegin = SavedBufferBegin;
1090 BufferEnd = SavedBufferEnd; 1111 BufferEnd = SavedBufferEnd;
1091 CurBufferPtr = SavedCurBufferPtr; 1112 CurBufferPtr = SavedCurBufferPtr;
1092 1113
1093 TheJIT->RegisterTable(FrameRegister); 1114 if (ExceptionHandling) {
1115 TheJIT->RegisterTable(FrameRegister);
1116 }
1117
1118 if (JitEmitDebugInfo) {
1119 DR->RegisterDebugInfo(F.getFunction(), FnStart, FnEnd, EhStart, EhEnd);
1120 }
1094 } 1121 }
1095 1122
1096 if (MMI) 1123 if (MMI)
1097 MMI->EndFunction(); 1124 MMI->EndFunction();
1098 · 1125 ·
1099 return false; 1126 return false;
1100 } 1127 }
1101 1128
1102 /// deallocateMemForFunction - Deallocate all memory for the specified 1129 /// deallocateMemForFunction - Deallocate all memory for the specified
1103 /// function body. Also drop any references the function has to stubs. 1130 /// function body. Also drop any references the function has to stubs.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 ·· 1342 ··
1316 Offset *= EntrySize; 1343 Offset *= EntrySize;
1317 ·· 1344 ··
1318 return (uintptr_t)((char *)JumpTableBase + Offset); 1345 return (uintptr_t)((char *)JumpTableBase + Offset);
1319 } 1346 }
1320 1347
1321 //===----------------------------------------------------------------------===// 1348 //===----------------------------------------------------------------------===//
1322 // Public interface to this file 1349 // Public interface to this file
1323 //===----------------------------------------------------------------------===// 1350 //===----------------------------------------------------------------------===//
1324 1351
1325 JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM) { 1352 JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM,
1326 return new JITEmitter(jit, JMM); 1353 TargetMachine &tm) {
1354 return new JITEmitter(jit, JMM, tm);
1327 } 1355 }
1328 1356
1329 // getPointerToNamedFunction - This function is used as a global wrapper to 1357 // getPointerToNamedFunction - This function is used as a global wrapper to
1330 // JIT::getPointerToNamedFunction for the purpose of resolving symbols when 1358 // JIT::getPointerToNamedFunction for the purpose of resolving symbols when
1331 // bugpoint is debugging the JIT. In that scenario, we are loading an .so and 1359 // bugpoint is debugging the JIT. In that scenario, we are loading an .so and
1332 // need to resolve function(s) that are being mis-codegenerated, so we need to 1360 // need to resolve function(s) that are being mis-codegenerated, so we need to
1333 // resolve their addresses at runtime, and this is the way to do it. 1361 // resolve their addresses at runtime, and this is the way to do it.
1334 extern "C" { 1362 extern "C" {
1335 void *getPointerToNamedFunction(const char *Name) { 1363 void *getPointerToNamedFunction(const char *Name) {
1336 if (Function *F = TheJIT->FindFunctionNamed(Name)) 1364 if (Function *F = TheJIT->FindFunctionNamed(Name))
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 // retranslated next time it is used. 1488 // retranslated next time it is used.
1461 void *OldPtr = updateGlobalMapping(F, 0); 1489 void *OldPtr = updateGlobalMapping(F, 0);
1462 1490
1463 if (OldPtr) 1491 if (OldPtr)
1464 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); 1492 TheJIT->NotifyFreeingMachineCode(*F, OldPtr);
1465 1493
1466 // Free the actual memory for the function body and related stuff. 1494 // Free the actual memory for the function body and related stuff.
1467 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1495 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?");
1468 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); 1496 cast<JITEmitter>(JCE)->deallocateMemForFunction(F);
1469 } 1497 }
OLDNEW

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