llvm.org GIT mirror llvm / d6b7a24
Add support to the JIT for true non-lazy operation. When a call to a function that has not been JIT'd yet, the callee is put on a list of pending functions to JIT. The call is directed through a stub, which is updated with the address of the function after it has been JIT'd. A new interface for allocating and updating empty stubs is provided. Add support for removing the ModuleProvider the JIT was created with, which would otherwise invalidate the JIT's PassManager, which is initialized with the ModuleProvider's Module. Add support under a new ExecutionEngine flag for emitting the infomration necessary to update Function and GlobalVariable stubs after JITing them, by recording the address of the stub and the name of the GlobalValue. This allows code to be copied from one address space to another, where libraries may live at different virtual addresses, and have the stubs updated with their new correct target addresses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64906 91177308-0d34-0410-b5e6-96231b3b80d8 Nate Begeman 11 years ago
13 changed file(s) with 290 addition(s) and 41 deletion(s). Raw diff Collapse all Expand all
8181 virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
8282 unsigned Alignment = 1) = 0;
8383
84 /// startGVStub - This callback is invoked when the JIT needs the address of a
85 /// GV (e.g. function) that has not been code generated yet. Buffer points to
86 /// memory already allocated for this stub.
87 ///
88 virtual void startGVStub(const GlobalValue* GV, void *Buffer,
89 unsigned StubSize) = 0;
90
8491 /// finishGVStub - This callback is invoked to terminate a GV stub.
8592 ///
8693 virtual void *finishGVStub(const GlobalValue* F) = 0;
6565 bool LazyCompilationDisabled;
6666 bool GVCompilationDisabled;
6767 bool SymbolSearchingDisabled;
68 bool DlsymStubsEnabled;
6869
6970 protected:
7071 /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We
287288 return SymbolSearchingDisabled;
288289 }
289290
291 /// EnableDlsymStubs -
292 void EnableDlsymStubs(bool Enabled = true) {
293 DlsymStubsEnabled = Enabled;
294 }
295 bool areDlsymStubsEnabled() const {
296 return DlsymStubsEnabled;
297 }
290298
291299 /// InstallLazyFunctionCreator - If an unknown function is needed, the
292300 /// specified function pointer is invoked to create it. If it returns null,
6161 /// return a pointer to its base.
6262 virtual unsigned char *getGOTBase() const = 0;
6363
64 /// SetDlsymTable - If the JIT must be able to relocate stubs after they have
65 /// been emitted, potentially because they are being copied to a process
66 /// where external symbols live at different addresses than in the JITing
67 /// process, allocate a table with sufficient information to do so.
68 virtual void SetDlsymTable(void *ptr) = 0;
69
70 /// getDlsymTable - If this is managing a table of entries so that stubs to
71 /// external symbols can be later relocated, this method should return a
72 /// pointer to it.
73 virtual void *getDlsymTable() const = 0;
74
6475 /// NeedsExactSize - If the memory manager requires to know the size of the
6576 /// objects to be emitted
6677 bool NeedsExactSize() const {
5454 MachineCodeEmitter &MCE) {
5555 assert(0 && "This target doesn't implement emitFunctionStub!");
5656 return 0;
57 }
58
59 /// emitFunctionStubAtAddr - Use the specified MachineCodeEmitter object to
60 /// emit a small native function that simply calls Fn. Emit the stub into
61 /// the supplied buffer.
62 virtual void emitFunctionStubAtAddr(const Function* F, void *Fn,
63 void *Buffer, MachineCodeEmitter &MCE) {
64 assert(0 && "This target doesn't implement emitFunctionStubAtAddr!");
5765 }
5866
5967 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
117117 /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
118118 void startGVStub(const GlobalValue* F, unsigned StubSize,
119119 unsigned Alignment = 1) {
120 assert(0 && "JIT specific function called!");
121 abort();
122 }
123 void startGVStub(const GlobalValue* F, void *Buffer, unsigned StubSize) {
120124 assert(0 && "JIT specific function called!");
121125 abort();
122126 }
143143 /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
144144 virtual void startGVStub(const GlobalValue* F, unsigned StubSize,
145145 unsigned Alignment = 1) {
146 assert(0 && "JIT specific function called!");
147 abort();
148 }
149 virtual void startGVStub(const GlobalValue* F, void *Buffer,
150 unsigned StubSize) {
146151 assert(0 && "JIT specific function called!");
147152 abort();
148153 }
4141 LazyCompilationDisabled = false;
4242 GVCompilationDisabled = false;
4343 SymbolSearchingDisabled = false;
44 DlsymStubsEnabled = false;
4445 Modules.push_back(P);
4546 assert(P && "ModuleProvider is null?");
4647 }
288288 Module *result = ExecutionEngine::removeModuleProvider(MP, E);
289289
290290 MutexGuard locked(lock);
291 if (Modules.empty()) {
291
292 if (jitstate->getMP() == MP) {
292293 delete jitstate;
293294 jitstate = 0;
294295 }
295296
297 if (!jitstate && !Modules.empty()) {
298 jitstate = new JITState(Modules[0]);
299
300 FunctionPassManager &PM = jitstate->getPM(locked);
301 PM.add(new TargetData(*TM.getTargetData()));
302
303 // Turn the machine code intermediate representation into bytes in memory
304 // that may be executed.
305 if (TM.addPassesToEmitMachineCode(PM, *MCE, false /*fast*/)) {
306 cerr << "Target does not support machine code emission!\n";
307 abort();
308 }
309
310 // Initialize passes.
311 PM.doInitialization();
312 }
296313 return result;
297314 }
298315
303320 ExecutionEngine::deleteModuleProvider(MP, E);
304321
305322 MutexGuard locked(lock);
306 if (Modules.empty()) {
323
324 if (jitstate->getMP() == MP) {
307325 delete jitstate;
308326 jitstate = 0;
309327 }
328
329 if (!jitstate && !Modules.empty()) {
330 jitstate = new JITState(Modules[0]);
331
332 FunctionPassManager &PM = jitstate->getPM(locked);
333 PM.add(new TargetData(*TM.getTargetData()));
334
335 // Turn the machine code intermediate representation into bytes in memory
336 // that may be executed.
337 if (TM.addPassesToEmitMachineCode(PM, *MCE, false /*fast*/)) {
338 cerr << "Target does not support machine code emission!\n";
339 abort();
340 }
341
342 // Initialize passes.
343 PM.doInitialization();
344 }
310345 }
311346
312347 /// run - Start execution with the specified function and arguments.
487522 jitstate->getPM(locked).run(*F);
488523 isAlreadyCodeGenerating = false;
489524
490 // If the function referred to a global variable that had not yet been
491 // emitted, it allocates memory for the global, but doesn't emit it yet. Emit
492 // all of these globals now.
493 while (!jitstate->getPendingGlobals(locked).empty()) {
494 const GlobalVariable *GV = jitstate->getPendingGlobals(locked).back();
495 jitstate->getPendingGlobals(locked).pop_back();
496 EmitGlobalVariable(GV);
497 }
525 // If the function referred to another function that had not yet been
526 // read from bitcode, but we are jitting non-lazily, emit it now.
527 while (!jitstate->getPendingFunctions(locked).empty()) {
528 Function *PF = jitstate->getPendingFunctions(locked).back();
529 jitstate->getPendingFunctions(locked).pop_back();
530
531 // JIT the function
532 isAlreadyCodeGenerating = true;
533 jitstate->getPM(locked).run(*PF);
534 isAlreadyCodeGenerating = false;
535
536 // Now that the function has been jitted, ask the JITEmitter to rewrite
537 // the stub with real address of the function.
538 updateFunctionStub(PF);
539 }
540
541 // If the JIT is configured to emit info so that dlsym can be used to
542 // rewrite stubs to external globals, do so now.
543 if (areDlsymStubsEnabled() && isLazyCompilationDisabled())
544 updateDlsymStubTable();
498545 }
499546
500547 /// getPointerToFunction - This method is used to get the address of the
643690 return new char[GVSize];
644691 }
645692 }
693
694 void JIT::addPendingFunction(Function *F) {
695 MutexGuard locked(lock);
696 jitstate->getPendingFunctions(locked).push_back(F);
697 }
1919 namespace llvm {
2020
2121 class Function;
22 class GlobalValue;
23 class Constant;
2422 class TargetMachine;
2523 class TargetJITInfo;
2624 class MachineCodeEmitter;
2826 class JITState {
2927 private:
3028 FunctionPassManager PM; // Passes to compile a function
29 ModuleProvider *MP; // ModuleProvider used to create the PM
3130
32 /// PendingGlobals - Global variables which have had memory allocated for them
33 /// while a function was code generated, but which have not been initialized
34 /// yet.
35 std::vector PendingGlobals;
31 /// PendingFunctions - Functions which have not been code generated yet, but
32 /// were called from a function being code generated.
33 std::vector PendingFunctions;
3634
3735 public:
38 explicit JITState(ModuleProvider *MP) : PM(MP) {}
36 explicit JITState(ModuleProvider *MP) : PM(MP), MP(MP) {}
3937
4038 FunctionPassManager &getPM(const MutexGuard &L) {
4139 return PM;
4240 }
43
44 std::vector &getPendingGlobals(const MutexGuard &L) {
45 return PendingGlobals;
41
42 ModuleProvider *getMP() const { return MP; }
43 std::vector &getPendingFunctions(const MutexGuard &L) {
44 return PendingFunctions;
4645 }
4746 };
4847
138137 ///
139138 void freeMachineCodeForFunction(Function *F);
140139
140 /// addPendingFunction - while jitting non-lazily, a called but non-codegen'd
141 /// function was encountered. Add it to a pending list to be processed after
142 /// the current function.
143 ///
144 void addPendingFunction(Function *F);
145
141146 /// getCodeEmitter - Return the code emitter this JIT is emitting into.
142147 MachineCodeEmitter *getCodeEmitter() const { return MCE; }
143148
148153 static MachineCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM);
149154 void runJITOnFunction(Function *F);
150155 void runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked);
151
156 void updateFunctionStub(Function *F);
157 void updateDlsymStubTable();
158
152159 protected:
153160
154161 /// getMemoryforGV - Allocate memory for a global variable.
3535 #include "llvm/System/Memory.h"
3636 #include "llvm/Target/TargetInstrInfo.h"
3737 #include "llvm/ADT/SmallPtrSet.h"
38 #include "llvm/ADT/SmallVector.h"
3839 #include "llvm/ADT/Statistic.h"
3940 #include
4041 #ifndef NDEBUG
119120 void *getFunctionStubIfAvailable(Function *F);
120121
121122 /// getFunctionStub - This returns a pointer to a function stub, creating
122 /// one on demand as needed.
123 void *getFunctionStub(Function *F);
123 /// one on demand as needed. If empty is true, create a function stub
124 /// pointing at address 0, to be filled in later.
125 void *getFunctionStub(Function *F, bool empty = false);
124126
125127 /// getExternalFunctionStub - Return a stub for the function at the
126128 /// specified address, created lazily on demand.
139141 state.getStubToFunctionMap(locked)[Location] = F;
140142 return (void*)(intptr_t)LazyResolverFn;
141143 }
144
145 void getRelocatableGVs(SmallVectorImpl &GVs,
146 SmallVectorImpl &Ptrs);
142147
143148 /// getGOTIndexForAddress - Return a new or existing index in the GOT for
144149 /// an address. This function only manages slots, it does not manage the
166171
167172 /// getFunctionStub - This returns a pointer to a function stub, creating
168173 /// one on demand as needed.
169 void *JITResolver::getFunctionStub(Function *F) {
174 void *JITResolver::getFunctionStub(Function *F, bool empty) {
170175 MutexGuard locked(TheJIT->lock);
171176
172177 // If we already have a stub for this function, recycle it.
175180
176181 // Call the lazy resolver function unless we already KNOW it is an external
177182 // function, in which case we just skip the lazy resolution step.
178 void *Actual = (void*)(intptr_t)LazyResolverFn;
183 void *Actual = empty ? (void*)0 : (void*)(intptr_t)LazyResolverFn;
179184 if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) {
180185 Actual = TheJIT->getPointerToFunction(F);
181186
202207 // Finally, keep track of the stub-to-Function mapping so that the
203208 // JITCompilerFn knows which function to compile!
204209 state.getStubToFunctionMap(locked)[Stub] = F;
210
211 // If this is an "empty" stub, then inform the JIT that it will need to
212 // JIT the function so an address can be provided.
213 if (empty)
214 TheJIT->addPendingFunction(F);
215
205216 return Stub;
206217 }
207218
247258 DOUT << "JIT: Adding GOT entry " << idx << " for addr [" << addr << "]\n";
248259 }
249260 return idx;
261 }
262
263 void JITResolver::getRelocatableGVs(SmallVectorImpl &GVs,
264 SmallVectorImpl &Ptrs) {
265 MutexGuard locked(TheJIT->lock);
266
267 std::map &FM = state.getFunctionToStubMap(locked);
268 std::map &GM = state.getGlobalToIndirectSymMap(locked);
269
270 for (std::map::iterator i = FM.begin(), e = FM.end();
271 i != e; ++i) {
272 Function *F = i->first;
273 if (F->isDeclaration() && F->hasExternalLinkage()) {
274 GVs.push_back(i->first);
275 Ptrs.push_back(i->second);
276 }
277 }
278 for (std::map::iterator i = GM.begin(), e = GM.end();
279 i != e; ++i) {
280 GVs.push_back(i->first);
281 Ptrs.push_back(i->second);
282 }
250283 }
251284
252285 /// JITCompilerFn - This function is called when a lazy compilation stub has
398431 JitSymbolEntry *OldSymbols = SymTabPtr->Symbols;
399432
400433 // Copy the old entries over.
401 memcpy(NewSymbols, OldSymbols,
402 SymTabPtr->NumSymbols*sizeof(OldSymbols[0]));
434 memcpy(NewSymbols, OldSymbols, SymTabPtr->NumSymbols*sizeof(OldSymbols[0]));
403435
404436 // Swap the new symbols in, delete the old ones.
405437 SymTabPtr->Symbols = NewSymbols;
537569
538570 virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
539571 unsigned Alignment = 1);
572 virtual void startGVStub(const GlobalValue* GV, void *Buffer,
573 unsigned StubSize);
540574 virtual void* finishGVStub(const GlobalValue *GV);
541575
542576 /// allocateSpace - Reserves space in the current block if any, or
590624 void setMemoryExecutable(void) {
591625 MemMgr->setMemoryExecutable();
592626 }
627
628 JITMemoryManager *getMemMgr(void) const { return MemMgr; }
593629
594630 private:
595631 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
604640
605641 void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
606642 bool DoesntNeedStub) {
607 if (GlobalVariable *GV = dyn_cast(V)) {
608 /// FIXME: If we straightened things out, this could actually emit the
609 /// global immediately instead of queuing it for codegen later!
643 if (GlobalVariable *GV = dyn_cast(V))
610644 return TheJIT->getOrEmitGlobalVariable(GV);
611 }
645
612646 if (GlobalAlias *GA = dyn_cast(V))
613647 return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false));
614648
622656 ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F);
623657 if (ResultPtr) return ResultPtr;
624658
625 if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) {
626 // If this is an external function pointer, we can force the JIT to
627 // 'compile' it, which really just adds it to the map.
628 if (DoesntNeedStub)
629 return TheJIT->getPointerToFunction(F);
630
631 return Resolver.getFunctionStub(F);
632 }
633
659 // If this is an external function pointer, we can force the JIT to
660 // 'compile' it, which really just adds it to the map.
661 if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode() && DoesntNeedStub)
662 return TheJIT->getPointerToFunction(F);
663
664 // If we are jitting non-lazily but encounter a function that has not been
665 // jitted yet, we need to allocate a blank stub to call the function
666 // once we JIT it and its address is known.
667 if (TheJIT->isLazyCompilationDisabled())
668 if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode())
669 return Resolver.getFunctionStub(F, true);
670
634671 // Okay, the function has not been compiled yet, if the target callback
635672 // mechanism is capable of rewriting the instruction directly, prefer to do
636673 // that instead of emitting a stub.
11741211 BufferEnd = BufferBegin+StubSize+1;
11751212 }
11761213
1214 void JITEmitter::startGVStub(const GlobalValue* GV, void *Buffer,
1215 unsigned StubSize) {
1216 SavedBufferBegin = BufferBegin;
1217 SavedBufferEnd = BufferEnd;
1218 SavedCurBufferPtr = CurBufferPtr;
1219
1220 BufferBegin = CurBufferPtr = (unsigned char *)Buffer;
1221 BufferEnd = BufferBegin+StubSize+1;
1222 }
1223
11771224 void *JITEmitter::finishGVStub(const GlobalValue* GV) {
11781225 NumBytes += getCurrentPCOffset();
11791226 std::swap(SavedBufferBegin, BufferBegin);
12471294 return JE->getJITResolver().getFunctionStub(F);
12481295 }
12491296
1297 void JIT::updateFunctionStub(Function *F) {
1298 // Get the empty stub we generated earlier.
1299 assert(isa(MCE) && "Unexpected MCE?");
1300 JITEmitter *JE = cast(getCodeEmitter());
1301 void *Stub = JE->getJITResolver().getFunctionStub(F);
1302
1303 // Tell the target jit info to rewrite the stub at the specified address,
1304 // rather than creating a new one.
1305 void *Addr = getPointerToGlobalIfAvailable(F);
1306 getJITInfo().emitFunctionStubAtAddr(F, Addr, Stub, *getCodeEmitter());
1307 }
1308
1309 /// updateDlsymStubTable - Emit the data necessary to relocate the stubs
1310 /// that were emitted during code generation.
1311 ///
1312 void JIT::updateDlsymStubTable() {
1313 assert(isa(MCE) && "Unexpected MCE?");
1314 JITEmitter *JE = cast(getCodeEmitter());
1315
1316 SmallVector GVs;
1317 SmallVector Ptrs;
1318
1319 JE->getJITResolver().getRelocatableGVs(GVs, Ptrs);
1320
1321 // If there are no relocatable stubs, return.
1322 if (GVs.empty())
1323 return;
1324
1325 // If there are no new relocatable stubs, return.
1326 void *CurTable = JE->getMemMgr()->getDlsymTable();
1327 if (CurTable && (*(unsigned *)CurTable == GVs.size()))
1328 return;
1329
1330 // Calculate the size of the stub info
1331 unsigned offset = 4 + 4 * GVs.size();
1332
1333 SmallVector Offsets;
1334 for (unsigned i = 0; i != GVs.size(); ++i) {
1335 Offsets.push_back(offset);
1336 offset += GVs[i]->getName().length() + 1;
1337 }
1338
1339 // FIXME: This currently allocates new space every time it's called. A
1340 // different data structure could be used to make this unnecessary.
1341 JE->startGVStub(0, offset, 4);
1342
1343 // Emit the number of records
1344 MCE->emitInt32(GVs.size());
1345
1346 // Emit the string offsets
1347 for (unsigned i = 0; i != GVs.size(); ++i)
1348 MCE->emitInt32(Offsets[i]);
1349
1350 // Emit the pointers
1351 for (unsigned i = 0; i != GVs.size(); ++i)
1352 if (sizeof(void *) == 8)
1353 MCE->emitInt64((intptr_t)Ptrs[i]);
1354 else
1355 MCE->emitInt32((intptr_t)Ptrs[i]);
1356
1357 // Emit the strings
1358 for (unsigned i = 0; i != GVs.size(); ++i)
1359 MCE->emitString(GVs[i]->getName());
1360
1361 // Tell the JIT memory manager where it is.
1362 JE->getMemMgr()->SetDlsymTable(JE->finishGVStub(0));
1363 }
1364
12501365 /// freeMachineCodeForFunction - release machine code memory for given Function.
12511366 ///
12521367 void JIT::freeMachineCodeForFunction(Function *F) {
257257
258258 unsigned char *CurStubPtr, *StubBase;
259259 unsigned char *GOTBase; // Target Specific reserved memory
260 void *DlsymTable; // Stub external symbol information
260261
261262 // Centralize memory block allocation.
262263 sys::MemoryBlock getNewMemoryBlock(unsigned size);
268269 ~DefaultJITMemoryManager();
269270
270271 void AllocateGOT();
271
272 void SetDlsymTable(void *);
273
272274 unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
273275 unsigned Alignment);
274276
340342
341343 unsigned char *getGOTBase() const {
342344 return GOTBase;
345 }
346
347 void *getDlsymTable() const {
348 return DlsymTable;
343349 }
344350
345351 /// deallocateMemForFunction - Deallocate all memory for the specified
462468 FreeMemoryList = Mem0;
463469
464470 GOTBase = NULL;
471 DlsymTable = NULL;
465472 }
466473
467474 void DefaultJITMemoryManager::AllocateGOT() {
470477 HasGOT = true;
471478 }
472479
480 void DefaultJITMemoryManager::SetDlsymTable(void *ptr) {
481 DlsymTable = ptr;
482 }
473483
474484 DefaultJITMemoryManager::~DefaultJITMemoryManager() {
475485 for (unsigned i = 0, e = Blocks.size(); i != e; ++i)
489489 return MCE.finishGVStub(F);
490490 }
491491
492 void X86JITInfo::emitFunctionStubAtAddr(const Function* F, void *Fn, void *Stub,
493 MachineCodeEmitter &MCE) {
494 // Note, we cast to intptr_t here to silence a -pedantic warning that
495 // complains about casting a function pointer to a normal pointer.
496 MCE.startGVStub(F, Stub, 5);
497 MCE.emitByte(0xE9);
498 #if defined (X86_64_JIT)
499 assert(((((intptr_t)Fn-MCE.getCurrentPCValue()-5) << 32) >> 32) ==
500 ((intptr_t)Fn-MCE.getCurrentPCValue()-5)
501 && "PIC displacement does not fit in displacement field!");
502 #endif
503 MCE.emitWordLE((intptr_t)Fn-MCE.getCurrentPCValue()-4);
504 MCE.finishGVStub(F);
505 }
506
492507 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
493508 /// specific basic block.
494509 uintptr_t X86JITInfo::getPICJumpTableEntry(uintptr_t BB, uintptr_t Entry) {
4848 virtual void *emitFunctionStub(const Function* F, void *Fn,
4949 MachineCodeEmitter &MCE);
5050
51 /// emitFunctionStubAtAddr - Use the specified MachineCodeEmitter object to
52 /// emit a small native function that simply calls Fn. Emit the stub into
53 /// the supplied buffer.
54 virtual void emitFunctionStubAtAddr(const Function* F, void *Fn,
55 void *Buffer, MachineCodeEmitter &MCE);
56
5157 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
5258 /// specific basic block.
5359 virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase);