1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- JITEmitter.cpp - Write machine code to executable memory ----------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines a MachineCodeEmitter object that is used by the JIT to 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// write machine code to memory and remember where relocatable values are. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define DEBUG_TYPE "jit" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "JIT.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "JITDebugRegisterer.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "JITDwarfEmitter.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/OwningPtr.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Constants.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Module.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/DerivedTypes.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Analysis/DebugInfo.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/JITCodeEmitter.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineCodeInfo.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineConstantPool.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineJumpTableInfo.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineModuleInfo.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineRelocation.h" 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ExecutionEngine/GenericValue.h" 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ExecutionEngine/JITEventListener.h" 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ExecutionEngine/JITMemoryManager.h" 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetData.h" 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetInstrInfo.h" 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetJITInfo.h" 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h" 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetOptions.h" 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ManagedStatic.h" 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MutexGuard.h" 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ValueHandle.h" 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Disassembler.h" 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Memory.h" 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/DenseMap.h" 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallPtrSet.h" 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallVector.h" 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/Statistic.h" 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/ValueMap.h" 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <algorithm> 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <iomanip> 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSTATISTIC(NumBytes, "Number of bytes of machine code compiled"); 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSTATISTIC(NumRelos, "Number of relocations applied"); 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSTATISTIC(NumRetries, "Number of retries with more memory"); 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// A declaration may stop being a declaration once it's fully read from bitcode. 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This function returns true if F is fully read and is still a declaration. 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bool isNonGhostDeclaration(const Function *F) { 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return F->isDeclaration() && !F->isMaterializable(); 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// JIT lazy compilation code. 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class JITEmitter; 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class JITResolverState; 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman template<typename ValueTy> 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman struct NoRAUWValueMapConfig : public ValueMapConfig<ValueTy> { 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef JITResolverState *ExtraData; 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void onRAUW(JITResolverState *, Value *Old, Value *New) { 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(false && "The JIT doesn't know how to handle a" 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " RAUW on a value it has emitted."); 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman struct CallSiteValueMapConfig : public NoRAUWValueMapConfig<Function*> { 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef JITResolverState *ExtraData; 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void onDelete(JITResolverState *JRS, Function *F); 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class JITResolverState { 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef ValueMap<Function*, void*, NoRAUWValueMapConfig<Function*> > 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToLazyStubMapTy; 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef std::map<void*, AssertingVH<Function> > CallSiteToFunctionMapTy; 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef ValueMap<Function *, SmallPtrSet<void*, 1>, 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallSiteValueMapConfig> FunctionToCallSitesMapTy; 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef std::map<AssertingVH<GlobalValue>, void*> GlobalToIndirectSymMapTy; 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private: 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// FunctionToLazyStubMap - Keep track of the lazy stub created for a 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// particular function so that we can reuse them if necessary. 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToLazyStubMapTy FunctionToLazyStubMap; 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// CallSiteToFunctionMap - Keep track of the function that each lazy call 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// site corresponds to, and vice versa. 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallSiteToFunctionMapTy CallSiteToFunctionMap; 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToCallSitesMapTy FunctionToCallSitesMap; 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// GlobalToIndirectSymMap - Keep track of the indirect symbol created for a 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// particular GlobalVariable so that we can reuse them if necessary. 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GlobalToIndirectSymMapTy GlobalToIndirectSymMap; 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Instance of the JIT this ResolverState serves. 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JIT *TheJIT; 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITResolverState(JIT *jit) : FunctionToLazyStubMap(this), 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToCallSitesMap(this), 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT(jit) {} 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToLazyStubMapTy& getFunctionToLazyStubMap( 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MutexGuard& locked) { 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(locked.holds(TheJIT->lock)); 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionToLazyStubMap; 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& lck) { 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(lck.holds(TheJIT->lock)); 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return GlobalToIndirectSymMap; 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<void *, Function *> LookupFunctionFromCallSite( 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MutexGuard &locked, void *CallSite) const { 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(locked.holds(TheJIT->lock)); 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The address given to us for the stub may not be exactly right, it 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // might be a little bit after the stub. As such, use upper_bound to 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // find it. 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallSiteToFunctionMapTy::const_iterator I = 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallSiteToFunctionMap.upper_bound(CallSite); 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I != CallSiteToFunctionMap.begin() && 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "This is not a known call site!"); 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *I; 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void AddCallSite(const MutexGuard &locked, void *CallSite, Function *F) { 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(locked.holds(TheJIT->lock)); 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool Inserted = CallSiteToFunctionMap.insert( 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::make_pair(CallSite, F)).second; 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (void)Inserted; 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Inserted && "Pair was already in CallSiteToFunctionMap"); 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToCallSitesMap[F].insert(CallSite); 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void EraseAllCallSitesForPrelocked(Function *F); 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Erases _all_ call sites regardless of their function. This is used to 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // unregister the stub addresses from the StubToResolverMap in 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ~JITResolver(). 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void EraseAllCallSitesPrelocked(); 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// JITResolver - Keep track of, and resolve, call sites for functions that 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// have not yet been compiled. 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class JITResolver { 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef JITResolverState::FunctionToLazyStubMapTy FunctionToLazyStubMapTy; 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef JITResolverState::CallSiteToFunctionMapTy CallSiteToFunctionMapTy; 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef JITResolverState::GlobalToIndirectSymMapTy GlobalToIndirectSymMapTy; 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// LazyResolverFn - The target lazy resolver function that we actually 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// rewrite instructions to use. 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetJITInfo::LazyResolverFn LazyResolverFn; 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITResolverState state; 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// for external functions. TODO: Of course, external functions don't need 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// a lazy stub. It's actually here to make it more likely that far calls 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// succeed, but no single stub can guarantee that. I'll remove this in a 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// subsequent checkin when I actually fix far calls. 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<void*, void*> ExternalFnToStubMap; 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// revGOTMap - map addresses to indexes in the GOT 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<void*, unsigned> revGOTMap; 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned nextGOTIndex; 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEmitter &JE; 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Instance of JIT corresponding to this Resolver. 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JIT *TheJIT; 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman explicit JITResolver(JIT &jit, JITEmitter &je) 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : state(&jit), nextGOTIndex(0), JE(je), TheJIT(&jit) { 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn); 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ~JITResolver(); 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getLazyFunctionStubIfAvailable - This returns a pointer to a function's 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// lazy-compilation stub if it has already been created. 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *getLazyFunctionStubIfAvailable(Function *F); 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getLazyFunctionStub - This returns a pointer to a function's 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// lazy-compilation stub, creating one on demand as needed. 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *getLazyFunctionStub(Function *F); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getExternalFunctionStub - Return a stub for the function at the 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// specified address, created lazily on demand. 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *getExternalFunctionStub(void *FnAddr); 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getGlobalValueIndirectSym - Return an indirect symbol containing the 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// specified GV address. 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *getGlobalValueIndirectSym(GlobalValue *V, void *GVAddress); 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getGOTIndexForAddress - Return a new or existing index in the GOT for 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// an address. This function only manages slots, it does not manage the 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// contents of the slots or the memory associated with the GOT. 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned getGOTIndexForAddr(void *addr); 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// JITCompilerFn - This function is called to resolve a stub to a compiled 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// address. If the LLVM Function corresponding to the stub has not yet 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// been compiled, this function compiles it first. 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void *JITCompilerFn(void *Stub); 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class StubToResolverMapTy { 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Map a stub address to a specific instance of a JITResolver so that 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// lazily-compiled functions can find the right resolver to use. 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Guarded by Lock. 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<void*, JITResolver*> Map; 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Guards Map from concurrent accesses. 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mutable sys::Mutex Lock; 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Registers a Stub to be resolved by Resolver. 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void RegisterStubResolver(void *Stub, JITResolver *Resolver) { 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard guard(Lock); 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Map.insert(std::make_pair(Stub, Resolver)); 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Unregisters the Stub when it's invalidated. 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void UnregisterStubResolver(void *Stub) { 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard guard(Lock); 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Map.erase(Stub); 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Returns the JITResolver instance that owns the Stub. 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITResolver *getResolverFromStub(void *Stub) const { 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard guard(Lock); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The address given to us for the stub may not be exactly right, it might 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // be a little bit after the stub. As such, use upper_bound to find it. 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This is the same trick as in LookupFunctionFromCallSite from 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // JITResolverState. 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<void*, JITResolver*>::const_iterator I = Map.upper_bound(Stub); 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I != Map.begin() && "This is not a known stub!"); 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return I->second; 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// True if any stubs refer to the given resolver. Only used in an assert(). 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// O(N) 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool ResolverHasStubs(JITResolver* Resolver) const { 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard guard(Lock); 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (std::map<void*, JITResolver*>::const_iterator I = Map.begin(), 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = Map.end(); I != E; ++I) { 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I->second == Resolver) 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// This needs to be static so that a lazy call stub can access it with no 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// context except the address of the stub. 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ManagedStatic<StubToResolverMapTy> StubToResolverMap; 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// used to output functions to memory for execution. 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class JITEmitter : public JITCodeEmitter { 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITMemoryManager *MemMgr; 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // When outputting a function stub in the context of some other function, we 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // save BufferBegin/BufferEnd/CurBufferPtr here. 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // When reattempting to JIT a function after running out of space, we store 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the estimated size of the function we're trying to JIT here, so we can 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ask the memory manager for at least this much space. When we 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // successfully emit the function, we reset this back to zero. 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uintptr_t SizeEstimate; 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Relocations - These are the relocations that the function needs, as 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// emitted. 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<MachineRelocation> Relocations; 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// MBBLocations - This vector is a mapping from MBB ID's to their address. 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// It is filled in by the StartMachineBasicBlock callback and queried by 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// the getMachineBasicBlockAddress callback. 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<uintptr_t> MBBLocations; 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// ConstantPool - The constant pool for the current function. 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineConstantPool *ConstantPool; 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// ConstantPoolBase - A pointer to the first entry in the constant pool. 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *ConstantPoolBase; 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// ConstPoolAddresses - Addresses of individual constant pool entries. 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<uintptr_t, 8> ConstPoolAddresses; 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// JumpTable - The jump tables for the current function. 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineJumpTableInfo *JumpTable; 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// JumpTableBase - A pointer to the first entry in the jump table. 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *JumpTableBase; 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Resolver - This contains info about the currently resolved functions. 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITResolver Resolver; 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /// DE - The dwarf emitter for the jit. 32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OwningPtr<JITDwarfEmitter> DE; 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /// DR - The debug registerer for the jit. 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OwningPtr<JITDebugRegisterer> DR; 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// LabelLocations - This vector is a mapping from Label ID's to their 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// address. 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DenseMap<MCSymbol*, uintptr_t> LabelLocations; 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// MMI - Machine module info for exception informations 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineModuleInfo* MMI; 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CurFn - The llvm function being emitted. Only valid during 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // finishFunction(). 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Function *CurFn; 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Information about emitted code, which is passed to the 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// JITEventListeners. This is reset in startFunction and used in 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// finishFunction. 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEvent_EmittedFunctionDetails EmissionDetails; 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman struct EmittedCode { 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *FunctionBody; // Beginning of the function's allocation. 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *Code; // The address the function's code actually starts at. 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *ExceptionTable; 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmittedCode() : FunctionBody(0), Code(0), ExceptionTable(0) {} 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman struct EmittedFunctionConfig : public ValueMapConfig<const Function*> { 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef JITEmitter *ExtraData; 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void onDelete(JITEmitter *, const Function*); 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void onRAUW(JITEmitter *, const Function*, const Function*); 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ValueMap<const Function *, EmittedCode, 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmittedFunctionConfig> EmittedFunctions; 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc PrevDL; 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Instance of the JIT 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JIT *TheJIT; 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0), 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmittedFunctions(this), TheJIT(&jit) { 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (jit.getJITInfo().needsGOT()) { 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->AllocateGOT(); 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT is managing a GOT\n"); 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (JITExceptionHandling || JITEmitDebugInfo) { 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DE.reset(new JITDwarfEmitter(jit)); 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (JITEmitDebugInfo) { 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DR.reset(new JITDebugRegisterer(TM)); 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ~JITEmitter() { 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete MemMgr; 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// classof - Methods for support type inquiry through isa, cast, and 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// dyn_cast: 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static inline bool classof(const MachineCodeEmitter*) { return true; } 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITResolver &getJITResolver() { return Resolver; } 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void startFunction(MachineFunction &F); 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual bool finishFunction(MachineFunction &F); 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emitConstantPool(MachineConstantPool *MCP); 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void initJumpTableInfo(MachineJumpTableInfo *MJTI); 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emitJumpTableInfo(MachineJumpTableInfo *MJTI); 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void startGVStub(const GlobalValue* GV, 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StubSize, unsigned Alignment = 1); 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void startGVStub(void *Buffer, unsigned StubSize); 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void finishGVStub(); 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void *allocIndirectGV(const GlobalValue *GV, 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const uint8_t *Buffer, size_t Size, 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment); 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// allocateSpace - Reserves space in the current block if any, or 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// allocate a new one of the given size. 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace, 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// this method does not allocate memory in the current output buffer, 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// because a global may live longer than the current function. 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment); 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void addRelocation(const MachineRelocation &MR) { 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Relocations.push_back(MR); 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MBBLocations.size() <= (unsigned)MBB->getNumber()) 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MBBLocations.resize((MBB->getNumber()+1)*2); 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MBBLocations[MBB->getNumber()] = getCurrentPCValue(); 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MBB->hasAddressTaken()) 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->addPointerToBasicBlock(MBB->getBasicBlock(), 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (void*)getCurrentPCValue()); 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Emitting BB" << MBB->getNumber() << " at [" 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << (void*) getCurrentPCValue() << "]\n"); 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const{ 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MBBLocations[MBB->getNumber()] && "MBB not emitted!"); 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MBBLocations[MBB->getNumber()]; 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// retryWithMoreMemory - Log a retry and deallocate all memory for the 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// given function. Increase the minimum allocation size so that we get 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// more memory next time. 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void retryWithMoreMemory(MachineFunction &F); 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// deallocateMemForFunction - Deallocate all memory for the specified 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// function body. 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void deallocateMemForFunction(const Function *F); 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void processDebugLoc(DebugLoc DL, bool BeforePrintingInsn); 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void emitLabel(MCSymbol *Label) { 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LabelLocations[Label] = getCurrentPCValue(); 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return &LabelLocations; 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual uintptr_t getLabelAddress(MCSymbol *Label) const { 461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LabelLocations.count(Label) && "Label not emitted!"); 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LabelLocations.find(Label)->second; 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void setModuleInfo(MachineModuleInfo* Info) { 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MMI = Info; 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (DE.get()) DE->setModuleInfo(Info); 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private: 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *getPointerToGlobal(GlobalValue *GV, void *Reference, 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool MayNeedFarStub); 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference); 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid CallSiteValueMapConfig::onDelete(JITResolverState *JRS, Function *F) { 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JRS->EraseAllCallSitesForPrelocked(F); 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITResolverState::EraseAllCallSitesForPrelocked(Function *F) { 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToCallSitesMapTy::iterator F2C = FunctionToCallSitesMap.find(F); 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (F2C == FunctionToCallSitesMap.end()) 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StubToResolverMapTy &S2RMap = *StubToResolverMap; 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (SmallPtrSet<void*, 1>::const_iterator I = F2C->second.begin(), 487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = F2C->second.end(); I != E; ++I) { 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman S2RMap.UnregisterStubResolver(*I); 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool Erased = CallSiteToFunctionMap.erase(*I); 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (void)Erased; 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Erased && "Missing call site->function mapping"); 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToCallSitesMap.erase(F2C); 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITResolverState::EraseAllCallSitesPrelocked() { 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StubToResolverMapTy &S2RMap = *StubToResolverMap; 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (CallSiteToFunctionMapTy::const_iterator 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = CallSiteToFunctionMap.begin(), 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = CallSiteToFunctionMap.end(); I != E; ++I) { 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman S2RMap.UnregisterStubResolver(I->first); 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CallSiteToFunctionMap.clear(); 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionToCallSitesMap.clear(); 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanJITResolver::~JITResolver() { 508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // No need to lock because we're in the destructor, and state isn't shared. 509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman state.EraseAllCallSitesPrelocked(); 510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!StubToResolverMap->ResolverHasStubs(this) && 511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Resolver destroyed with stubs still alive."); 512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getLazyFunctionStubIfAvailable - This returns a pointer to a function stub 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// if it has already been created. 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITResolver::getLazyFunctionStubIfAvailable(Function *F) { 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard locked(TheJIT->lock); 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we already have a stub for this function, recycle it. 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return state.getFunctionToLazyStubMap(locked).lookup(F); 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getFunctionStub - This returns a pointer to a function stub, creating 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// one on demand as needed. 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITResolver::getLazyFunctionStub(Function *F) { 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard locked(TheJIT->lock); 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we already have a lazy stub for this function, recycle it. 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *&Stub = state.getFunctionToLazyStubMap(locked)[F]; 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Stub) return Stub; 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Call the lazy resolver function if we are JIT'ing lazily. Otherwise we 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // must resolve the symbol now. 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *Actual = TheJIT->isCompilingLazily() 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? (void *)(intptr_t)LazyResolverFn : (void *)0; 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is an external declaration, attempt to resolve the address now 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to place in the stub. 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isNonGhostDeclaration(F) || F->hasAvailableExternallyLinkage()) { 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Actual = TheJIT->getPointerToFunction(F); 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we resolved the symbol to a null address (eg. a weak external) 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // don't emit a stub. Return a null pointer to the application. 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Actual) return 0; 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout(); 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE.startGVStub(F, SL.Size, SL.Alignment); 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Codegen a new stub, calling the lazy resolver or the actual address of the 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // external function, if it was resolved. 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE); 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE.finishGVStub(); 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Actual != (void*)(intptr_t)LazyResolverFn) { 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we are getting the stub for an external function, we really want the 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // address of the stub in the GlobalAddressMap for the JIT, not the address 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // of the external function. 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->updateGlobalMapping(F, Stub); 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Lazy stub emitted at [" << Stub << "] for function '" 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << F->getName() << "'\n"); 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheJIT->isCompilingLazily()) { 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Register this JITResolver as the one corresponding to this call site so 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // JITCompilerFn will be able to find it. 567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StubToResolverMap->RegisterStubResolver(Stub, this); 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Finally, keep track of the stub-to-Function mapping so that the 570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // JITCompilerFn knows which function to compile! 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman state.AddCallSite(locked, Stub, F); 572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (!Actual) { 573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we are JIT'ing non-lazily but need to call a function that does not 574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // exist yet, add it to the JIT's work list so that we can fill in the 575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // stub address later. 576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!isNonGhostDeclaration(F) && !F->hasAvailableExternallyLinkage() && 577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "'Actual' should have been set above."); 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->addPendingFunction(F); 579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Stub; 582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getGlobalValueIndirectSym - Return a lazy pointer containing the specified 585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// GV address. 586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) { 587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard locked(TheJIT->lock); 588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we already have a stub for this global variable, recycle it. 590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV]; 591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (IndirectSym) return IndirectSym; 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, codegen a new indirect symbol. 594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress, 595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE); 596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Indirect symbol emitted at [" << IndirectSym 598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "] for GV '" << GV->getName() << "'\n"); 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return IndirectSym; 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getExternalFunctionStub - Return a stub for the function at the 604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// specified address, created lazily on demand. 605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITResolver::getExternalFunctionStub(void *FnAddr) { 606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we already have a stub for this function, recycle it. 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *&Stub = ExternalFnToStubMap[FnAddr]; 608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Stub) return Stub; 609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout(); 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE.startGVStub(0, SL.Size, SL.Alignment); 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE); 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE.finishGVStub(); 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Stub emitted at [" << Stub 616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "] for external function at '" << FnAddr << "'\n"); 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Stub; 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned JITResolver::getGOTIndexForAddr(void* addr) { 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned idx = revGOTMap[addr]; 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!idx) { 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman idx = ++nextGOTIndex; 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman revGOTMap[addr] = idx; 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Adding GOT entry " << idx << " for addr [" 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << addr << "]\n"); 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return idx; 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// JITCompilerFn - This function is called when a lazy compilation stub has 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// been entered. It looks up which function this stub corresponds to, compiles 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// it if necessary, then returns the resultant function pointer. 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITResolver::JITCompilerFn(void *Stub) { 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITResolver *JR = StubToResolverMap->getResolverFromStub(Stub); 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(JR && "Unable to find the corresponding JITResolver to the call site"); 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Function* F = 0; 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void* ActualPtr = 0; 640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Only lock for getting the Function. The call getPointerToFunction made 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // in this function might trigger function materializing, which requires 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // JIT lock to be unlocked. 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard locked(JR->TheJIT->lock); 646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The address given to us for the stub may not be exactly right, it might 648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // be a little bit after the stub. As such, use upper_bound to find it. 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<void*, Function*> I = 650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JR->state.LookupFunctionFromCallSite(locked, Stub); 651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman F = I.second; 652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ActualPtr = I.first; 653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have already code generated the function, just return the address. 656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *Result = JR->TheJIT->getPointerToGlobalIfAvailable(F); 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Result) { 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise we don't have it, do lazy compilation now. 660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If lazy compilation is disabled, emit a useful error message and abort. 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!JR->TheJIT->isCompilingLazily()) { 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("LLVM JIT requested to do lazy compilation of" 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman " function '" 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman + F->getName() + "' when lazy compiles are disabled!"); 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Lazily resolving function '" << F->getName() 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "' In stub ptr = " << Stub << " actual ptr = " 670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << ActualPtr << "\n"); 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (void)ActualPtr; 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = JR->TheJIT->getPointerToFunction(F); 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Reacquire the lock to update the GOT map. 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MutexGuard locked(JR->TheJIT->lock); 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We might like to remove the call site from the CallSiteToFunction map, but 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // we can't do that! Multiple threads could be stuck, waiting to acquire the 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lock above. As soon as the 1st function finishes compiling the function, 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the next one will be released, and needs to be able to find the function it 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // needs to call. 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: We could rewrite all references to this stub if we knew them. 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // What we will do is set the compiled function address to map to the 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // same GOT entry as the stub so that later clients may update the GOT 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // if they see it still using the stub address. 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Note: this is done so the Resolver doesn't have to manage GOT memory 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do this without allocating map space if the target isn't using a GOT 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(JR->revGOTMap.find(Stub) != JR->revGOTMap.end()) 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JR->revGOTMap[Result] = JR->revGOTMap[Stub]; 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// JITEmitter code. 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference, 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool MayNeedFarStub) { 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TheJIT->getOrEmitGlobalVariable(GV); 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false)); 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have already compiled the function, return a pointer to its body. 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Function *F = cast<Function>(V); 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *FnStub = Resolver.getLazyFunctionStubIfAvailable(F); 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FnStub) { 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Return the function stub if it's already created. We do this first so 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // that we're returning the same address for the function as any previous 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // call. TODO: Yes, this is wrong. The lazy stub isn't guaranteed to be 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // close enough to call. 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FnStub; 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we know the target can handle arbitrary-distance calls, try to 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // return a direct pointer. 723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MayNeedFarStub) { 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have code, go ahead and return that. 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F); 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ResultPtr) return ResultPtr; 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is an external function pointer, we can force the JIT to 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 'compile' it, which really just adds it to the map. 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isNonGhostDeclaration(F) || F->hasAvailableExternallyLinkage()) 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TheJIT->getPointerToFunction(F); 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, we may need a to emit a stub, and, conservatively, we always do 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // so. Note that it's possible to return null from getLazyFunctionStub in the 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // case of a weak extern that fails to resolve. 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Resolver.getLazyFunctionStub(F); 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITEmitter::getPointerToGVIndirectSym(GlobalValue *V, void *Reference) { 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure GV is emitted first, and create a stub containing the fully 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // resolved address. 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *GVAddress = getPointerToGlobal(V, Reference, false); 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *StubAddr = Resolver.getGlobalValueIndirectSym(V, GVAddress); 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return StubAddr; 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) { 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DL.isUnknown()) return; 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!BeforePrintingInsn) return; 75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const LLVMContext &Context = EmissionDetails.MF->getFunction()->getContext(); 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DL.getScope(Context) != 0 && PrevDL != DL) { 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEvent_EmittedFunctionDetails::LineStart NextLine; 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NextLine.Address = getCurrentPCValue(); 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NextLine.Loc = DL; 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmissionDetails.LineStarts.push_back(NextLine); 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PrevDL = DL; 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, 765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetData *TD) { 766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Constants.empty()) return 0; 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Size = 0; 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineConstantPoolEntry CPE = Constants[i]; 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned AlignMask = CPE.getAlignment() - 1; 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Size = (Size + AlignMask) & ~AlignMask; 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty = CPE.getType(); 775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Size += TD->getTypeAllocSize(Ty); 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Size; 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::startFunction(MachineFunction &F) { 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Starting CodeGen of Function " 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << F.getFunction()->getName() << "\n"); 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uintptr_t ActualSize = 0; 785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set the memory writable, if it's not already 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->setMemoryWritable(); 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SizeEstimate > 0) { 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SizeEstimate will be non-zero on reallocation attempts. 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ActualSize = SizeEstimate; 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ActualSize); 795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferEnd = BufferBegin+ActualSize; 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmittedFunctions[F.getFunction()].FunctionBody = BufferBegin; 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ensure the constant pool/jump table info is at least 4-byte aligned. 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitAlignment(16); 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitConstantPool(F.getConstantPool()); 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo()) 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman initJumpTableInfo(MJTI); 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // About to start emitting the machine code for the function. 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmittedFunctions[F.getFunction()].Code = CurBufferPtr; 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MBBLocations.clear(); 811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmissionDetails.MF = &F; 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmissionDetails.LineStarts.clear(); 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool JITEmitter::finishFunction(MachineFunction &F) { 817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CurBufferPtr == BufferEnd) { 818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We must call endFunctionBody before retrying, because 819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // deallocateMemForFunction requires it. 820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); 821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman retryWithMoreMemory(F); 822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo()) 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitJumpTableInfo(MJTI); 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FnStart is the start of the text, not the start of the constant pool and 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // other per-function data. 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t *FnStart = 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FnEnd is the end of the function's machine code. 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t *FnEnd = CurBufferPtr; 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Relocations.empty()) { 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurFn = F.getFunction(); 838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumRelos += Relocations.size(); 839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Resolve the relocations to concrete pointers. 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { 842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineRelocation &MR = Relocations[i]; 843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *ResultPtr = 0; 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MR.letTargetResolve()) { 845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MR.isExternalSymbol()) { 846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(), 847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false); 848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Map \'" << MR.getExternalSymbol() << "\' to [" 849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << ResultPtr << "]\n"); 850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the target REALLY wants a stub for this function, emit it now. 852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MR.mayNeedFarStub()) { 853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); 854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (MR.isGlobalValue()) { 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultPtr = getPointerToGlobal(MR.getGlobalValue(), 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin+MR.getMachineCodeOffset(), 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MR.mayNeedFarStub()); 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (MR.isIndirectSymbol()) { 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultPtr = getPointerToGVIndirectSym( 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MR.getGlobalValue(), BufferBegin+MR.getMachineCodeOffset()); 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (MR.isBasicBlock()) { 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock()); 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (MR.isConstantPoolIndex()) { 86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ResultPtr = 86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(MR.isJumpTableIndex()); 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultPtr=(void*)getJumpTableEntryAddress(MR.getJumpTableIndex()); 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MR.setResultPointer(ResultPtr); 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // if we are managing the GOT and the relocation wants an index, 876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // give it one 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MR.setGOTIndex(idx); 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: GOT was out of date for " << ResultPtr 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "\n"); 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; 885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurFn = 0; 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Relocations.size(), MemMgr->getGOTBase()); 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update the GOT entry for F to point to the new code. 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MemMgr->isManagingGOT()) { 896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { 898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: GOT was out of date for " << (void*)BufferBegin 899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "\n"); 901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for 906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // global variables that were referenced in the relocations. 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CurBufferPtr == BufferEnd) { 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman retryWithMoreMemory(F); 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Now that we've succeeded in emitting the function, reset the 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SizeEstimate back down to zero. 915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SizeEstimate = 0; 916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin = CurBufferPtr = 0; 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumBytes += FnEnd-FnStart; 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Invalidate the icache if necessary. 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart); 923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->NotifyFunctionEmitted(*F.getFunction(), FnStart, FnEnd-FnStart, 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmissionDetails); 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Reset the previous debug location. 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PrevDL = DebugLoc(); 929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Finished CodeGen of [" << (void*)FnStart 931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "] Function: " << F.getFunction()->getName() 932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << ": " << (FnEnd-FnStart) << " bytes of text, " 933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << Relocations.size() << " relocations\n"); 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Relocations.clear(); 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstPoolAddresses.clear(); 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Mark code region readable and executable if it's not so already. 939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->setMemoryExecutable(); 940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG({ 942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (sys::hasDisassembler()) { 943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "JIT: Disassembled code:\n"; 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << sys::disassembleBuffer(FnStart, FnEnd-FnStart, 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (uintptr_t)FnStart); 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "JIT: Binary code:\n"; 948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t* q = FnStart; 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0; q < FnEnd; q += 4, ++i) { 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i == 4) 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman i = 0; 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i == 0) 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "JIT: " << (long)(q - FnStart) << ": "; 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool Done = false; 955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int j = 3; j >= 0; --j) { 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (q + j >= FnEnd) 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Done = true; 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << (unsigned short)q[j]; 960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Done) 962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << ' '; 964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i == 3) 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << '\n'; 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs()<< '\n'; 968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }); 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (JITExceptionHandling || JITEmitDebugInfo) { 97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uintptr_t ActualSize = 0; 97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SavedBufferBegin = BufferBegin; 97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SavedBufferEnd = BufferEnd; 97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SavedCurBufferPtr = CurBufferPtr; 97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ActualSize); 97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BufferEnd = BufferBegin+ActualSize; 98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin; 98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint8_t *EhStart; 98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, 98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EhStart); 98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameRegister); 98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint8_t *EhEnd = CurBufferPtr; 98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BufferBegin = SavedBufferBegin; 98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BufferEnd = SavedBufferEnd; 98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CurBufferPtr = SavedCurBufferPtr; 99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (JITExceptionHandling) { 99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TheJIT->RegisterTable(F.getFunction(), FrameRegister); 99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (JITEmitDebugInfo) { 99619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugInfo I; 99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I.FnStart = FnStart; 99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I.FnEnd = FnEnd; 99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I.EhStart = EhStart; 100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I.EhEnd = EhEnd; 100119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DR->RegisterFunction(F.getFunction(), I); 100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 100319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 100419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MMI) 1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MMI->EndFunction(); 1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::retryWithMoreMemory(MachineFunction &F) { 1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Ran out of space for native code. Reattempting.\n"); 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Relocations.clear(); // Clear the old relocations or we'll reapply them. 1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstPoolAddresses.clear(); 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++NumRetries; 1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman deallocateMemForFunction(F.getFunction()); 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Try again with at least twice as much free space. 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin)); 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineFunction::iterator MBB = F.begin(), E = F.end(); MBB != E; ++MBB){ 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MBB->hasAddressTaken()) 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->clearPointerToBasicBlock(MBB->getBasicBlock()); 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// deallocateMemForFunction - Deallocate all memory for the specified 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// function body. Also drop any references the function has to stubs. 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// May be called while the Function is being destroyed inside ~Value(). 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::deallocateMemForFunction(const Function *F) { 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ValueMap<const Function *, EmittedCode, EmittedFunctionConfig>::iterator 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Emitted = EmittedFunctions.find(F); 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Emitted != EmittedFunctions.end()) { 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->deallocateFunctionBody(Emitted->second.FunctionBody); 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemMgr->deallocateExceptionTable(Emitted->second.ExceptionTable); 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->NotifyFreeingMachineCode(Emitted->second.Code); 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EmittedFunctions.erase(Emitted); 1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 104019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(JITExceptionHandling) { 104119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TheJIT->DeregisterTable(F); 104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 104319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (JITEmitDebugInfo) { 104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DR->UnregisterFunction(F); 104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid* JITEmitter::allocateSpace(uintptr_t Size, unsigned Alignment) { 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BufferBegin) 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return JITCodeEmitter::allocateSpace(Size, Alignment); 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // create a new memory block if there is no active one. 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // care must be taken so that BufferBegin is invalidated when a 1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // block is trimmed 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment); 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferEnd = BufferBegin+Size; 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurBufferPtr; 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid* JITEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) { 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Delegate this call through the memory manager. 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MemMgr->allocateGlobal(Size, Alignment); 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::emitConstantPool(MachineConstantPool *MCP) { 1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheJIT->getJITInfo().hasCustomConstantPool()) 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Constants.empty()) return; 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); 1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = MCP->getConstantPoolAlignment(); 1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantPoolBase = allocateSpace(Size, Align); 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantPool = MCP; 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantPoolBase == 0) return; // Buffer overflow. 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: Emitted constant pool at [" << ConstantPoolBase 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "] (size: " << Size << ", alignment: " << Align << ")\n"); 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Initialize the memory for all of the constant pool entries. 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Offset = 0; 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineConstantPoolEntry CPE = Constants[i]; 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned AlignMask = CPE.getAlignment() - 1; 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = (Offset + AlignMask) & ~AlignMask; 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstPoolAddresses.push_back(CAddr); 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CPE.isMachineConstantPoolEntry()) { 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: add support to lower machine constant pool values into bytes! 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman report_fatal_error("Initialize memory with machine specific constant pool" 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "entry has not been implemented!"); 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "JIT: CP" << i << " at [0x"; 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs().write_hex(CAddr) << "]\n"); 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty = CPE.Val.ConstVal->getType(); 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheJIT->getJITInfo().hasCustomJumpTables()) 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (JT.empty()) return; 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumEntries = 0; 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = JT.size(); i != e; ++i) 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumEntries += JT[i].MBBs.size(); 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EntrySize = MJTI->getEntrySize(*TheJIT->getTargetData()); 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Just allocate space for all the jump tables now. We will fix up the actual 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // MBB entries in the tables after we emit the code for each block, since then 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // we will know the final locations of the MBBs in memory. 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JumpTable = MJTI; 1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JumpTableBase = allocateSpace(NumEntries * EntrySize, 1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MJTI->getEntryAlignment(*TheJIT->getTargetData())); 1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { 1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheJIT->getJITInfo().hasCustomJumpTables()) 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (JT.empty() || JumpTableBase == 0) return; 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (MJTI->getEntryKind()) { 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MachineJumpTableInfo::EK_Inline: 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MachineJumpTableInfo::EK_BlockAddress: { 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // EK_BlockAddress - Each entry is a plain address of block, e.g.: 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // .word LBB123 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == sizeof(void*) && 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Cross JIT'ing?"); 114619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For each jump table, map each target in the jump table to the address of 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // an emitted MachineBasicBlock. 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman intptr_t *SlotPtr = (intptr_t*)JumpTableBase; 115019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = JT.size(); i != e; ++i) { 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the address of the basic block for this jump table slot in the 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // memory we allocated for the jump table in 'initJumpTableInfo' 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) 1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); 1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MachineJumpTableInfo::EK_Custom32: 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MachineJumpTableInfo::EK_GPRel32BlockAddress: 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MachineJumpTableInfo::EK_LabelDifference32: { 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == 4&&"Cross JIT'ing?"); 1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For each jump table, place the offset from the beginning of the table 1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to the target address. 1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int *SlotPtr = (int*)JumpTableBase; 1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = JT.size(); i != e; ++i) { 1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the offset of the basic block for this jump table slot in the 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // memory we allocated for the jump table in 'initJumpTableInfo' 1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uintptr_t Base = (uintptr_t)SlotPtr; 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uintptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]); 1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// FIXME: USe EntryKind instead of magic "getPICJumpTableEntry" hook. 1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base); 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::startGVStub(const GlobalValue* GV, 1186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StubSize, unsigned Alignment) { 1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SavedBufferBegin = BufferBegin; 1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SavedBufferEnd = BufferEnd; 1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SavedCurBufferPtr = CurBufferPtr; 1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment); 1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferEnd = BufferBegin+StubSize+1; 1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::startGVStub(void *Buffer, unsigned StubSize) { 1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SavedBufferBegin = BufferBegin; 1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SavedBufferEnd = BufferEnd; 1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SavedCurBufferPtr = CurBufferPtr; 1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin = CurBufferPtr = (uint8_t *)Buffer; 1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferEnd = BufferBegin+StubSize+1; 1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::finishGVStub() { 1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space."); 1206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumBytes += getCurrentPCOffset(); 1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferBegin = SavedBufferBegin; 1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferEnd = SavedBufferEnd; 1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurBufferPtr = SavedCurBufferPtr; 1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JITEmitter::allocIndirectGV(const GlobalValue *GV, 1213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const uint8_t *Buffer, size_t Size, 1214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment) { 1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t *IndGV = MemMgr->allocateStub(GV, Size, Alignment); 1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman memcpy(IndGV, Buffer, Size); 1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return IndGV; 1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry 1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// in the constant pool that was last emitted with the 'emitConstantPool' 1222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// method. 1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuintptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { 1225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ConstantNum < ConstantPool->getConstants().size() && 1226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Invalid ConstantPoolIndex!"); 1227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ConstPoolAddresses[ConstantNum]; 1228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// getJumpTableEntryAddress - Return the address of the JumpTable with index 1231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo' 1232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 1233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { 1234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables(); 1235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Index < JT.size() && "Invalid jump table index!"); 1236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EntrySize = JumpTable->getEntrySize(*TheJIT->getTargetData()); 1238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Offset = 0; 1240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < Index; ++i) 1241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += JT[i].MBBs.size(); 1242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset *= EntrySize; 1244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (uintptr_t)((char *)JumpTableBase + Offset); 1246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::EmittedFunctionConfig::onDelete( 1249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEmitter *Emitter, const Function *F) { 1250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Emitter->deallocateMemForFunction(F); 1251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JITEmitter::EmittedFunctionConfig::onRAUW( 1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEmitter *, const Function*, const Function*) { 1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("The JIT doesn't know how to handle a" 1255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " RAUW on a value it has emitted."); 1256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Public interface to this file 1261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanJITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM, 1264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetMachine &tm) { 1265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return new JITEmitter(jit, JMM, tm); 1266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// getPointerToFunctionOrStub - If the specified function has been 1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// code-gen'd, return a pointer to the function. If not, compile it, or use 1270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// a stub to implement lazy compilation if available. 1271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 1272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid *JIT::getPointerToFunctionOrStub(Function *F) { 1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have already code generated the function, just return the address. 1274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (void *Addr = getPointerToGlobalIfAvailable(F)) 1275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Addr; 1276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get a stub if the target supports it. 1278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEmitter *JE = cast<JITEmitter>(getCodeEmitter()); 1280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return JE->getJITResolver().getLazyFunctionStub(F); 1281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JIT::updateFunctionStub(Function *F) { 1284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the empty stub we generated earlier. 1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JITEmitter *JE = cast<JITEmitter>(getCodeEmitter()); 1287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *Stub = JE->getJITResolver().getLazyFunctionStub(F); 1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void *Addr = getPointerToGlobalIfAvailable(F); 1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Addr != Stub && "Function must have non-stub address to be updated."); 1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Tell the target jit info to rewrite the stub at the specified address, 1292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // rather than creating a new one. 1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout(); 1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE->startGVStub(Stub, layout.Size); 1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter()); 1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JE->finishGVStub(); 1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// freeMachineCodeForFunction - release machine code memory for given Function. 1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid JIT::freeMachineCodeForFunction(Function *F) { 1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Delete translation for this from the ExecutionEngine, so it will get 1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // retranslated next time it is used. 1304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman updateGlobalMapping(F, 0); 1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Free the actual memory for the function body and related stuff. 1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cast<JITEmitter>(JCE)->deallocateMemForFunction(F); 1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1310