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

Side by Side Diff: 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/
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:
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"
19 #include "llvm/ADT/OwningPtr.h"
18 #include "llvm/Constants.h" 20 #include "llvm/Constants.h"
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"
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 /// JumpTable - The jump tables for the current function. 459 /// JumpTable - The jump tables for the current function.
458 /// 460 ///
459 MachineJumpTableInfo *JumpTable; 461 MachineJumpTableInfo *JumpTable;
460 462
461 /// JumpTableBase - A pointer to the first entry in the jump table. 463 /// JumpTableBase - A pointer to the first entry in the jump table.
462 /// 464 ///
463 void *JumpTableBase; 465 void *JumpTableBase;
464 466
465 /// Resolver - This contains info about the currently resolved functions. 467 /// Resolver - This contains info about the currently resolved functions.
466 JITResolver Resolver; 468 JITResolver Resolver;
467 469
468 /// DE - The dwarf emitter for the jit. 470 /// DE - The dwarf emitter for the jit.
469 JITDwarfEmitter *DE; 471 OwningPtr<JITDwarfEmitter> DE;
472
473 /// DR - The debug registerer for the jit.
474 OwningPtr<JITDebugRegisterer> DR;
470 475
471 /// 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
472 /// address. 477 /// address.
473 std::vector<uintptr_t> LabelLocations; 478 std::vector<uintptr_t> LabelLocations;
474 479
475 /// MMI - Machine module info for exception informations 480 /// MMI - Machine module info for exception informations
476 MachineModuleInfo* MMI; 481 MachineModuleInfo* MMI;
477 482
478 // 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
479 SmallPtrSet<const GlobalVariable*, 8> GVSet; 484 SmallPtrSet<const GlobalVariable*, 8> GVSet;
(...skipping 17 matching lines...) Expand all
497 // the stub is unused. 502 // the stub is unused.
498 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; 503 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
499 504
500 // 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
501 // in the JITResolver's ExternalFnToStubMap. 506 // in the JITResolver's ExternalFnToStubMap.
502 StringMap<void *> ExtFnStubs; 507 StringMap<void *> ExtFnStubs;
503 508
504 DebugLocTuple PrevDLT; 509 DebugLocTuple PrevDLT;
505 510
506 public: 511 public:
507 JITEmitter(JIT &jit, JITMemoryManager *JMM) 512 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
508 : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0) { 513 : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0) {
509 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 514 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
510 if (jit.getJITInfo().needsGOT()) { 515 if (jit.getJITInfo().needsGOT()) {
511 MemMgr->AllocateGOT(); 516 MemMgr->AllocateGOT();
512 DEBUG(errs() << "JIT is managing a GOT\n"); 517 DEBUG(errs() << "JIT is managing a GOT\n");
513 } 518 }
514 519
515 if (DwarfExceptionHandling) DE = new JITDwarfEmitter(jit); 520 if (DwarfExceptionHandling || JITEmitDebugInfo) {
521 DE.reset(new JITDwarfEmitter(jit));
522 }
523 if (JITEmitDebugInfo) {
524 DR.reset(new JITDebugRegisterer(TM));
525 }
516 } 526 }
517 ~JITEmitter() { 527 ~JITEmitter() {
518 delete MemMgr; 528 delete MemMgr;
519 if (DwarfExceptionHandling) delete DE;
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
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 } 606 }
598 607
599 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { 608 virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
600 assert(LabelLocations.size() > (unsigned)LabelID && 609 assert(LabelLocations.size() > (unsigned)LabelID &&
601 LabelLocations[LabelID] && "Label not emitted!"); 610 LabelLocations[LabelID] && "Label not emitted!");
602 return LabelLocations[LabelID]; 611 return LabelLocations[LabelID];
603 } 612 }
604 613
605 virtual void setModuleInfo(MachineModuleInfo* Info) { 614 virtual void setModuleInfo(MachineModuleInfo* Info) {
606 MMI = Info; 615 MMI = Info;
607 if (DwarfExceptionHandling) DE->setModuleInfo(Info); 616 if (DE.get()) DE->setModuleInfo(Info);
608 } 617 }
609 618
610 void setMemoryExecutable() { 619 void setMemoryExecutable() {
611 MemMgr->setMemoryExecutable(); 620 MemMgr->setMemoryExecutable();
612 } 621 }
613 622
614 JITMemoryManager *getMemMgr() const { return MemMgr; } 623 JITMemoryManager *getMemMgr() const { return MemMgr; }
615 624
616 private: 625 private:
617 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); 626 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 if (Done) 1126 if (Done)
1118 break; 1127 break;
1119 errs() << ' '; 1128 errs() << ' ';
1120 if (i == 3) 1129 if (i == 3)
1121 errs() << '\n'; 1130 errs() << '\n';
1122 } 1131 }
1123 errs()<< '\n'; 1132 errs()<< '\n';
1124 } 1133 }
1125 ); 1134 );
1126 1135
1127 if (DwarfExceptionHandling) { 1136 if (DwarfExceptionHandling || JITEmitDebugInfo) {
1128 uintptr_t ActualSize = 0; 1137 uintptr_t ActualSize = 0;
1129 SavedBufferBegin = BufferBegin; 1138 SavedBufferBegin = BufferBegin;
1130 SavedBufferEnd = BufferEnd; 1139 SavedBufferEnd = BufferEnd;
1131 SavedCurBufferPtr = CurBufferPtr; 1140 SavedCurBufferPtr = CurBufferPtr;
1132 1141
1133 if (MemMgr->NeedsExactSize()) { 1142 if (MemMgr->NeedsExactSize()) {
1134 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); 1143 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
1135 } 1144 }
1136 1145
1137 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 1146 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
1138 ActualSize); 1147 ActualSize);
1139 BufferEnd = BufferBegin+ActualSize; 1148 BufferEnd = BufferBegin+ActualSize;
1140 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); 1149 uint8_t *EhStart;
1150 uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd,
1151 EhStart);
1141 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 1152 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
1142 FrameRegister); 1153 FrameRegister);
1154 uint8_t *EhEnd = CurBufferPtr;
1143 BufferBegin = SavedBufferBegin; 1155 BufferBegin = SavedBufferBegin;
1144 BufferEnd = SavedBufferEnd; 1156 BufferEnd = SavedBufferEnd;
1145 CurBufferPtr = SavedCurBufferPtr; 1157 CurBufferPtr = SavedCurBufferPtr;
1146 1158
1147 TheJIT->RegisterTable(FrameRegister); 1159 if (DwarfExceptionHandling) {
1160 TheJIT->RegisterTable(FrameRegister);
1161 }
1162
1163 if (JITEmitDebugInfo) {
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);
1170 }
1148 } 1171 }
1149 1172
1150 if (MMI) 1173 if (MMI)
1151 MMI->EndFunction(); 1174 MMI->EndFunction();
1152 1175
1153 return false; 1176 return false;
1154 } 1177 }
1155 1178
1156 void JITEmitter::retryWithMoreMemory(MachineFunction &F) { 1179 void JITEmitter::retryWithMoreMemory(MachineFunction &F) {
1157 DEBUG(errs() << "JIT: Ran out of space for native code. Reattempting.\n"); 1180 DEBUG(errs() << "JIT: Ran out of space for native code. Reattempting.\n");
1158 Relocations.clear(); // Clear the old relocations or we'll reapply them. 1181 Relocations.clear(); // Clear the old relocations or we'll reapply them.
1159 ConstPoolAddresses.clear(); 1182 ConstPoolAddresses.clear();
1160 ++NumRetries; 1183 ++NumRetries;
1161 deallocateMemForFunction(F.getFunction()); 1184 deallocateMemForFunction(F.getFunction());
1162 // Try again with at least twice as much free space. 1185 // Try again with at least twice as much free space.
1163 SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin)); 1186 SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin));
1164 } 1187 }
1165 1188
1166 /// deallocateMemForFunction - Deallocate all memory for the specified 1189 /// deallocateMemForFunction - Deallocate all memory for the specified
1167 /// function body. Also drop any references the function has to stubs. 1190 /// function body. Also drop any references the function has to stubs.
1168 void JITEmitter::deallocateMemForFunction(const Function *F) { 1191 void JITEmitter::deallocateMemForFunction(const Function *F) {
1169 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 }
1170 1199
1171 // If the function did not reference any stubs, return. 1200 // If the function did not reference any stubs, return.
1172 if (CurFnStubUses.find(F) == CurFnStubUses.end()) 1201 if (CurFnStubUses.find(F) == CurFnStubUses.end())
1173 return; 1202 return;
1174 1203
1175 // 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
1176 // erase the list of referenced stubs. 1205 // erase the list of referenced stubs.
1177 SmallVectorImpl<void *> &StubList = CurFnStubUses[F]; 1206 SmallVectorImpl<void *> &StubList = CurFnStubUses[F];
1178 for (unsigned i = 0, e = StubList.size(); i != e; ++i) { 1207 for (unsigned i = 0, e = StubList.size(); i != e; ++i) {
1179 void *Stub = StubList[i]; 1208 void *Stub = StubList[i];
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 1412
1384 Offset *= EntrySize; 1413 Offset *= EntrySize;
1385 1414
1386 return (uintptr_t)((char *)JumpTableBase + Offset); 1415 return (uintptr_t)((char *)JumpTableBase + Offset);
1387 } 1416 }
1388 1417
1389 //===----------------------------------------------------------------------===// 1418 //===----------------------------------------------------------------------===//
1390 // Public interface to this file 1419 // Public interface to this file
1391 //===----------------------------------------------------------------------===// 1420 //===----------------------------------------------------------------------===//
1392 1421
1393 JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM) { 1422 JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM,
1394 return new JITEmitter(jit, JMM); 1423 TargetMachine &tm) {
1424 return new JITEmitter(jit, JMM, tm);
1395 } 1425 }
1396 1426
1397 // getPointerToNamedFunction - This function is used as a global wrapper to 1427 // getPointerToNamedFunction - This function is used as a global wrapper to
1398 // JIT::getPointerToNamedFunction for the purpose of resolving symbols when 1428 // JIT::getPointerToNamedFunction for the purpose of resolving symbols when
1399 // bugpoint is debugging the JIT. In that scenario, we are loading an .so and 1429 // bugpoint is debugging the JIT. In that scenario, we are loading an .so and
1400 // need to resolve function(s) that are being mis-codegenerated, so we need to 1430 // need to resolve function(s) that are being mis-codegenerated, so we need to
1401 // resolve their addresses at runtime, and this is the way to do it. 1431 // resolve their addresses at runtime, and this is the way to do it.
1402 extern "C" { 1432 extern "C" {
1403 void *getPointerToNamedFunction(const char *Name) { 1433 void *getPointerToNamedFunction(const char *Name) {
1404 if (Function *F = TheJIT->FindFunctionNamed(Name)) 1434 if (Function *F = TheJIT->FindFunctionNamed(Name))
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 // retranslated next time it is used. 1558 // retranslated next time it is used.
1529 void *OldPtr = updateGlobalMapping(F, 0); 1559 void *OldPtr = updateGlobalMapping(F, 0);
1530 1560
1531 if (OldPtr) 1561 if (OldPtr)
1532 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); 1562 TheJIT->NotifyFreeingMachineCode(*F, OldPtr);
1533 1563
1534 // Free the actual memory for the function body and related stuff. 1564 // Free the actual memory for the function body and related stuff.
1535 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1565 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?");
1536 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); 1566 cast<JITEmitter>(JCE)->deallocateMemForFunction(F);
1537 } 1567 }
OLDNEW

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