llvm.org GIT mirror llvm / 108c838
* Move stub allocation inside the JITEmitter, instead of exposing a way for each TargetJITInfo subclass to allocate its own stubs. This means stubs aren't as exactly-sized anymore, but it lets us get rid of TargetJITInfo::emitFunctionStubAtAddr(), which lets ARM and PPC support the eager JIT, fixing http://llvm.org/PR4816. * Rename the JITEmitter's stub creation functions to describe the kind of stub they create. So far, all of them create lazy-compilation stubs, but they sometimes get used when far-call stubs are needed. Fixing http://llvm.org/PR5201 will involve fixing this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89715 91177308-0d34-0410-b5e6-96231b3b80d8 Jeffrey Yasskin 11 years ago
11 changed file(s) with 209 addition(s) and 136 deletion(s). Raw diff Collapse all Expand all
1717 #define LLVM_TARGET_TARGETJITINFO_H
1818
1919 #include
20 #include "llvm/Support/ErrorHandling.h"
2021 #include "llvm/System/DataTypes.h"
2122
2223 namespace llvm {
4748 return 0;
4849 }
4950
51 /// Records the required size and alignment for a call stub in bytes.
52 struct StubLayout {
53 size_t Size;
54 size_t Alignment;
55 };
56 /// Returns the maximum size and alignment for a call stub on this target.
57 virtual StubLayout getStubLayout() {
58 llvm_unreachable("This target doesn't implement getStubLayout!");
59 StubLayout Result = {0, 0};
60 return Result;
61 }
62
5063 /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
5164 /// small native function that simply calls the function at the specified
52 /// address. Return the address of the resultant function.
53 virtual void *emitFunctionStub(const Function* F, void *Fn,
65 /// address. The JITCodeEmitter must already have storage allocated for the
66 /// stub. Return the address of the resultant function, which may have been
67 /// aligned from the address the JCE was set up to emit at.
68 virtual void *emitFunctionStub(const Function* F, void *Target,
5469 JITCodeEmitter &JCE) {
5570 assert(0 && "This target doesn't implement emitFunctionStub!");
5671 return 0;
57 }
58
59 /// emitFunctionStubAtAddr - Use the specified JITCodeEmitter 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, JITCodeEmitter &JCE) {
64 assert(0 && "This target doesn't implement emitFunctionStubAtAddr!");
6572 }
6673
6774 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
8282 class JITResolverState {
8383 public:
8484 typedef ValueMap >
85 FunctionToStubMapTy;
85 FunctionToLazyStubMapTy;
8686 typedef std::map > CallSiteToFunctionMapTy;
8787 typedef ValueMap,
8888 CallSiteValueMapConfig> FunctionToCallSitesMapTy;
8989 typedef std::map, void*> GlobalToIndirectSymMapTy;
9090 private:
91 /// FunctionToStubMap - Keep track of the stub created for a particular
92 /// function so that we can reuse them if necessary.
93 FunctionToStubMapTy FunctionToStubMap;
91 /// FunctionToLazyStubMap - Keep track of the lazy stub created for a
92 /// particular function so that we can reuse them if necessary.
93 FunctionToLazyStubMapTy FunctionToLazyStubMap;
9494
9595 /// CallSiteToFunctionMap - Keep track of the function that each lazy call
9696 /// site corresponds to, and vice versa.
102102 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
103103
104104 public:
105 JITResolverState() : FunctionToStubMap(this),
105 JITResolverState() : FunctionToLazyStubMap(this),
106106 FunctionToCallSitesMap(this) {}
107107
108 FunctionToStubMapTy& getFunctionToStubMap(const MutexGuard& locked) {
108 FunctionToLazyStubMapTy& getFunctionToLazyStubMap(
109 const MutexGuard& locked) {
109110 assert(locked.holds(TheJIT->lock));
110 return FunctionToStubMap;
111 return FunctionToLazyStubMap;
111112 }
112113
113114 GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& locked) {
153154
154155 Function *const F = C2F_I->second;
155156 #ifndef NDEBUG
156 void *RealStub = FunctionToStubMap.lookup(F);
157 void *RealStub = FunctionToLazyStubMap.lookup(F);
157158 assert(RealStub == Stub &&
158159 "Call-site that wasn't a stub pass in to EraseStub");
159160 #endif
160 FunctionToStubMap.erase(F);
161 FunctionToLazyStubMap.erase(F);
161162 CallSiteToFunctionMap.erase(C2F_I);
162163
163164 // Remove the stub from the function->call-sites map, and remove the whole
195196 /// JITResolver - Keep track of, and resolve, call sites for functions that
196197 /// have not yet been compiled.
197198 class JITResolver {
198 typedef JITResolverState::FunctionToStubMapTy FunctionToStubMapTy;
199 typedef JITResolverState::FunctionToLazyStubMapTy FunctionToLazyStubMapTy;
199200 typedef JITResolverState::CallSiteToFunctionMapTy CallSiteToFunctionMapTy;
200201 typedef JITResolverState::GlobalToIndirectSymMapTy GlobalToIndirectSymMapTy;
201202
205206
206207 JITResolverState state;
207208
208 /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for
209 /// external functions.
209 /// ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
210 /// for external functions. TODO: Of course, external functions don't need
211 /// a lazy stub. It's actually here to make it more likely that far calls
212 /// succeed, but no single stub can guarantee that. I'll remove this in a
213 /// subsequent checkin when I actually fix far calls.
210214 std::map ExternalFnToStubMap;
211215
212216 /// revGOTMap - map addresses to indexes in the GOT
229233 TheJITResolver = 0;
230234 }
231235
232 /// getFunctionStubIfAvailable - This returns a pointer to a function stub
233 /// if it has already been created.
234 void *getFunctionStubIfAvailable(Function *F);
235
236 /// getFunctionStub - This returns a pointer to a function stub, creating
237 /// one on demand as needed. If empty is true, create a function stub
238 /// pointing at address 0, to be filled in later.
239 void *getFunctionStub(Function *F);
236 /// getLazyFunctionStubIfAvailable - This returns a pointer to a function's
237 /// lazy-compilation stub if it has already been created.
238 void *getLazyFunctionStubIfAvailable(Function *F);
239
240 /// getLazyFunctionStub - This returns a pointer to a function's
241 /// lazy-compilation stub, creating one on demand as needed.
242 void *getLazyFunctionStub(Function *F);
240243
241244 /// getExternalFunctionStub - Return a stub for the function at the
242245 /// specified address, created lazily on demand.
484487 JRS->EraseAllCallSitesPrelocked(F);
485488 }
486489
487 /// getFunctionStubIfAvailable - This returns a pointer to a function stub
490 /// getLazyFunctionStubIfAvailable - This returns a pointer to a function stub
488491 /// if it has already been created.
489 void *JITResolver::getFunctionStubIfAvailable(Function *F) {
492 void *JITResolver::getLazyFunctionStubIfAvailable(Function *F) {
490493 MutexGuard locked(TheJIT->lock);
491494
492495 // If we already have a stub for this function, recycle it.
493 return state.getFunctionToStubMap(locked).lookup(F);
496 return state.getFunctionToLazyStubMap(locked).lookup(F);
494497 }
495498
496499 /// getFunctionStub - This returns a pointer to a function stub, creating
497500 /// one on demand as needed.
498 void *JITResolver::getFunctionStub(Function *F) {
501 void *JITResolver::getLazyFunctionStub(Function *F) {
499502 MutexGuard locked(TheJIT->lock);
500503
501 // If we already have a stub for this function, recycle it.
502 void *&Stub = state.getFunctionToStubMap(locked)[F];
504 // If we already have a lazy stub for this function, recycle it.
505 void *&Stub = state.getFunctionToLazyStubMap(locked)[F];
503506 if (Stub) return Stub;
504507
505508 // Call the lazy resolver function if we are JIT'ing lazily. Otherwise we
517520 if (!Actual) return 0;
518521 }
519522
523 MachineCodeEmitter::BufferState BS;
524 TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
525 JE.startGVStub(BS, F, SL.Size, SL.Alignment);
520526 // Codegen a new stub, calling the lazy resolver or the actual address of the
521527 // external function, if it was resolved.
522528 Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE);
529 JE.finishGVStub(BS);
523530
524531 if (Actual != (void*)(intptr_t)LazyResolverFn) {
525532 // If we are getting the stub for an external function, we really want the
528535 TheJIT->updateGlobalMapping(F, Stub);
529536 }
530537
531 DEBUG(errs() << "JIT: Stub emitted at [" << Stub << "] for function '"
538 DEBUG(errs() << "JIT: Lazy stub emitted at [" << Stub << "] for function '"
532539 << F->getName() << "'\n");
533540
534541 // Finally, keep track of the stub-to-Function mapping so that the
571578 void *&Stub = ExternalFnToStubMap[FnAddr];
572579 if (Stub) return Stub;
573580
581 MachineCodeEmitter::BufferState BS;
582 TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
583 JE.startGVStub(BS, 0, SL.Size, SL.Alignment);
574584 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE);
585 JE.finishGVStub(BS);
575586
576587 DEBUG(errs() << "JIT: Stub emitted at [" << Stub
577588 << "] for external function at '" << FnAddr << "'\n");
593604 SmallVectorImpl &Ptrs) {
594605 MutexGuard locked(TheJIT->lock);
595606
596 const FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked);
607 const FunctionToLazyStubMapTy &FM = state.getFunctionToLazyStubMap(locked);
597608 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
598609
599 for (FunctionToStubMapTy::const_iterator i = FM.begin(), e = FM.end();
610 for (FunctionToLazyStubMapTy::const_iterator i = FM.begin(), e = FM.end();
600611 i != e; ++i){
601612 Function *F = i->first;
602613 if (F->isDeclaration() && F->hasExternalLinkage()) {
722733 // If we have already compiled the function, return a pointer to its body.
723734 Function *F = cast(V);
724735
725 void *FnStub = Resolver.getFunctionStubIfAvailable(F);
736 void *FnStub = Resolver.getLazyFunctionStubIfAvailable(F);
726737 if (FnStub) {
727 // Return the function stub if it's already created. We do this first
728 // so that we're returning the same address for the function as any
729 // previous call.
738 // Return the function stub if it's already created. We do this first so
739 // that we're returning the same address for the function as any previous
740 // call. TODO: Yes, this is wrong. The lazy stub isn't guaranteed to be
741 // close enough to call.
730742 AddStubToCurrentFunction(FnStub);
731743 return FnStub;
732744 }
746758
747759 // Otherwise, we may need a to emit a stub, and, conservatively, we
748760 // always do so.
749 void *StubAddr = Resolver.getFunctionStub(F);
761 void *StubAddr = Resolver.getLazyFunctionStub(F);
750762
751763 // Add the stub to the current function's list of referenced stubs, so we can
752764 // deallocate them if the current function is ever freed. It's possible to
753 // return null from getFunctionStub in the case of a weak extern that fails
754 // to resolve.
765 // return null from getLazyFunctionStub in the case of a weak extern that
766 // fails to resolve.
755767 if (StubAddr)
756768 AddStubToCurrentFunction(StubAddr);
757769
14411453 }
14421454
14431455 void *JITEmitter::finishGVStub(BufferState &BS) {
1456 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
14441457 NumBytes += getCurrentPCOffset();
14451458 void *Result = BufferBegin;
14461459 RestoreStateFrom(BS);
15201533 // Get a stub if the target supports it.
15211534 assert(isa(JCE) && "Unexpected MCE?");
15221535 JITEmitter *JE = cast(getCodeEmitter());
1523 return JE->getJITResolver().getFunctionStub(F);
1536 return JE->getJITResolver().getLazyFunctionStub(F);
15241537 }
15251538
15261539 void JIT::updateFunctionStub(Function *F) {
15271540 // Get the empty stub we generated earlier.
15281541 assert(isa(JCE) && "Unexpected MCE?");
15291542 JITEmitter *JE = cast(getCodeEmitter());
1530 void *Stub = JE->getJITResolver().getFunctionStub(F);
1543 void *Stub = JE->getJITResolver().getLazyFunctionStub(F);
1544 void *Addr = getPointerToGlobalIfAvailable(F);
15311545
15321546 // Tell the target jit info to rewrite the stub at the specified address,
15331547 // rather than creating a new one.
1534 void *Addr = getPointerToGlobalIfAvailable(F);
1535 getJITInfo().emitFunctionStubAtAddr(F, Addr, Stub, *getCodeEmitter());
1548 MachineCodeEmitter::BufferState BS;
1549 TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout();
1550 JE->startGVStub(BS, Stub, layout.Size);
1551 getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter());
1552 JE->finishGVStub(BS);
15361553 }
15371554
15381555 /// freeMachineCodeForFunction - release machine code memory for given Function.
153153 return PtrAddr;
154154 }
155155
156 TargetJITInfo::StubLayout ARMJITInfo::getStubLayout() {
157 // The stub contains up to 3 4-byte instructions, aligned at 4 bytes, and a
158 // 4-byte address. See emitFunctionStub for details.
159 StubLayout Result = {16, 4};
160 return Result;
161 }
162
156163 void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
157164 JITCodeEmitter &JCE) {
158 MachineCodeEmitter::BufferState BS;
165 void *Addr;
159166 // If this is just a call to an external function, emit a branch instead of a
160167 // call. The code is the same except for one bit of the last instruction.
161168 if (Fn != (void*)(intptr_t)ARMCompilationCallback) {
162169 // Branch to the corresponding function addr.
163170 if (IsPIC) {
164 // The stub is 8-byte size and 4-aligned.
171 // The stub is 16-byte size and 4-aligned.
165172 intptr_t LazyPtr = getIndirectSymAddr(Fn);
166173 if (!LazyPtr) {
167174 // In PIC mode, the function stub is loading a lazy-ptr.
173180 errs() << "JIT: Stub emitted at [" << LazyPtr
174181 << "] for external function at '" << Fn << "'\n");
175182 }
176 JCE.startGVStub(BS, F, 16, 4);
177 intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
178 if (!sys::Memory::setRangeWritable((void*)Addr, 16)) {
183 JCE.emitAlignment(4);
184 Addr = (void*)JCE.getCurrentPCValue();
185 if (!sys::Memory::setRangeWritable(Addr, 16)) {
179186 llvm_unreachable("ERROR: Unable to mark stub writable");
180187 }
181188 JCE.emitWordLE(0xe59fc004); // ldr ip, [pc, #+4]
182189 JCE.emitWordLE(0xe08fc00c); // L_func$scv: add ip, pc, ip
183190 JCE.emitWordLE(0xe59cf000); // ldr pc, [ip]
184 JCE.emitWordLE(LazyPtr - (Addr+4+8)); // func - (L_func$scv+8)
185 sys::Memory::InvalidateInstructionCache((void*)Addr, 16);
186 if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) {
191 JCE.emitWordLE(LazyPtr - (intptr_t(Addr)+4+8)); // func - (L_func$scv+8)
192 sys::Memory::InvalidateInstructionCache(Addr, 16);
193 if (!sys::Memory::setRangeExecutable(Addr, 16)) {
187194 llvm_unreachable("ERROR: Unable to mark stub executable");
188195 }
189196 } else {
190197 // The stub is 8-byte size and 4-aligned.
191 JCE.startGVStub(BS, F, 8, 4);
192 intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
193 if (!sys::Memory::setRangeWritable((void*)Addr, 8)) {
198 JCE.emitAlignment(4);
199 Addr = (void*)JCE.getCurrentPCValue();
200 if (!sys::Memory::setRangeWritable(Addr, 8)) {
194201 llvm_unreachable("ERROR: Unable to mark stub writable");
195202 }
196203 JCE.emitWordLE(0xe51ff004); // ldr pc, [pc, #-4]
197204 JCE.emitWordLE((intptr_t)Fn); // addr of function
198 sys::Memory::InvalidateInstructionCache((void*)Addr, 8);
199 if (!sys::Memory::setRangeExecutable((void*)Addr, 8)) {
205 sys::Memory::InvalidateInstructionCache(Addr, 8);
206 if (!sys::Memory::setRangeExecutable(Addr, 8)) {
200207 llvm_unreachable("ERROR: Unable to mark stub executable");
201208 }
202209 }
208215 //
209216 // Branch and link to the compilation callback.
210217 // The stub is 16-byte size and 4-byte aligned.
211 JCE.startGVStub(BS, F, 16, 4);
212 intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
213 if (!sys::Memory::setRangeWritable((void*)Addr, 16)) {
218 JCE.emitAlignment(4);
219 Addr = (void*)JCE.getCurrentPCValue();
220 if (!sys::Memory::setRangeWritable(Addr, 16)) {
214221 llvm_unreachable("ERROR: Unable to mark stub writable");
215222 }
216223 // Save LR so the callback can determine which stub called it.
223230 JCE.emitWordLE(0xe51ff004); // ldr pc, [pc, #-4]
224231 // The address of the compilation callback.
225232 JCE.emitWordLE((intptr_t)ARMCompilationCallback);
226 sys::Memory::InvalidateInstructionCache((void*)Addr, 16);
227 if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) {
233 sys::Memory::InvalidateInstructionCache(Addr, 16);
234 if (!sys::Memory::setRangeExecutable(Addr, 16)) {
228235 llvm_unreachable("ERROR: Unable to mark stub executable");
229236 }
230237 }
231238
232 return JCE.finishGVStub(BS);
239 return Addr;
233240 }
234241
235242 intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const {
5959 /// ptr.
6060 virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
6161 JITCodeEmitter &JCE);
62
63 // getStubLayout - Returns the size and alignment of the largest call stub
64 // on ARM.
65 virtual StubLayout getStubLayout();
6266
6367 /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
6468 /// small native function that simply calls the function at the specified
189189 #endif
190190 }
191191
192 TargetJITInfo::StubLayout AlphaJITInfo::getStubLayout() {
193 // The stub contains 19 4-byte instructions, aligned at 4 bytes:
194 // R0 = R27
195 // 8 x "R27 <<= 8; R27 |= 8-bits-of-Target" == 16 instructions
196 // JMP R27
197 // Magic number so the compilation callback can recognize the stub.
198 StubLayout Result = {19 * 4, 4};
199 return Result;
200 }
201
192202 void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn,
193203 JITCodeEmitter &JCE) {
194204 MachineCodeEmitter::BufferState BS;
195205 //assert(Fn == AlphaCompilationCallback && "Where are you going?\n");
196206 //Do things in a stupid slow way!
197 JCE.startGVStub(BS, F, 19*4);
198207 void* Addr = (void*)(intptr_t)JCE.getCurrentPCValue();
199208 for (int x = 0; x < 19; ++ x)
200209 JCE.emitWordLE(0);
201210 EmitBranchToAt(Addr, Fn);
202211 DEBUG(errs() << "Emitting Stub to " << Fn << " at [" << Addr << "]\n");
203 return JCE.finishGVStub(BS);
212 return Addr;
204213 }
205214
206215 TargetJITInfo::LazyResolverFn
3030 explicit AlphaJITInfo(TargetMachine &tm) : TM(tm)
3131 { useGOT = true; }
3232
33 virtual StubLayout getStubLayout();
3334 virtual void *emitFunctionStub(const Function* F, void *Fn,
3435 JITCodeEmitter &JCE);
3536 virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
322322 return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback;
323323 }
324324
325 TargetJITInfo::StubLayout PPCJITInfo::getStubLayout() {
326 // The stub contains up to 10 4-byte instructions, aligned at 4 bytes: 3
327 // instructions to save the caller's address if this is a lazy-compilation
328 // stub, plus a 1-, 4-, or 7-instruction sequence to load an arbitrary address
329 // into a register and jump through it.
330 StubLayout Result = {10*4, 4};
331 return Result;
332 }
333
325334 #if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
326335 defined(__APPLE__)
327336 extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
334343 // call. The code is the same except for one bit of the last instruction.
335344 if (Fn != (void*)(intptr_t)PPC32CompilationCallback &&
336345 Fn != (void*)(intptr_t)PPC64CompilationCallback) {
337 JCE.startGVStub(BS, F, 7*4);
338 intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
339 JCE.emitWordBE(0);
340 JCE.emitWordBE(0);
341 JCE.emitWordBE(0);
342 JCE.emitWordBE(0);
343 JCE.emitWordBE(0);
344 JCE.emitWordBE(0);
345 JCE.emitWordBE(0);
346 EmitBranchToAt(Addr, (intptr_t)Fn, false, is64Bit);
347 sys::Memory::InvalidateInstructionCache((void*)Addr, 7*4);
348 return JCE.finishGVStub(BS);
349 }
350
351 JCE.startGVStub(BS, F, 10*4);
352 intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
346 void *Addr = (void*)JCE.getCurrentPCValue();
347 JCE.emitWordBE(0);
348 JCE.emitWordBE(0);
349 JCE.emitWordBE(0);
350 JCE.emitWordBE(0);
351 JCE.emitWordBE(0);
352 JCE.emitWordBE(0);
353 JCE.emitWordBE(0);
354 EmitBranchToAt((intptr_t)Addr, (intptr_t)Fn, false, is64Bit);
355 sys::Memory::InvalidateInstructionCache(Addr, 7*4);
356 return Addr;
357 }
358
359 void *Addr = (void*)JCE.getCurrentPCValue();
353360 if (is64Bit) {
354361 JCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1)
355362 JCE.emitWordBE(0x7d6802a6); // mflr r11
372379 JCE.emitWordBE(0);
373380 JCE.emitWordBE(0);
374381 EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit);
375 sys::Memory::InvalidateInstructionCache((void*)Addr, 10*4);
376 return JCE.finishGVStub(BS);
382 sys::Memory::InvalidateInstructionCache(Addr, 10*4);
383 return Addr;
377384 }
378385
379386
2929 is64Bit = tmIs64Bit;
3030 }
3131
32 virtual StubLayout getStubLayout();
3233 virtual void *emitFunctionStub(const Function* F, void *Fn,
3334 JITCodeEmitter &JCE);
3435 virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
437437 return JCE.finishGVStub(BS);
438438 }
439439
440 void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
440 TargetJITInfo::StubLayout X86JITInfo::getStubLayout() {
441 // The 64-bit stub contains:
442 // movabs r10 <- 8-byte-target-address # 10 bytes
443 // call|jmp *r10 # 3 bytes
444 // The 32-bit stub contains a 5-byte call|jmp.
445 // If the stub is a call to the compilation callback, an extra byte is added
446 // to mark it as a stub.
447 StubLayout Result = {14, 4};
448 return Result;
449 }
450
451 void *X86JITInfo::emitFunctionStub(const Function* F, void *Target,
441452 JITCodeEmitter &JCE) {
442453 MachineCodeEmitter::BufferState BS;
443454 // Note, we cast to intptr_t here to silence a -pedantic warning that
444455 // complains about casting a function pointer to a normal pointer.
445456 #if defined (X86_32_JIT) && !defined (_MSC_VER)
446 bool NotCC = (Fn != (void*)(intptr_t)X86CompilationCallback &&
447 Fn != (void*)(intptr_t)X86CompilationCallback_SSE);
448 #else
449 bool NotCC = Fn != (void*)(intptr_t)X86CompilationCallback;
450 #endif
457 bool NotCC = (Target != (void*)(intptr_t)X86CompilationCallback &&
458 Target != (void*)(intptr_t)X86CompilationCallback_SSE);
459 #else
460 bool NotCC = Target != (void*)(intptr_t)X86CompilationCallback;
461 #endif
462 JCE.emitAlignment(4);
463 void *Result = (void*)JCE.getCurrentPCValue();
451464 if (NotCC) {
452465 #if defined (X86_64_JIT)
453 JCE.startGVStub(BS, F, 13, 4);
454466 JCE.emitByte(0x49); // REX prefix
455467 JCE.emitByte(0xB8+2); // movabsq r10
456 JCE.emitWordLE((unsigned)(intptr_t)Fn);
457 JCE.emitWordLE((unsigned)(((intptr_t)Fn) >> 32));
468 JCE.emitWordLE((unsigned)(intptr_t)Target);
469 JCE.emitWordLE((unsigned)(((intptr_t)Target) >> 32));
458470 JCE.emitByte(0x41); // REX prefix
459471 JCE.emitByte(0xFF); // jmpq *r10
460472 JCE.emitByte(2 | (4 << 3) | (3 << 6));
461473 #else
462 JCE.startGVStub(BS, F, 5, 4);
463474 JCE.emitByte(0xE9);
464 JCE.emitWordLE((intptr_t)Fn-JCE.getCurrentPCValue()-4);
465 #endif
466 return JCE.finishGVStub(BS);
475 JCE.emitWordLE((intptr_t)Target-JCE.getCurrentPCValue()-4);
476 #endif
477 return Result;
467478 }
468479
469480 #if defined (X86_64_JIT)
470 JCE.startGVStub(BS, F, 14, 4);
471481 JCE.emitByte(0x49); // REX prefix
472482 JCE.emitByte(0xB8+2); // movabsq r10
473 JCE.emitWordLE((unsigned)(intptr_t)Fn);
474 JCE.emitWordLE((unsigned)(((intptr_t)Fn) >> 32));
483 JCE.emitWordLE((unsigned)(intptr_t)Target);
484 JCE.emitWordLE((unsigned)(((intptr_t)Target) >> 32));
475485 JCE.emitByte(0x41); // REX prefix
476486 JCE.emitByte(0xFF); // callq *r10
477487 JCE.emitByte(2 | (2 << 3) | (3 << 6));
478488 #else
479 JCE.startGVStub(BS, F, 6, 4);
480489 JCE.emitByte(0xE8); // Call with 32 bit pc-rel destination...
481490
482 JCE.emitWordLE((intptr_t)Fn-JCE.getCurrentPCValue()-4);
491 JCE.emitWordLE((intptr_t)Target-JCE.getCurrentPCValue()-4);
483492 #endif
484493
485494 // This used to use 0xCD, but that value is used by JITMemoryManager to
486495 // initialize the buffer with garbage, which means it may follow a
487496 // noreturn function call, confusing X86CompilationCallback2. PR 4929.
488497 JCE.emitByte(0xCE); // Interrupt - Just a marker identifying the stub!
489 return JCE.finishGVStub(BS);
490 }
491
492 void X86JITInfo::emitFunctionStubAtAddr(const Function* F, void *Fn, void *Stub,
493 JITCodeEmitter &JCE) {
494 MachineCodeEmitter::BufferState BS;
495 // Note, we cast to intptr_t here to silence a -pedantic warning that
496 // complains about casting a function pointer to a normal pointer.
497 JCE.startGVStub(BS, Stub, 5);
498 JCE.emitByte(0xE9);
499 #if defined (X86_64_JIT) && !defined (NDEBUG)
500 // Yes, we need both of these casts, or some broken versions of GCC (4.2.4)
501 // get the signed-ness of the expression wrong. Go figure.
502 intptr_t Displacement = (intptr_t)Fn - (intptr_t)JCE.getCurrentPCValue() - 5;
503 assert(((Displacement << 32) >> 32) == Displacement
504 && "PIC displacement does not fit in displacement field!");
505 #endif
506 JCE.emitWordLE((intptr_t)Fn-JCE.getCurrentPCValue()-4);
507 JCE.finishGVStub(BS);
498 return Result;
508499 }
509500
510501 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
4242 virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
4343 JITCodeEmitter &JCE);
4444
45 // getStubLayout - Returns the size and alignment of the largest call stub
46 // on X86.
47 virtual StubLayout getStubLayout();
48
4549 /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
4650 /// small native function that simply calls the function at the specified
4751 /// address.
48 virtual void *emitFunctionStub(const Function* F, void *Fn,
52 virtual void *emitFunctionStub(const Function* F, void *Target,
4953 JITCodeEmitter &JCE);
50
51 /// emitFunctionStubAtAddr - Use the specified JITCodeEmitter 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, JITCodeEmitter &JCE);
5654
5755 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
5856 /// specific basic block.
182182 M = new Module("
", Context);
183183 MP = new ExistingModuleProvider(M);
184184 RJMM = new RecordingJITMemoryManager;
185 RJMM->setPoisonMemory(true);
185186 std::string Error;
186187 TheJIT.reset(EngineBuilder(MP).setEngineKind(EngineKind::JIT)
187188 .setJITMemoryManager(RJMM)
310311 EXPECT_EQ(8, TestFunctionPtr());
311312 }
312313
313 #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__)
314314 // Test a function C which calls A and B which call each other.
315315 TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) {
316316 TheJIT->DisableLazyCompilation(true);
406406 EXPECT_EQ(Func2->getNumUses(), 0u);
407407 Func2->eraseFromParent();
408408 }
409 #endif
410409
411410 TEST_F(JITTest, ModuleDeletion) {
412411 TheJIT->DisableLazyCompilation(false);
457456 NumTablesDeallocated);
458457 }
459458
460 #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__)
461459 typedef int (*FooPtr) ();
462460
463461 TEST_F(JITTest, NoStubs) {
495493
496494 ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
497495 }
496
497 TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
498 TheJIT->DisableLazyCompilation(true);
499 LoadAssembly("define i8()* @get_foo_addr() { "
500 " ret i8()* @foo "
501 "} "
502 " "
503 "define i8 @foo() { "
504 " ret i8 42 "
505 "} ");
506 Function *F_get_foo_addr = M->getFunction("get_foo_addr");
507
508 typedef char(*fooT)();
509 fooT (*get_foo_addr)() = reinterpret_cast(
510 (intptr_t)TheJIT->getPointerToFunction(F_get_foo_addr));
511 fooT foo_addr = get_foo_addr();
512
513 // Now free get_foo_addr. This should not free the machine code for foo or
514 // any call stub returned as foo's canonical address.
515 TheJIT->freeMachineCodeForFunction(F_get_foo_addr);
516
517 // Check by calling the reported address of foo.
518 EXPECT_EQ(42, foo_addr());
519
520 // The reported address should also be the same as the result of a subsequent
521 // getPointerToFunction(foo).
522 #if 0
523 // Fails until PR5126 is fixed:
524 Function *F_foo = M->getFunction("foo");
525 fooT foo = reinterpret_cast(
526 (intptr_t)TheJIT->getPointerToFunction(F_foo));
527 EXPECT_EQ((intptr_t)foo, (intptr_t)foo_addr);
498528 #endif
529 }
499530
500531 // This code is copied from JITEventListenerTest, but it only runs once for all
501532 // the tests in this directory. Everything seems fine, but that's strange