| LEFT | RIGHT |
| 1 //===-- JITEmitter.cpp - Write machine code to executable memory ----------===// | 1 //===-- JITEmitter.cpp - Write machine code to executable memory ----------===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file defines a MachineCodeEmitter object that is used by the JIT to | 10 // This file defines a MachineCodeEmitter object that is used by the JIT to |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "llvm/CodeGen/MachineRelocation.h" | 28 #include "llvm/CodeGen/MachineRelocation.h" |
| 29 #include "llvm/ExecutionEngine/GenericValue.h" | 29 #include "llvm/ExecutionEngine/GenericValue.h" |
| 30 #include "llvm/ExecutionEngine/JITEventListener.h" | 30 #include "llvm/ExecutionEngine/JITEventListener.h" |
| 31 #include "llvm/ExecutionEngine/JITMemoryManager.h" | 31 #include "llvm/ExecutionEngine/JITMemoryManager.h" |
| 32 #include "llvm/CodeGen/MachineCodeInfo.h" | 32 #include "llvm/CodeGen/MachineCodeInfo.h" |
| 33 #include "llvm/Target/TargetData.h" | 33 #include "llvm/Target/TargetData.h" |
| 34 #include "llvm/Target/TargetJITInfo.h" | 34 #include "llvm/Target/TargetJITInfo.h" |
| 35 #include "llvm/Target/TargetMachine.h" | 35 #include "llvm/Target/TargetMachine.h" |
| 36 #include "llvm/Target/TargetOptions.h" | 36 #include "llvm/Target/TargetOptions.h" |
| 37 #include "llvm/Support/Debug.h" | 37 #include "llvm/Support/Debug.h" |
| 38 #include "llvm/Support/ErrorHandling.h" |
| 38 #include "llvm/Support/MutexGuard.h" | 39 #include "llvm/Support/MutexGuard.h" |
| 39 #include "llvm/Support/ValueHandle.h" | 40 #include "llvm/Support/ValueHandle.h" |
| 41 #include "llvm/Support/raw_ostream.h" |
| 40 #include "llvm/System/Disassembler.h" | 42 #include "llvm/System/Disassembler.h" |
| 41 #include "llvm/System/Memory.h" | 43 #include "llvm/System/Memory.h" |
| 42 #include "llvm/Target/TargetInstrInfo.h" | 44 #include "llvm/Target/TargetInstrInfo.h" |
| 43 #include "llvm/ADT/SmallPtrSet.h" | 45 #include "llvm/ADT/SmallPtrSet.h" |
| 44 #include "llvm/ADT/SmallVector.h" | 46 #include "llvm/ADT/SmallVector.h" |
| 45 #include "llvm/ADT/Statistic.h" | 47 #include "llvm/ADT/Statistic.h" |
| 46 #include <algorithm> | 48 #include <algorithm> |
| 47 #ifndef NDEBUG | 49 #ifndef NDEBUG |
| 48 #include <iomanip> | 50 #include <iomanip> |
| 49 #endif | 51 #endif |
| 50 using namespace llvm; | 52 using namespace llvm; |
| 51 | 53 |
| 52 STATISTIC(NumBytes, "Number of bytes of machine code compiled"); | 54 STATISTIC(NumBytes, "Number of bytes of machine code compiled"); |
| 53 STATISTIC(NumRelos, "Number of relocations applied"); | 55 STATISTIC(NumRelos, "Number of relocations applied"); |
| 56 STATISTIC(NumRetries, "Number of retries with more memory"); |
| 54 static JIT *TheJIT = 0; | 57 static JIT *TheJIT = 0; |
| 55 | 58 |
| 56 | 59 |
| 57 //===----------------------------------------------------------------------===// | 60 //===----------------------------------------------------------------------===// |
| 58 // JIT lazy compilation code. | 61 // JIT lazy compilation code. |
| 59 // | 62 // |
| 60 namespace { | 63 namespace { |
| 61 class JITResolverState { | 64 class JITResolverState { |
| 62 public: | 65 public: |
| 63 typedef std::map<AssertingVH<Function>, void*> FunctionToStubMapTy; | 66 typedef std::map<AssertingVH<Function>, void*> FunctionToStubMapTy; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, | 218 Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, |
| 216 *TheJIT->getCodeEmitter()); | 219 *TheJIT->getCodeEmitter()); |
| 217 | 220 |
| 218 if (Actual != (void*)(intptr_t)LazyResolverFn) { | 221 if (Actual != (void*)(intptr_t)LazyResolverFn) { |
| 219 // If we are getting the stub for an external function, we really want the | 222 // If we are getting the stub for an external function, we really want the |
| 220 // address of the stub in the GlobalAddressMap for the JIT, not the address | 223 // address of the stub in the GlobalAddressMap for the JIT, not the address |
| 221 // of the external function. | 224 // of the external function. |
| 222 TheJIT->updateGlobalMapping(F, Stub); | 225 TheJIT->updateGlobalMapping(F, Stub); |
| 223 } | 226 } |
| 224 | 227 |
| 225 DOUT << "JIT: Stub emitted at [" << Stub << "] for function '" | 228 DEBUG(errs() << "JIT: Stub emitted at [" << Stub << "] for function '" |
| 226 << F->getName() << "'\n"; | 229 << F->getName() << "'\n"); |
| 227 | 230 |
| 228 // Finally, keep track of the stub-to-Function mapping so that the | 231 // Finally, keep track of the stub-to-Function mapping so that the |
| 229 // JITCompilerFn knows which function to compile! | 232 // JITCompilerFn knows which function to compile! |
| 230 state.getStubToFunctionMap(locked)[Stub] = F; | 233 state.getStubToFunctionMap(locked)[Stub] = F; |
| 231 | 234 |
| 232 // If we are JIT'ing non-lazily but need to call a function that does not | 235 // If we are JIT'ing non-lazily but need to call a function that does not |
| 233 // exist yet, add it to the JIT's work list so that we can fill in the stub | 236 // exist yet, add it to the JIT's work list so that we can fill in the stub |
| 234 // address later. | 237 // address later. |
| 235 if (!Actual && TheJIT->isLazyCompilationDisabled()) | 238 if (!Actual && TheJIT->isLazyCompilationDisabled()) |
| 236 if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode()) | 239 if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode()) |
| 237 TheJIT->addPendingFunction(F); | 240 TheJIT->addPendingFunction(F); |
| 238 | 241 |
| 239 return Stub; | 242 return Stub; |
| 240 } | 243 } |
| 241 | 244 |
| 242 /// getGlobalValueIndirectSym - Return a lazy pointer containing the specified | 245 /// getGlobalValueIndirectSym - Return a lazy pointer containing the specified |
| 243 /// GV address. | 246 /// GV address. |
| 244 void *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) { | 247 void *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) { |
| 245 MutexGuard locked(TheJIT->lock); | 248 MutexGuard locked(TheJIT->lock); |
| 246 | 249 |
| 247 // If we already have a stub for this global variable, recycle it. | 250 // If we already have a stub for this global variable, recycle it. |
| 248 void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV]; | 251 void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV]; |
| 249 if (IndirectSym) return IndirectSym; | 252 if (IndirectSym) return IndirectSym; |
| 250 | 253 |
| 251 // Otherwise, codegen a new indirect symbol. | 254 // Otherwise, codegen a new indirect symbol. |
| 252 IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress, | 255 IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress, |
| 253 *TheJIT->getCodeEmitter()); | 256 *TheJIT->getCodeEmitter()); |
| 254 | 257 |
| 255 DOUT << "JIT: Indirect symbol emitted at [" << IndirectSym << "] for GV '" | 258 DEBUG(errs() << "JIT: Indirect symbol emitted at [" << IndirectSym |
| 256 << GV->getName() << "'\n"; | 259 << "] for GV '" << GV->getName() << "'\n"); |
| 257 | 260 |
| 258 return IndirectSym; | 261 return IndirectSym; |
| 259 } | 262 } |
| 260 | 263 |
| 261 /// getExternalFunctionStub - Return a stub for the function at the | 264 /// getExternalFunctionStub - Return a stub for the function at the |
| 262 /// specified address, created lazily on demand. | 265 /// specified address, created lazily on demand. |
| 263 void *JITResolver::getExternalFunctionStub(void *FnAddr) { | 266 void *JITResolver::getExternalFunctionStub(void *FnAddr) { |
| 264 // If we already have a stub for this function, recycle it. | 267 // If we already have a stub for this function, recycle it. |
| 265 void *&Stub = ExternalFnToStubMap[FnAddr]; | 268 void *&Stub = ExternalFnToStubMap[FnAddr]; |
| 266 if (Stub) return Stub; | 269 if (Stub) return Stub; |
| 267 | 270 |
| 268 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, | 271 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, |
| 269 *TheJIT->getCodeEmitter()); | 272 *TheJIT->getCodeEmitter()); |
| 270 | 273 |
| 271 DOUT << "JIT: Stub emitted at [" << Stub | 274 DEBUG(errs() << "JIT: Stub emitted at [" << Stub |
| 272 << "] for external function at '" << FnAddr << "'\n"; | 275 << "] for external function at '" << FnAddr << "'\n"); |
| 273 return Stub; | 276 return Stub; |
| 274 } | 277 } |
| 275 | 278 |
| 276 unsigned JITResolver::getGOTIndexForAddr(void* addr) { | 279 unsigned JITResolver::getGOTIndexForAddr(void* addr) { |
| 277 unsigned idx = revGOTMap[addr]; | 280 unsigned idx = revGOTMap[addr]; |
| 278 if (!idx) { | 281 if (!idx) { |
| 279 idx = ++nextGOTIndex; | 282 idx = ++nextGOTIndex; |
| 280 revGOTMap[addr] = idx; | 283 revGOTMap[addr] = idx; |
| 281 DOUT << "JIT: Adding GOT entry " << idx << " for addr [" << addr << "]\n"; | 284 DEBUG(errs() << "JIT: Adding GOT entry " << idx << " for addr [" |
| 285 << addr << "]\n"); |
| 282 } | 286 } |
| 283 return idx; | 287 return idx; |
| 284 } | 288 } |
| 285 | 289 |
| 286 void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs, | 290 void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs, |
| 287 SmallVectorImpl<void*> &Ptrs) { | 291 SmallVectorImpl<void*> &Ptrs) { |
| 288 MutexGuard locked(TheJIT->lock); | 292 MutexGuard locked(TheJIT->lock); |
| 289 | 293 |
| 290 FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked); | 294 FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked); |
| 291 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked); | 295 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 } | 372 } |
| 369 | 373 |
| 370 // If we have already code generated the function, just return the address. | 374 // If we have already code generated the function, just return the address. |
| 371 void *Result = TheJIT->getPointerToGlobalIfAvailable(F); | 375 void *Result = TheJIT->getPointerToGlobalIfAvailable(F); |
| 372 | 376 |
| 373 if (!Result) { | 377 if (!Result) { |
| 374 // Otherwise we don't have it, do lazy compilation now. | 378 // Otherwise we don't have it, do lazy compilation now. |
| 375 | 379 |
| 376 // If lazy compilation is disabled, emit a useful error message and abort. | 380 // If lazy compilation is disabled, emit a useful error message and abort. |
| 377 if (TheJIT->isLazyCompilationDisabled()) { | 381 if (TheJIT->isLazyCompilationDisabled()) { |
| 378 cerr << "LLVM JIT requested to do lazy compilation of function '" | 382 llvm_report_error("LLVM JIT requested to do lazy compilation of function '
" |
| 379 << F->getName() << "' when lazy compiles are disabled!\n"; | 383 + F->getName() + "' when lazy compiles are disabled!"); |
| 380 abort(); | |
| 381 } | 384 } |
| 382 | 385 |
| 383 // We might like to remove the stub from the StubToFunction map. | 386 // We might like to remove the stub from the StubToFunction map. |
| 384 // We can't do that! Multiple threads could be stuck, waiting to acquire the | 387 // We can't do that! Multiple threads could be stuck, waiting to acquire the |
| 385 // lock above. As soon as the 1st function finishes compiling the function, | 388 // lock above. As soon as the 1st function finishes compiling the function, |
| 386 // the next one will be released, and needs to be able to find the function | 389 // the next one will be released, and needs to be able to find the function |
| 387 // it needs to call. | 390 // it needs to call. |
| 388 //JR.state.getStubToFunctionMap(locked).erase(I); | 391 //JR.state.getStubToFunctionMap(locked).erase(I); |
| 389 | 392 |
| 390 DOUT << "JIT: Lazily resolving function '" << F->getName() | 393 DEBUG(errs() << "JIT: Lazily resolving function '" << F->getName() |
| 391 << "' In stub ptr = " << Stub << " actual ptr = " | 394 << "' In stub ptr = " << Stub << " actual ptr = " |
| 392 << ActualPtr << "\n"; | 395 << ActualPtr << "\n"); |
| 393 | 396 |
| 394 Result = TheJIT->getPointerToFunction(F); | 397 Result = TheJIT->getPointerToFunction(F); |
| 395 } | 398 } |
| 396 | 399 |
| 397 // Reacquire the lock to erase the stub in the map. | 400 // Reacquire the lock to erase the stub in the map. |
| 398 MutexGuard locked(TheJIT->lock); | 401 MutexGuard locked(TheJIT->lock); |
| 399 | 402 |
| 400 // We don't need to reuse this stub in the future, as F is now compiled. | 403 // We don't need to reuse this stub in the future, as F is now compiled. |
| 401 JR.state.getFunctionToStubMap(locked).erase(F); | 404 JR.state.getFunctionToStubMap(locked).erase(F); |
| 402 | 405 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 419 namespace { | 422 namespace { |
| 420 /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is | 423 /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is |
| 421 /// used to output functions to memory for execution. | 424 /// used to output functions to memory for execution. |
| 422 class JITEmitter : public JITCodeEmitter { | 425 class JITEmitter : public JITCodeEmitter { |
| 423 JITMemoryManager *MemMgr; | 426 JITMemoryManager *MemMgr; |
| 424 | 427 |
| 425 // When outputting a function stub in the context of some other function, we | 428 // When outputting a function stub in the context of some other function, we |
| 426 // save BufferBegin/BufferEnd/CurBufferPtr here. | 429 // save BufferBegin/BufferEnd/CurBufferPtr here. |
| 427 uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; | 430 uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; |
| 428 | 431 |
| 432 // When reattempting to JIT a function after running out of space, we store |
| 433 // the estimated size of the function we're trying to JIT here, so we can |
| 434 // ask the memory manager for at least this much space. When we |
| 435 // successfully emit the function, we reset this back to zero. |
| 436 uintptr_t SizeEstimate; |
| 437 |
| 429 /// Relocations - These are the relocations that the function needs, as | 438 /// Relocations - These are the relocations that the function needs, as |
| 430 /// emitted. | 439 /// emitted. |
| 431 std::vector<MachineRelocation> Relocations; | 440 std::vector<MachineRelocation> Relocations; |
| 432 | 441 |
| 433 /// MBBLocations - This vector is a mapping from MBB ID's to their address. | 442 /// MBBLocations - This vector is a mapping from MBB ID's to their address. |
| 434 /// It is filled in by the StartMachineBasicBlock callback and queried by | 443 /// It is filled in by the StartMachineBasicBlock callback and queried by |
| 435 /// the getMachineBasicBlockAddress callback. | 444 /// the getMachineBasicBlockAddress callback. |
| 436 std::vector<uintptr_t> MBBLocations; | 445 std::vector<uintptr_t> MBBLocations; |
| 437 | 446 |
| 438 /// ConstantPool - The constant pool for the current function. | 447 /// ConstantPool - The constant pool for the current function. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 | 479 |
| 471 /// MMI - Machine module info for exception informations | 480 /// MMI - Machine module info for exception informations |
| 472 MachineModuleInfo* MMI; | 481 MachineModuleInfo* MMI; |
| 473 | 482 |
| 474 // GVSet - a set to keep track of which globals have been seen | 483 // GVSet - a set to keep track of which globals have been seen |
| 475 SmallPtrSet<const GlobalVariable*, 8> GVSet; | 484 SmallPtrSet<const GlobalVariable*, 8> GVSet; |
| 476 | 485 |
| 477 // CurFn - The llvm function being emitted. Only valid during | 486 // CurFn - The llvm function being emitted. Only valid during |
| 478 // finishFunction(). | 487 // finishFunction(). |
| 479 const Function *CurFn; | 488 const Function *CurFn; |
| 480 | 489 |
| 490 /// Information about emitted code, which is passed to the |
| 491 /// JITEventListeners. This is reset in startFunction and used in |
| 492 /// finishFunction. |
| 493 JITEvent_EmittedFunctionDetails EmissionDetails; |
| 494 |
| 481 // CurFnStubUses - For a given Function, a vector of stubs that it | 495 // CurFnStubUses - For a given Function, a vector of stubs that it |
| 482 // references. This facilitates the JIT detecting that a stub is no | 496 // references. This facilitates the JIT detecting that a stub is no |
| 483 // longer used, so that it may be deallocated. | 497 // longer used, so that it may be deallocated. |
| 484 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses; | 498 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses; |
| 485 | 499 |
| 486 // StubFnRefs - For a given pointer to a stub, a set of Functions which | 500 // StubFnRefs - For a given pointer to a stub, a set of Functions which |
| 487 // reference the stub. When the count of a stub's references drops to zero, | 501 // reference the stub. When the count of a stub's references drops to zero, |
| 488 // the stub is unused. | 502 // the stub is unused. |
| 489 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; | 503 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; |
| 490 | 504 |
| 491 // ExtFnStubs - A map of external function names to stubs which have entries | 505 // ExtFnStubs - A map of external function names to stubs which have entries |
| 492 // in the JITResolver's ExternalFnToStubMap. | 506 // in the JITResolver's ExternalFnToStubMap. |
| 493 StringMap<void *> ExtFnStubs; | 507 StringMap<void *> ExtFnStubs; |
| 494 | 508 |
| 509 DebugLocTuple PrevDLT; |
| 510 |
| 495 public: | 511 public: |
| 496 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) | 512 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) |
| 497 : Resolver(jit), CurFn(0) { | 513 : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0) { |
| 498 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); | 514 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); |
| 499 if (jit.getJITInfo().needsGOT()) { | 515 if (jit.getJITInfo().needsGOT()) { |
| 500 MemMgr->AllocateGOT(); | 516 MemMgr->AllocateGOT(); |
| 501 DOUT << "JIT is managing a GOT\n"; | 517 DEBUG(errs() << "JIT is managing a GOT\n"); |
| 502 } | 518 } |
| 503 | 519 |
| 504 if (ExceptionHandling || JITEmitDebugInfo) { | 520 if (DwarfExceptionHandling || JITEmitDebugInfo) { |
| 505 DE.reset(new JITDwarfEmitter(jit)); | 521 DE.reset(new JITDwarfEmitter(jit)); |
| 506 } | 522 } |
| 507 if (JITEmitDebugInfo) { | 523 if (JITEmitDebugInfo) { |
| 508 DR.reset(new JITDebugRegisterer(TM)); | 524 DR.reset(new JITDebugRegisterer(TM)); |
| 509 } | 525 } |
| 510 } | 526 } |
| 511 | |
| 512 ~JITEmitter() { | 527 ~JITEmitter() { |
| 513 delete MemMgr; | 528 delete MemMgr; |
| 514 } | 529 } |
| 515 | 530 |
| 516 /// classof - Methods for support type inquiry through isa, cast, and | 531 /// classof - Methods for support type inquiry through isa, cast, and |
| 517 /// dyn_cast: | 532 /// dyn_cast: |
| 518 /// | 533 /// |
| 519 static inline bool classof(const JITEmitter*) { return true; } | 534 static inline bool classof(const JITEmitter*) { return true; } |
| 520 static inline bool classof(const MachineCodeEmitter*) { return true; } | 535 static inline bool classof(const MachineCodeEmitter*) { return true; } |
| 521 | 536 |
| 522 JITResolver &getJITResolver() { return Resolver; } | 537 JITResolver &getJITResolver() { return Resolver; } |
| 523 | 538 |
| 524 virtual void startFunction(MachineFunction &F); | 539 virtual void startFunction(MachineFunction &F); |
| 525 virtual bool finishFunction(MachineFunction &F); | 540 virtual bool finishFunction(MachineFunction &F); |
| 526 | 541 |
| 527 void emitConstantPool(MachineConstantPool *MCP); | 542 void emitConstantPool(MachineConstantPool *MCP); |
| 528 void initJumpTableInfo(MachineJumpTableInfo *MJTI); | 543 void initJumpTableInfo(MachineJumpTableInfo *MJTI); |
| 529 void emitJumpTableInfo(MachineJumpTableInfo *MJTI); | 544 void emitJumpTableInfo(MachineJumpTableInfo *MJTI); |
| 530 | 545 |
| 531 virtual void startGVStub(const GlobalValue* GV, unsigned StubSize, | 546 virtual void startGVStub(const GlobalValue* GV, unsigned StubSize, |
| 532 unsigned Alignment = 1); | 547 unsigned Alignment = 1); |
| 533 virtual void startGVStub(const GlobalValue* GV, void *Buffer, | 548 virtual void startGVStub(const GlobalValue* GV, void *Buffer, |
| 534 unsigned StubSize); | 549 unsigned StubSize); |
| 535 virtual void* finishGVStub(const GlobalValue *GV); | 550 virtual void* finishGVStub(const GlobalValue *GV); |
| 536 | 551 |
| 537 /// allocateSpace - Reserves space in the current block if any, or | 552 /// allocateSpace - Reserves space in the current block if any, or |
| 538 /// allocate a new one of the given size. | 553 /// allocate a new one of the given size. |
| 539 virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); | 554 virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); |
| 540 | 555 |
| 556 /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace, |
| 557 /// this method does not allocate memory in the current output buffer, |
| 558 /// because a global may live longer than the current function. |
| 559 virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment); |
| 560 |
| 541 virtual void addRelocation(const MachineRelocation &MR) { | 561 virtual void addRelocation(const MachineRelocation &MR) { |
| 542 Relocations.push_back(MR); | 562 Relocations.push_back(MR); |
| 543 } | 563 } |
| 544 | 564 |
| 545 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { | 565 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { |
| 546 if (MBBLocations.size() <= (unsigned)MBB->getNumber()) | 566 if (MBBLocations.size() <= (unsigned)MBB->getNumber()) |
| 547 MBBLocations.resize((MBB->getNumber()+1)*2); | 567 MBBLocations.resize((MBB->getNumber()+1)*2); |
| 548 MBBLocations[MBB->getNumber()] = getCurrentPCValue(); | 568 MBBLocations[MBB->getNumber()] = getCurrentPCValue(); |
| 549 DOUT << "JIT: Emitting BB" << MBB->getNumber() << " at [" | 569 DEBUG(errs() << "JIT: Emitting BB" << MBB->getNumber() << " at [" |
| 550 << (void*) getCurrentPCValue() << "]\n"; | 570 << (void*) getCurrentPCValue() << "]\n"); |
| 551 } | 571 } |
| 552 | 572 |
| 553 virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; | 573 virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; |
| 554 virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; | 574 virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; |
| 555 | 575 |
| 556 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const
{ | 576 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const
{ |
| 557 assert(MBBLocations.size() > (unsigned)MBB->getNumber() && | 577 assert(MBBLocations.size() > (unsigned)MBB->getNumber() && |
| 558 MBBLocations[MBB->getNumber()] && "MBB not emitted!"); | 578 MBBLocations[MBB->getNumber()] && "MBB not emitted!"); |
| 559 return MBBLocations[MBB->getNumber()]; | 579 return MBBLocations[MBB->getNumber()]; |
| 560 } | 580 } |
| 561 | 581 |
| 582 /// retryWithMoreMemory - Log a retry and deallocate all memory for the |
| 583 /// given function. Increase the minimum allocation size so that we get |
| 584 /// more memory next time. |
| 585 void retryWithMoreMemory(MachineFunction &F); |
| 586 |
| 562 /// deallocateMemForFunction - Deallocate all memory for the specified | 587 /// deallocateMemForFunction - Deallocate all memory for the specified |
| 563 /// function body. | 588 /// function body. |
| 564 void deallocateMemForFunction(Function *F); | 589 void deallocateMemForFunction(const Function *F); |
| 565 | 590 |
| 566 /// AddStubToCurrentFunction - Mark the current function being JIT'd as | 591 /// AddStubToCurrentFunction - Mark the current function being JIT'd as |
| 567 /// using the stub at the specified address. Allows | 592 /// using the stub at the specified address. Allows |
| 568 /// deallocateMemForFunction to also remove stubs no longer referenced. | 593 /// deallocateMemForFunction to also remove stubs no longer referenced. |
| 569 void AddStubToCurrentFunction(void *Stub); | 594 void AddStubToCurrentFunction(void *Stub); |
| 570 | 595 |
| 571 /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for | 596 /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for |
| 572 /// MachineRelocations that reference external functions by name. | 597 /// MachineRelocations that reference external functions by name. |
| 573 const StringMap<void*> &getExternalFnStubs() const { return ExtFnStubs; } | 598 const StringMap<void*> &getExternalFnStubs() const { return ExtFnStubs; } |
| 574 | 599 |
| 600 virtual void processDebugLoc(DebugLoc DL); |
| 601 |
| 575 virtual void emitLabel(uint64_t LabelID) { | 602 virtual void emitLabel(uint64_t LabelID) { |
| 576 if (LabelLocations.size() <= LabelID) | 603 if (LabelLocations.size() <= LabelID) |
| 577 LabelLocations.resize((LabelID+1)*2); | 604 LabelLocations.resize((LabelID+1)*2); |
| 578 LabelLocations[LabelID] = getCurrentPCValue(); | 605 LabelLocations[LabelID] = getCurrentPCValue(); |
| 579 } | 606 } |
| 580 | 607 |
| 581 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { | 608 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { |
| 582 assert(LabelLocations.size() > (unsigned)LabelID && | 609 assert(LabelLocations.size() > (unsigned)LabelID && |
| 583 LabelLocations[LabelID] && "Label not emitted!"); | 610 LabelLocations[LabelID] && "Label not emitted!"); |
| 584 return LabelLocations[LabelID]; | 611 return LabelLocations[LabelID]; |
| 585 } | 612 } |
| 586 | 613 |
| 587 virtual void setModuleInfo(MachineModuleInfo* Info) { | 614 virtual void setModuleInfo(MachineModuleInfo* Info) { |
| 588 MMI = Info; | 615 MMI = Info; |
| 589 if (ExceptionHandling || JITEmitDebugInfo) { | 616 if (DE.get()) DE->setModuleInfo(Info); |
| 590 DE->setModuleInfo(Info); | 617 } |
| 591 } | 618 |
| 592 } | 619 void setMemoryExecutable() { |
| 593 | |
| 594 void setMemoryExecutable(void) { | |
| 595 MemMgr->setMemoryExecutable(); | 620 MemMgr->setMemoryExecutable(); |
| 596 } | 621 } |
| 597 | 622 |
| 598 JITMemoryManager *getMemMgr(void) const { return MemMgr; } | 623 JITMemoryManager *getMemMgr() const { return MemMgr; } |
| 599 | 624 |
| 600 private: | 625 private: |
| 601 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); | 626 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); |
| 602 void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference, | 627 void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference, |
| 603 bool NoNeedStub); | 628 bool NoNeedStub); |
| 604 unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size); | 629 unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size); |
| 605 unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size); | 630 unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size); |
| 606 unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size); | 631 unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size); |
| 607 unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF); | 632 unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF); |
| 608 }; | 633 }; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 | 701 |
| 677 assert(CurFn && "Stub added to current function, but current function is 0!"); | 702 assert(CurFn && "Stub added to current function, but current function is 0!"); |
| 678 | 703 |
| 679 SmallVectorImpl<void*> &StubsUsed = CurFnStubUses[CurFn]; | 704 SmallVectorImpl<void*> &StubsUsed = CurFnStubUses[CurFn]; |
| 680 StubsUsed.push_back(StubAddr); | 705 StubsUsed.push_back(StubAddr); |
| 681 | 706 |
| 682 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[StubAddr]; | 707 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[StubAddr]; |
| 683 FnRefs.insert(CurFn); | 708 FnRefs.insert(CurFn); |
| 684 } | 709 } |
| 685 | 710 |
| 711 void JITEmitter::processDebugLoc(DebugLoc DL) { |
| 712 if (!DL.isUnknown()) { |
| 713 DebugLocTuple CurDLT = EmissionDetails.MF->getDebugLocTuple(DL); |
| 714 |
| 715 if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT) { |
| 716 JITEvent_EmittedFunctionDetails::LineStart NextLine; |
| 717 NextLine.Address = getCurrentPCValue(); |
| 718 NextLine.Loc = DL; |
| 719 EmissionDetails.LineStarts.push_back(NextLine); |
| 720 } |
| 721 |
| 722 PrevDLT = CurDLT; |
| 723 } |
| 724 } |
| 725 |
| 686 static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, | 726 static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, |
| 687 const TargetData *TD) { | 727 const TargetData *TD) { |
| 688 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); | 728 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); |
| 689 if (Constants.empty()) return 0; | 729 if (Constants.empty()) return 0; |
| 690 | 730 |
| 691 unsigned Size = 0; | 731 unsigned Size = 0; |
| 692 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { | 732 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { |
| 693 MachineConstantPoolEntry CPE = Constants[i]; | 733 MachineConstantPoolEntry CPE = Constants[i]; |
| 694 unsigned AlignMask = CPE.getAlignment() - 1; | 734 unsigned AlignMask = CPE.getAlignment() - 1; |
| 695 Size = (Size + AlignMask) & ~AlignMask; | 735 Size = (Size + AlignMask) & ~AlignMask; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 719 } | 759 } |
| 720 | 760 |
| 721 /// addSizeOfGlobal - add the size of the global (plus any alignment padding) | 761 /// addSizeOfGlobal - add the size of the global (plus any alignment padding) |
| 722 /// into the running total Size. | 762 /// into the running total Size. |
| 723 | 763 |
| 724 unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) { | 764 unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) { |
| 725 const Type *ElTy = GV->getType()->getElementType(); | 765 const Type *ElTy = GV->getType()->getElementType(); |
| 726 size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy); | 766 size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy); |
| 727 size_t GVAlign = | 767 size_t GVAlign = |
| 728 (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); | 768 (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); |
| 729 DOUT << "JIT: Adding in size " << GVSize << " alignment " << GVAlign; | 769 DEBUG(errs() << "JIT: Adding in size " << GVSize << " alignment " << GVAlign); |
| 730 DEBUG(GV->dump()); | 770 DEBUG(GV->dump()); |
| 731 // Assume code section ends with worst possible alignment, so first | 771 // Assume code section ends with worst possible alignment, so first |
| 732 // variable needs maximal padding. | 772 // variable needs maximal padding. |
| 733 if (Size==0) | 773 if (Size==0) |
| 734 Size = 1; | 774 Size = 1; |
| 735 Size = ((Size+GVAlign-1)/GVAlign)*GVAlign; | 775 Size = ((Size+GVAlign-1)/GVAlign)*GVAlign; |
| 736 Size += GVSize; | 776 Size += GVSize; |
| 737 return Size; | 777 return Size; |
| 738 } | 778 } |
| 739 | 779 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 case Instruction::URem: | 818 case Instruction::URem: |
| 779 case Instruction::SRem: | 819 case Instruction::SRem: |
| 780 case Instruction::And: | 820 case Instruction::And: |
| 781 case Instruction::Or: | 821 case Instruction::Or: |
| 782 case Instruction::Xor: { | 822 case Instruction::Xor: { |
| 783 Size = addSizeOfGlobalsInConstantVal(Op0, Size); | 823 Size = addSizeOfGlobalsInConstantVal(Op0, Size); |
| 784 Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size); | 824 Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size); |
| 785 break; | 825 break; |
| 786 } | 826 } |
| 787 default: { | 827 default: { |
| 788 cerr << "ConstantExpr not handled: " << *CE << "\n"; | 828 std::string msg; |
| 789 abort(); | 829 raw_string_ostream Msg(msg); |
| 830 Msg << "ConstantExpr not handled: " << *CE; |
| 831 llvm_report_error(Msg.str()); |
| 790 } | 832 } |
| 791 } | 833 } |
| 792 } | 834 } |
| 793 | 835 |
| 794 if (C->getType()->getTypeID() == Type::PointerTyID) | 836 if (C->getType()->getTypeID() == Type::PointerTyID) |
| 795 if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C)) | 837 if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C)) |
| 796 if (GVSet.insert(GV)) | 838 if (GVSet.insert(GV)) |
| 797 Size = addSizeOfGlobal(GV, Size); | 839 Size = addSizeOfGlobal(GV, Size); |
| 798 | 840 |
| 799 return Size; | 841 return Size; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 // assuming the addresses of the new globals in this module | 887 // assuming the addresses of the new globals in this module |
| 846 // start at 0 (or something) and adjusting them after codegen | 888 // start at 0 (or something) and adjusting them after codegen |
| 847 // complete. Another possibility is to grab a marker bit in GV. | 889 // complete. Another possibility is to grab a marker bit in GV. |
| 848 if (GVSet.insert(GV)) | 890 if (GVSet.insert(GV)) |
| 849 // A variable as yet unseen. Add in its size. | 891 // A variable as yet unseen. Add in its size. |
| 850 Size = addSizeOfGlobal(GV, Size); | 892 Size = addSizeOfGlobal(GV, Size); |
| 851 } | 893 } |
| 852 } | 894 } |
| 853 } | 895 } |
| 854 } | 896 } |
| 855 DOUT << "JIT: About to look through initializers\n"; | 897 DEBUG(errs() << "JIT: About to look through initializers\n"); |
| 856 // Look for more globals that are referenced only from initializers. | 898 // Look for more globals that are referenced only from initializers. |
| 857 // GVSet.end is computed each time because the set can grow as we go. | 899 // GVSet.end is computed each time because the set can grow as we go. |
| 858 for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin(); | 900 for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin(); |
| 859 I != GVSet.end(); I++) { | 901 I != GVSet.end(); I++) { |
| 860 const GlobalVariable* GV = *I; | 902 const GlobalVariable* GV = *I; |
| 861 if (GV->hasInitializer()) | 903 if (GV->hasInitializer()) |
| 862 Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size); | 904 Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size); |
| 863 } | 905 } |
| 864 | 906 |
| 865 return Size; | 907 return Size; |
| 866 } | 908 } |
| 867 | 909 |
| 868 void JITEmitter::startFunction(MachineFunction &F) { | 910 void JITEmitter::startFunction(MachineFunction &F) { |
| 869 DOUT << "JIT: Starting CodeGen of Function " | 911 DEBUG(errs() << "JIT: Starting CodeGen of Function " |
| 870 << F.getFunction()->getName() << "\n"; | 912 << F.getFunction()->getName() << "\n"); |
| 871 | 913 |
| 872 uintptr_t ActualSize = 0; | 914 uintptr_t ActualSize = 0; |
| 873 // Set the memory writable, if it's not already | 915 // Set the memory writable, if it's not already |
| 874 MemMgr->setMemoryWritable(); | 916 MemMgr->setMemoryWritable(); |
| 875 if (MemMgr->NeedsExactSize()) { | 917 if (MemMgr->NeedsExactSize()) { |
| 876 DOUT << "JIT: ExactSize\n"; | 918 DEBUG(errs() << "JIT: ExactSize\n"); |
| 877 const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); | 919 const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); |
| 878 MachineJumpTableInfo *MJTI = F.getJumpTableInfo(); | 920 MachineJumpTableInfo *MJTI = F.getJumpTableInfo(); |
| 879 MachineConstantPool *MCP = F.getConstantPool(); | 921 MachineConstantPool *MCP = F.getConstantPool(); |
| 880 | 922 |
| 881 // Ensure the constant pool/jump table info is at least 4-byte aligned. | 923 // Ensure the constant pool/jump table info is at least 4-byte aligned. |
| 882 ActualSize = RoundUpToAlign(ActualSize, 16); | 924 ActualSize = RoundUpToAlign(ActualSize, 16); |
| 883 | 925 |
| 884 // Add the alignment of the constant pool | 926 // Add the alignment of the constant pool |
| 885 ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment()); | 927 ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment()); |
| 886 | 928 |
| 887 // Add the constant pool size | 929 // Add the constant pool size |
| 888 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); | 930 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); |
| 889 | 931 |
| 890 // Add the aligment of the jump table info | 932 // Add the aligment of the jump table info |
| 891 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); | 933 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); |
| 892 | 934 |
| 893 // Add the jump table size | 935 // Add the jump table size |
| 894 ActualSize += GetJumpTableSizeInBytes(MJTI); | 936 ActualSize += GetJumpTableSizeInBytes(MJTI); |
| 895 | 937 |
| 896 // Add the alignment for the function | 938 // Add the alignment for the function |
| 897 ActualSize = RoundUpToAlign(ActualSize, | 939 ActualSize = RoundUpToAlign(ActualSize, |
| 898 std::max(F.getFunction()->getAlignment(), 8U)); | 940 std::max(F.getFunction()->getAlignment(), 8U)); |
| 899 | 941 |
| 900 // Add the function size | 942 // Add the function size |
| 901 ActualSize += TII->GetFunctionSizeInBytes(F); | 943 ActualSize += TII->GetFunctionSizeInBytes(F); |
| 902 | 944 |
| 903 DOUT << "JIT: ActualSize before globals " << ActualSize << "\n"; | 945 DEBUG(errs() << "JIT: ActualSize before globals " << ActualSize << "\n"); |
| 904 // Add the size of the globals that will be allocated after this function. | 946 // Add the size of the globals that will be allocated after this function. |
| 905 // These are all the ones referenced from this function that were not | 947 // These are all the ones referenced from this function that were not |
| 906 // previously allocated. | 948 // previously allocated. |
| 907 ActualSize += GetSizeOfGlobalsInBytes(F); | 949 ActualSize += GetSizeOfGlobalsInBytes(F); |
| 908 DOUT << "JIT: ActualSize after globals " << ActualSize << "\n"; | 950 DEBUG(errs() << "JIT: ActualSize after globals " << ActualSize << "\n"); |
| 951 } else if (SizeEstimate > 0) { |
| 952 // SizeEstimate will be non-zero on reallocation attempts. |
| 953 ActualSize = SizeEstimate; |
| 909 } | 954 } |
| 910 | 955 |
| 911 BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), | 956 BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), |
| 912 ActualSize); | 957 ActualSize); |
| 913 BufferEnd = BufferBegin+ActualSize; | 958 BufferEnd = BufferBegin+ActualSize; |
| 914 | 959 |
| 915 // Ensure the constant pool/jump table info is at least 4-byte aligned. | 960 // Ensure the constant pool/jump table info is at least 4-byte aligned. |
| 916 emitAlignment(16); | 961 emitAlignment(16); |
| 917 | 962 |
| 918 emitConstantPool(F.getConstantPool()); | 963 emitConstantPool(F.getConstantPool()); |
| 919 initJumpTableInfo(F.getJumpTableInfo()); | 964 initJumpTableInfo(F.getJumpTableInfo()); |
| 920 | 965 |
| 921 // About to start emitting the machine code for the function. | 966 // About to start emitting the machine code for the function. |
| 922 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); | 967 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); |
| 923 TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); | 968 TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); |
| 924 | 969 |
| 925 MBBLocations.clear(); | 970 MBBLocations.clear(); |
| 971 |
| 972 EmissionDetails.MF = &F; |
| 973 EmissionDetails.LineStarts.clear(); |
| 926 } | 974 } |
| 927 | 975 |
| 928 bool JITEmitter::finishFunction(MachineFunction &F) { | 976 bool JITEmitter::finishFunction(MachineFunction &F) { |
| 929 if (CurBufferPtr == BufferEnd) { | 977 if (CurBufferPtr == BufferEnd) { |
| 930 // FIXME: Allocate more space, then try again. | 978 // We must call endFunctionBody before retrying, because |
| 931 cerr << "JIT: Ran out of space for generated machine code!\n"; | 979 // deallocateMemForFunction requires it. |
| 932 abort(); | 980 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); |
| 933 } | 981 retryWithMoreMemory(F); |
| 934 | 982 return true; |
| 983 } |
| 984 |
| 935 emitJumpTableInfo(F.getJumpTableInfo()); | 985 emitJumpTableInfo(F.getJumpTableInfo()); |
| 936 | 986 |
| 937 // FnStart is the start of the text, not the start of the constant pool and | 987 // FnStart is the start of the text, not the start of the constant pool and |
| 938 // other per-function data. | 988 // other per-function data. |
| 939 uint8_t *FnStart = | 989 uint8_t *FnStart = |
| 940 (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); | 990 (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); |
| 941 | 991 |
| 942 // FnEnd is the end of the function's machine code. | 992 // FnEnd is the end of the function's machine code. |
| 943 uint8_t *FnEnd = CurBufferPtr; | 993 uint8_t *FnEnd = CurBufferPtr; |
| 944 | 994 |
| 945 if (!Relocations.empty()) { | 995 if (!Relocations.empty()) { |
| 946 CurFn = F.getFunction(); | 996 CurFn = F.getFunction(); |
| 947 NumRelos += Relocations.size(); | 997 NumRelos += Relocations.size(); |
| 948 | 998 |
| 949 // Resolve the relocations to concrete pointers. | 999 // Resolve the relocations to concrete pointers. |
| 950 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { | 1000 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { |
| 951 MachineRelocation &MR = Relocations[i]; | 1001 MachineRelocation &MR = Relocations[i]; |
| 952 void *ResultPtr = 0; | 1002 void *ResultPtr = 0; |
| 953 if (!MR.letTargetResolve()) { | 1003 if (!MR.letTargetResolve()) { |
| 954 if (MR.isExternalSymbol()) { | 1004 if (MR.isExternalSymbol()) { |
| 955 ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(), | 1005 ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(), |
| 956 false); | 1006 false); |
| 957 DOUT << "JIT: Map \'" << MR.getExternalSymbol() << "\' to [" | 1007 DEBUG(errs() << "JIT: Map \'" << MR.getExternalSymbol() << "\' to [" |
| 958 << ResultPtr << "]\n"; | 1008 << ResultPtr << "]\n"); |
| 959 | 1009 |
| 960 // If the target REALLY wants a stub for this function, emit it now. | 1010 // If the target REALLY wants a stub for this function, emit it now. |
| 961 if (!MR.doesntNeedStub()) { | 1011 if (!MR.doesntNeedStub()) { |
| 962 if (!TheJIT->areDlsymStubsEnabled()) { | 1012 if (!TheJIT->areDlsymStubsEnabled()) { |
| 963 ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); | 1013 ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); |
| 964 } else { | 1014 } else { |
| 965 void *&Stub = ExtFnStubs[MR.getExternalSymbol()]; | 1015 void *&Stub = ExtFnStubs[MR.getExternalSymbol()]; |
| 966 if (!Stub) { | 1016 if (!Stub) { |
| 967 Stub = Resolver.getExternalFunctionStub((void *)&Stub); | 1017 Stub = Resolver.getExternalFunctionStub((void *)&Stub); |
| 968 AddStubToCurrentFunction(Stub); | 1018 AddStubToCurrentFunction(Stub); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 989 | 1039 |
| 990 MR.setResultPointer(ResultPtr); | 1040 MR.setResultPointer(ResultPtr); |
| 991 } | 1041 } |
| 992 | 1042 |
| 993 // if we are managing the GOT and the relocation wants an index, | 1043 // if we are managing the GOT and the relocation wants an index, |
| 994 // give it one | 1044 // give it one |
| 995 if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { | 1045 if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { |
| 996 unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); | 1046 unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); |
| 997 MR.setGOTIndex(idx); | 1047 MR.setGOTIndex(idx); |
| 998 if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { | 1048 if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { |
| 999 DOUT << "JIT: GOT was out of date for " << ResultPtr | 1049 DEBUG(errs() << "JIT: GOT was out of date for " << ResultPtr |
| 1000 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] | 1050 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] |
| 1001 << "\n"; | 1051 << "\n"); |
| 1002 ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; | 1052 ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; |
| 1003 } | 1053 } |
| 1004 } | 1054 } |
| 1005 } | 1055 } |
| 1006 | 1056 |
| 1007 CurFn = 0; | 1057 CurFn = 0; |
| 1008 TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], | 1058 TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], |
| 1009 Relocations.size(), MemMgr->getGOTBase()); | 1059 Relocations.size(), MemMgr->getGOTBase()); |
| 1010 } | 1060 } |
| 1011 | 1061 |
| 1012 // Update the GOT entry for F to point to the new code. | 1062 // Update the GOT entry for F to point to the new code. |
| 1013 if (MemMgr->isManagingGOT()) { | 1063 if (MemMgr->isManagingGOT()) { |
| 1014 unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); | 1064 unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); |
| 1015 if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { | 1065 if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { |
| 1016 DOUT << "JIT: GOT was out of date for " << (void*)BufferBegin | 1066 DEBUG(errs() << "JIT: GOT was out of date for " << (void*)BufferBegin |
| 1017 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n"; | 1067 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] |
| 1068 << "\n"); |
| 1018 ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; | 1069 ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; |
| 1019 } | 1070 } |
| 1020 } | 1071 } |
| 1021 | 1072 |
| 1022 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for | 1073 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for |
| 1023 // global variables that were referenced in the relocations. | 1074 // global variables that were referenced in the relocations. |
| 1024 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); | 1075 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); |
| 1025 | 1076 |
| 1026 if (CurBufferPtr == BufferEnd) { | 1077 if (CurBufferPtr == BufferEnd) { |
| 1027 // FIXME: Allocate more space, then try again. | 1078 retryWithMoreMemory(F); |
| 1028 cerr << "JIT: Ran out of space for generated machine code!\n"; | 1079 return true; |
| 1029 abort(); | 1080 } else { |
| 1081 // Now that we've succeeded in emitting the function, reset the |
| 1082 // SizeEstimate back down to zero. |
| 1083 SizeEstimate = 0; |
| 1030 } | 1084 } |
| 1031 | 1085 |
| 1032 BufferBegin = CurBufferPtr = 0; | 1086 BufferBegin = CurBufferPtr = 0; |
| 1033 NumBytes += FnEnd-FnStart; | 1087 NumBytes += FnEnd-FnStart; |
| 1034 | 1088 |
| 1035 // Invalidate the icache if necessary. | 1089 // Invalidate the icache if necessary. |
| 1036 sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart); | 1090 sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart); |
| 1037 | 1091 |
| 1038 JITEvent_EmittedFunctionDetails Details; | |
| 1039 TheJIT->NotifyFunctionEmitted(*F.getFunction(), FnStart, FnEnd-FnStart, | 1092 TheJIT->NotifyFunctionEmitted(*F.getFunction(), FnStart, FnEnd-FnStart, |
| 1040 Details); | 1093 EmissionDetails); |
| 1041 | 1094 |
| 1042 DOUT << "JIT: Finished CodeGen of [" << (void*)FnStart | 1095 DEBUG(errs() << "JIT: Finished CodeGen of [" << (void*)FnStart |
| 1043 << "] Function: " << F.getFunction()->getName() | 1096 << "] Function: " << F.getFunction()->getName() |
| 1044 << ": " << (FnEnd-FnStart) << " bytes of text, " | 1097 << ": " << (FnEnd-FnStart) << " bytes of text, " |
| 1045 << Relocations.size() << " relocations\n"; | 1098 << Relocations.size() << " relocations\n"); |
| 1046 | 1099 |
| 1047 Relocations.clear(); | 1100 Relocations.clear(); |
| 1048 ConstPoolAddresses.clear(); | 1101 ConstPoolAddresses.clear(); |
| 1049 | 1102 |
| 1050 // Mark code region readable and executable if it's not so already. | 1103 // Mark code region readable and executable if it's not so already. |
| 1051 MemMgr->setMemoryExecutable(); | 1104 MemMgr->setMemoryExecutable(); |
| 1052 | 1105 |
| 1053 #ifndef NDEBUG | 1106 DEBUG( |
| 1054 { | |
| 1055 if (sys::hasDisassembler()) { | 1107 if (sys::hasDisassembler()) { |
| 1056 DOUT << "JIT: Disassembled code:\n"; | 1108 errs() << "JIT: Disassembled code:\n"; |
| 1057 DOUT << sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart)
; | 1109 errs() << sys::disassembleBuffer(FnStart, FnEnd-FnStart, |
| 1110 (uintptr_t)FnStart); |
| 1058 } else { | 1111 } else { |
| 1059 DOUT << "JIT: Binary code:\n"; | 1112 errs() << "JIT: Binary code:\n"; |
| 1060 DOUT << std::hex; | |
| 1061 uint8_t* q = FnStart; | 1113 uint8_t* q = FnStart; |
| 1062 for (int i = 0; q < FnEnd; q += 4, ++i) { | 1114 for (int i = 0; q < FnEnd; q += 4, ++i) { |
| 1063 if (i == 4) | 1115 if (i == 4) |
| 1064 i = 0; | 1116 i = 0; |
| 1065 if (i == 0) | 1117 if (i == 0) |
| 1066 DOUT << "JIT: " << std::setw(8) << std::setfill('0') | 1118 errs() << "JIT: " << (long)(q - FnStart) << ": "; |
| 1067 << (long)(q - FnStart) << ": "; | |
| 1068 bool Done = false; | 1119 bool Done = false; |
| 1069 for (int j = 3; j >= 0; --j) { | 1120 for (int j = 3; j >= 0; --j) { |
| 1070 if (q + j >= FnEnd) | 1121 if (q + j >= FnEnd) |
| 1071 Done = true; | 1122 Done = true; |
| 1072 else | 1123 else |
| 1073 DOUT << std::setw(2) << std::setfill('0') << (unsigned short)q[j]; | 1124 errs() << (unsigned short)q[j]; |
| 1074 } | 1125 } |
| 1075 if (Done) | 1126 if (Done) |
| 1076 break; | 1127 break; |
| 1077 DOUT << ' '; | 1128 errs() << ' '; |
| 1078 if (i == 3) | 1129 if (i == 3) |
| 1079 DOUT << '\n'; | 1130 errs() << '\n'; |
| 1080 } | 1131 } |
| 1081 DOUT << std::dec; | 1132 errs()<< '\n'; |
| 1082 DOUT<< '\n'; | 1133 } |
| 1083 } | 1134 ); |
| 1084 } | 1135 |
| 1085 #endif | 1136 if (DwarfExceptionHandling || JITEmitDebugInfo) { |
| 1086 if (ExceptionHandling || JITEmitDebugInfo) { | |
| 1087 uintptr_t ActualSize = 0; | 1137 uintptr_t ActualSize = 0; |
| 1088 SavedBufferBegin = BufferBegin; | 1138 SavedBufferBegin = BufferBegin; |
| 1089 SavedBufferEnd = BufferEnd; | 1139 SavedBufferEnd = BufferEnd; |
| 1090 SavedCurBufferPtr = CurBufferPtr; | 1140 SavedCurBufferPtr = CurBufferPtr; |
| 1091 | 1141 |
| 1092 if (MemMgr->NeedsExactSize()) { | 1142 if (MemMgr->NeedsExactSize()) { |
| 1093 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); | 1143 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); |
| 1094 } | 1144 } |
| 1095 | 1145 |
| 1096 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), | 1146 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), |
| 1097 ActualSize); | 1147 ActualSize); |
| 1098 BufferEnd = BufferBegin+ActualSize; | 1148 BufferEnd = BufferBegin+ActualSize; |
| 1099 uint8_t* EhStart = BufferBegin; | 1149 uint8_t *EhStart; |
| 1100 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); | 1150 uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, |
| 1151 EhStart); |
| 1101 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, | 1152 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, |
| 1102 FrameRegister); | 1153 FrameRegister); |
| 1103 uint8_t* EhEnd = CurBufferPtr; | 1154 uint8_t *EhEnd = CurBufferPtr; |
| 1104 BufferBegin = SavedBufferBegin; | 1155 BufferBegin = SavedBufferBegin; |
| 1105 BufferEnd = SavedBufferEnd; | 1156 BufferEnd = SavedBufferEnd; |
| 1106 CurBufferPtr = SavedCurBufferPtr; | 1157 CurBufferPtr = SavedCurBufferPtr; |
| 1107 | 1158 |
| 1108 if (ExceptionHandling) { | 1159 if (DwarfExceptionHandling) { |
| 1109 TheJIT->RegisterTable(FrameRegister); | 1160 TheJIT->RegisterTable(FrameRegister); |
| 1110 } | 1161 } |
| 1111 | 1162 |
| 1112 if (JITEmitDebugInfo) { | 1163 if (JITEmitDebugInfo) { |
| 1113 DebugInfo I; | 1164 DebugInfo I; |
| 1114 I.FnStart = FnStart; | 1165 I.FnStart = FnStart; |
| 1115 I.FnEnd = FnEnd; | 1166 I.FnEnd = FnEnd; |
| 1116 I.EhStart = EhStart; | 1167 I.EhStart = EhStart; |
| 1117 I.EhEnd = EhEnd; | 1168 I.EhEnd = EhEnd; |
| 1118 DR->RegisterFunction(F.getFunction(), I); | 1169 DR->RegisterFunction(F.getFunction(), I); |
| 1119 } | 1170 } |
| 1120 } | 1171 } |
| 1121 | 1172 |
| 1122 if (MMI) | 1173 if (MMI) |
| 1123 MMI->EndFunction(); | 1174 MMI->EndFunction(); |
| 1124 | 1175 |
| 1125 return false; | 1176 return false; |
| 1126 } | 1177 } |
| 1127 | 1178 |
| 1179 void JITEmitter::retryWithMoreMemory(MachineFunction &F) { |
| 1180 DEBUG(errs() << "JIT: Ran out of space for native code. Reattempting.\n"); |
| 1181 Relocations.clear(); // Clear the old relocations or we'll reapply them. |
| 1182 ConstPoolAddresses.clear(); |
| 1183 ++NumRetries; |
| 1184 deallocateMemForFunction(F.getFunction()); |
| 1185 // Try again with at least twice as much free space. |
| 1186 SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin)); |
| 1187 } |
| 1188 |
| 1128 /// deallocateMemForFunction - Deallocate all memory for the specified | 1189 /// deallocateMemForFunction - Deallocate all memory for the specified |
| 1129 /// function body. Also drop any references the function has to stubs. | 1190 /// function body. Also drop any references the function has to stubs. |
| 1130 void JITEmitter::deallocateMemForFunction(Function *F) { | 1191 void JITEmitter::deallocateMemForFunction(const Function *F) { |
| 1131 MemMgr->deallocateMemForFunction(F); | 1192 MemMgr->deallocateMemForFunction(F); |
| 1132 | 1193 |
| 1133 // Do we need to unregister exception handling information from libgcc here? | 1194 // Do we need to unregister exception handling information from libgcc here? |
| 1134 | 1195 |
| 1135 if (JITEmitDebugInfo) { | 1196 if (JITEmitDebugInfo) { |
| 1136 DR->UnregisterFunction(F); | 1197 DR->UnregisterFunction(F); |
| 1137 } | 1198 } |
| 1138 | 1199 |
| 1139 // If the function did not reference any stubs, return. | 1200 // If the function did not reference any stubs, return. |
| 1140 if (CurFnStubUses.find(F) == CurFnStubUses.end()) | 1201 if (CurFnStubUses.find(F) == CurFnStubUses.end()) |
| 1141 return; | 1202 return; |
| 1142 | 1203 |
| 1143 // For each referenced stub, erase the reference to this function, and then | 1204 // For each referenced stub, erase the reference to this function, and then |
| 1144 // erase the list of referenced stubs. | 1205 // erase the list of referenced stubs. |
| 1145 SmallVectorImpl<void *> &StubList = CurFnStubUses[F]; | 1206 SmallVectorImpl<void *> &StubList = CurFnStubUses[F]; |
| 1146 for (unsigned i = 0, e = StubList.size(); i != e; ++i) { | 1207 for (unsigned i = 0, e = StubList.size(); i != e; ++i) { |
| 1147 void *Stub = StubList[i]; | 1208 void *Stub = StubList[i]; |
| 1148 | 1209 |
| 1149 // If we already invalidated this stub for this function, continue. | 1210 // If we already invalidated this stub for this function, continue. |
| 1150 if (StubFnRefs.count(Stub) == 0) | 1211 if (StubFnRefs.count(Stub) == 0) |
| 1151 continue; | 1212 continue; |
| 1152 | 1213 |
| 1153 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub]; | 1214 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub]; |
| 1154 FnRefs.erase(F); | 1215 FnRefs.erase(F); |
| 1155 | 1216 |
| 1156 // If this function was the last reference to the stub, invalidate the stub | 1217 // If this function was the last reference to the stub, invalidate the stub |
| 1157 // in the JITResolver. Were there a memory manager deallocateStub routine, | 1218 // in the JITResolver. Were there a memory manager deallocateStub routine, |
| 1158 // we could call that at this point too. | 1219 // we could call that at this point too. |
| 1159 if (FnRefs.empty()) { | 1220 if (FnRefs.empty()) { |
| 1160 DOUT << "\nJIT: Invalidated Stub at [" << Stub << "]\n"; | 1221 DEBUG(errs() << "\nJIT: Invalidated Stub at [" << Stub << "]\n"); |
| 1161 StubFnRefs.erase(Stub); | 1222 StubFnRefs.erase(Stub); |
| 1162 | 1223 |
| 1163 // Invalidate the stub. If it is a GV stub, update the JIT's global | 1224 // Invalidate the stub. If it is a GV stub, update the JIT's global |
| 1164 // mapping for that GV to zero, otherwise, search the string map of | 1225 // mapping for that GV to zero, otherwise, search the string map of |
| 1165 // external function names to stubs and remove the entry for this stub. | 1226 // external function names to stubs and remove the entry for this stub. |
| 1166 GlobalValue *GV = Resolver.invalidateStub(Stub); | 1227 GlobalValue *GV = Resolver.invalidateStub(Stub); |
| 1167 if (GV) { | 1228 if (GV) { |
| 1168 TheJIT->updateGlobalMapping(GV, 0); | 1229 TheJIT->updateGlobalMapping(GV, 0); |
| 1169 } else { | 1230 } else { |
| 1170 for (StringMapIterator<void*> i = ExtFnStubs.begin(), | 1231 for (StringMapIterator<void*> i = ExtFnStubs.begin(), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1186 return JITCodeEmitter::allocateSpace(Size, Alignment); | 1247 return JITCodeEmitter::allocateSpace(Size, Alignment); |
| 1187 | 1248 |
| 1188 // create a new memory block if there is no active one. | 1249 // create a new memory block if there is no active one. |
| 1189 // care must be taken so that BufferBegin is invalidated when a | 1250 // care must be taken so that BufferBegin is invalidated when a |
| 1190 // block is trimmed | 1251 // block is trimmed |
| 1191 BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment); | 1252 BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment); |
| 1192 BufferEnd = BufferBegin+Size; | 1253 BufferEnd = BufferBegin+Size; |
| 1193 return CurBufferPtr; | 1254 return CurBufferPtr; |
| 1194 } | 1255 } |
| 1195 | 1256 |
| 1257 void* JITEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) { |
| 1258 // Delegate this call through the memory manager. |
| 1259 return MemMgr->allocateGlobal(Size, Alignment); |
| 1260 } |
| 1261 |
| 1196 void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { | 1262 void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { |
| 1197 if (TheJIT->getJITInfo().hasCustomConstantPool()) | 1263 if (TheJIT->getJITInfo().hasCustomConstantPool()) |
| 1198 return; | 1264 return; |
| 1199 | 1265 |
| 1200 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); | 1266 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); |
| 1201 if (Constants.empty()) return; | 1267 if (Constants.empty()) return; |
| 1202 | 1268 |
| 1203 unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); | 1269 unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); |
| 1204 unsigned Align = MCP->getConstantPoolAlignment(); | 1270 unsigned Align = MCP->getConstantPoolAlignment(); |
| 1205 ConstantPoolBase = allocateSpace(Size, Align); | 1271 ConstantPoolBase = allocateSpace(Size, Align); |
| 1206 ConstantPool = MCP; | 1272 ConstantPool = MCP; |
| 1207 | 1273 |
| 1208 if (ConstantPoolBase == 0) return; // Buffer overflow. | 1274 if (ConstantPoolBase == 0) return; // Buffer overflow. |
| 1209 | 1275 |
| 1210 DOUT << "JIT: Emitted constant pool at [" << ConstantPoolBase | 1276 DEBUG(errs() << "JIT: Emitted constant pool at [" << ConstantPoolBase |
| 1211 << "] (size: " << Size << ", alignment: " << Align << ")\n"; | 1277 << "] (size: " << Size << ", alignment: " << Align << ")\n"); |
| 1212 | 1278 |
| 1213 // Initialize the memory for all of the constant pool entries. | 1279 // Initialize the memory for all of the constant pool entries. |
| 1214 unsigned Offset = 0; | 1280 unsigned Offset = 0; |
| 1215 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { | 1281 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { |
| 1216 MachineConstantPoolEntry CPE = Constants[i]; | 1282 MachineConstantPoolEntry CPE = Constants[i]; |
| 1217 unsigned AlignMask = CPE.getAlignment() - 1; | 1283 unsigned AlignMask = CPE.getAlignment() - 1; |
| 1218 Offset = (Offset + AlignMask) & ~AlignMask; | 1284 Offset = (Offset + AlignMask) & ~AlignMask; |
| 1219 | 1285 |
| 1220 uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; | 1286 uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; |
| 1221 ConstPoolAddresses.push_back(CAddr); | 1287 ConstPoolAddresses.push_back(CAddr); |
| 1222 if (CPE.isMachineConstantPoolEntry()) { | 1288 if (CPE.isMachineConstantPoolEntry()) { |
| 1223 // FIXME: add support to lower machine constant pool values into bytes! | 1289 // FIXME: add support to lower machine constant pool values into bytes! |
| 1224 cerr << "Initialize memory with machine specific constant pool entry" | 1290 llvm_report_error("Initialize memory with machine specific constant pool" |
| 1225 << " has not been implemented!\n"; | 1291 "entry has not been implemented!"); |
| 1226 abort(); | |
| 1227 } | 1292 } |
| 1228 TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); | 1293 TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); |
| 1229 DOUT << "JIT: CP" << i << " at [0x" | 1294 DEBUG(errs() << "JIT: CP" << i << " at [0x"; |
| 1230 << std::hex << CAddr << std::dec << "]\n"; | 1295 errs().write_hex(CAddr) << "]\n"); |
| 1231 | 1296 |
| 1232 const Type *Ty = CPE.Val.ConstVal->getType(); | 1297 const Type *Ty = CPE.Val.ConstVal->getType(); |
| 1233 Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); | 1298 Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); |
| 1234 } | 1299 } |
| 1235 } | 1300 } |
| 1236 | 1301 |
| 1237 void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { | 1302 void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { |
| 1238 if (TheJIT->getJITInfo().hasCustomJumpTables()) | 1303 if (TheJIT->getJITInfo().hasCustomJumpTables()) |
| 1239 return; | 1304 return; |
| 1240 | 1305 |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 void *CurTable = JE->getMemMgr()->getDlsymTable(); | 1487 void *CurTable = JE->getMemMgr()->getDlsymTable(); |
| 1423 if (CurTable && (*(unsigned *)CurTable == nStubs)) | 1488 if (CurTable && (*(unsigned *)CurTable == nStubs)) |
| 1424 return; | 1489 return; |
| 1425 | 1490 |
| 1426 // Calculate the size of the stub info | 1491 // Calculate the size of the stub info |
| 1427 unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs; | 1492 unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs; |
| 1428 | 1493 |
| 1429 SmallVector<unsigned, 8> Offsets; | 1494 SmallVector<unsigned, 8> Offsets; |
| 1430 for (unsigned i = 0; i != GVs.size(); ++i) { | 1495 for (unsigned i = 0; i != GVs.size(); ++i) { |
| 1431 Offsets.push_back(offset); | 1496 Offsets.push_back(offset); |
| 1432 offset += GVs[i]->getName().length() + 1; | 1497 offset += GVs[i]->getName().size() + 1; |
| 1433 } | 1498 } |
| 1434 for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end(); | 1499 for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end(); |
| 1435 i != e; ++i) { | 1500 i != e; ++i) { |
| 1436 Offsets.push_back(offset); | 1501 Offsets.push_back(offset); |
| 1437 offset += strlen(i->first()) + 1; | 1502 offset += strlen(i->first()) + 1; |
| 1438 } | 1503 } |
| 1439 | 1504 |
| 1440 // Allocate space for the new "stub", which contains the dlsym table. | 1505 // Allocate space for the new "stub", which contains the dlsym table. |
| 1441 JE->startGVStub(0, offset, 4); | 1506 JE->startGVStub(0, offset, 4); |
| 1442 | 1507 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 // retranslated next time it is used. | 1558 // retranslated next time it is used. |
| 1494 void *OldPtr = updateGlobalMapping(F, 0); | 1559 void *OldPtr = updateGlobalMapping(F, 0); |
| 1495 | 1560 |
| 1496 if (OldPtr) | 1561 if (OldPtr) |
| 1497 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); | 1562 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); |
| 1498 | 1563 |
| 1499 // Free the actual memory for the function body and related stuff. | 1564 // Free the actual memory for the function body and related stuff. |
| 1500 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); | 1565 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); |
| 1501 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); | 1566 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); |
| 1502 } | 1567 } |
| LEFT | RIGHT |