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

Delta Between Two Patch Sets: lib/ExecutionEngine/JIT/JITEmitter.cpp

Issue 91042: Implement LLVM JIT side of GDB JIT debugging interface (Closed) SVN Base: http://llvm.org/svn/llvm-project/llvm/trunk/
Left Patch Set: Move the object files off disk and into memory. Created 3 months, 2 weeks ago
Right Patch Set: Synced with TOT. Created 2 months, 2 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 /// getExternalFunctionStub - Return a stub for the function at the 264 /// getExternalFunctionStub - Return a stub for the function at the
265 /// specified address, created lazily on demand. 265 /// specified address, created lazily on demand.
266 void *JITResolver::getExternalFunctionStub(void *FnAddr) { 266 void *JITResolver::getExternalFunctionStub(void *FnAddr) {
267 // If we already have a stub for this function, recycle it. 267 // If we already have a stub for this function, recycle it.
268 void *&Stub = ExternalFnToStubMap[FnAddr]; 268 void *&Stub = ExternalFnToStubMap[FnAddr];
269 if (Stub) return Stub; 269 if (Stub) return Stub;
270 270
271 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, 271 Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr,
272 *TheJIT->getCodeEmitter()); 272 *TheJIT->getCodeEmitter());
273 273
274 DOUT << "JIT: Stub emitted at [" << Stub 274 DEBUG(errs() << "JIT: Stub emitted at [" << Stub
275 << "] for external function at '" << FnAddr << "'\n"; 275 << "] for external function at '" << FnAddr << "'\n");
276 return Stub; 276 return Stub;
277 } 277 }
278 278
279 unsigned JITResolver::getGOTIndexForAddr(void* addr) { 279 unsigned JITResolver::getGOTIndexForAddr(void* addr) {
280 unsigned idx = revGOTMap[addr]; 280 unsigned idx = revGOTMap[addr];
281 if (!idx) { 281 if (!idx) {
282 idx = ++nextGOTIndex; 282 idx = ++nextGOTIndex;
283 revGOTMap[addr] = idx; 283 revGOTMap[addr] = idx;
284 DOUT << "JIT: Adding GOT entry " << idx << " for addr [" << addr << "]\n"; 284 DEBUG(errs() << "JIT: Adding GOT entry " << idx << " for addr ["
285 << addr << "]\n");
285 } 286 }
286 return idx; 287 return idx;
287 } 288 }
288 289
289 void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs, 290 void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
290 SmallVectorImpl<void*> &Ptrs) { 291 SmallVectorImpl<void*> &Ptrs) {
291 MutexGuard locked(TheJIT->lock); 292 MutexGuard locked(TheJIT->lock);
292 293
293 FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked); 294 FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked);
294 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked); 295 GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; 503 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
503 504
504 // 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
505 // in the JITResolver's ExternalFnToStubMap. 506 // in the JITResolver's ExternalFnToStubMap.
506 StringMap<void *> ExtFnStubs; 507 StringMap<void *> ExtFnStubs;
507 508
508 DebugLocTuple PrevDLT; 509 DebugLocTuple PrevDLT;
509 510
510 public: 511 public:
511 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) 512 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
512 : SizeEstimate(0), Resolver(jit), CurFn(0) { 513 : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0) {
513 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 514 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
514 if (jit.getJITInfo().needsGOT()) { 515 if (jit.getJITInfo().needsGOT()) {
515 MemMgr->AllocateGOT(); 516 MemMgr->AllocateGOT();
516 DOUT << "JIT is managing a GOT\n"; 517 DEBUG(errs() << "JIT is managing a GOT\n");
517 } 518 }
518 519
519 if (DwarfExceptionHandling || JITEmitDebugInfo) { 520 if (DwarfExceptionHandling || JITEmitDebugInfo) {
520 DE.reset(new JITDwarfEmitter(jit)); 521 DE.reset(new JITDwarfEmitter(jit));
521 } 522 }
522 if (JITEmitDebugInfo) { 523 if (JITEmitDebugInfo) {
523 DR.reset(new JITDebugRegisterer(TM)); 524 DR.reset(new JITDebugRegisterer(TM));
524 } 525 }
525 } 526 }
526 ~JITEmitter() { 527 ~JITEmitter() {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment); 559 virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment);
559 560
560 virtual void addRelocation(const MachineRelocation &MR) { 561 virtual void addRelocation(const MachineRelocation &MR) {
561 Relocations.push_back(MR); 562 Relocations.push_back(MR);
562 } 563 }
563 564
564 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { 565 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
565 if (MBBLocations.size() <= (unsigned)MBB->getNumber()) 566 if (MBBLocations.size() <= (unsigned)MBB->getNumber())
566 MBBLocations.resize((MBB->getNumber()+1)*2); 567 MBBLocations.resize((MBB->getNumber()+1)*2);
567 MBBLocations[MBB->getNumber()] = getCurrentPCValue(); 568 MBBLocations[MBB->getNumber()] = getCurrentPCValue();
568 DOUT << "JIT: Emitting BB" << MBB->getNumber() << " at [" 569 DEBUG(errs() << "JIT: Emitting BB" << MBB->getNumber() << " at ["
569 << (void*) getCurrentPCValue() << "]\n"; 570 << (void*) getCurrentPCValue() << "]\n");
570 } 571 }
571 572
572 virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; 573 virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const;
573 virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; 574 virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const;
574 575
575 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { 576 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
576 assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 577 assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
577 MBBLocations[MBB->getNumber()] && "MBB not emitted!"); 578 MBBLocations[MBB->getNumber()] && "MBB not emitted!");
578 return MBBLocations[MBB->getNumber()]; 579 return MBBLocations[MBB->getNumber()];
579 } 580 }
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } 759 }
759 760
760 /// addSizeOfGlobal - add the size of the global (plus any alignment padding) 761 /// addSizeOfGlobal - add the size of the global (plus any alignment padding)
761 /// into the running total Size. 762 /// into the running total Size.
762 763
763 unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) { 764 unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) {
764 const Type *ElTy = GV->getType()->getElementType(); 765 const Type *ElTy = GV->getType()->getElementType();
765 size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy); 766 size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy);
766 size_t GVAlign = 767 size_t GVAlign =
767 (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); 768 (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV);
768 DOUT << "JIT: Adding in size " << GVSize << " alignment " << GVAlign; 769 DEBUG(errs() << "JIT: Adding in size " << GVSize << " alignment " << GVAlign);
769 DEBUG(GV->dump()); 770 DEBUG(GV->dump());
770 // Assume code section ends with worst possible alignment, so first 771 // Assume code section ends with worst possible alignment, so first
771 // variable needs maximal padding. 772 // variable needs maximal padding.
772 if (Size==0) 773 if (Size==0)
773 Size = 1; 774 Size = 1;
774 Size = ((Size+GVAlign-1)/GVAlign)*GVAlign; 775 Size = ((Size+GVAlign-1)/GVAlign)*GVAlign;
775 Size += GVSize; 776 Size += GVSize;
776 return Size; 777 return Size;
777 } 778 }
778 779
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 // assuming the addresses of the new globals in this module 887 // assuming the addresses of the new globals in this module
887 // start at 0 (or something) and adjusting them after codegen 888 // start at 0 (or something) and adjusting them after codegen
888 // complete. Another possibility is to grab a marker bit in GV. 889 // complete. Another possibility is to grab a marker bit in GV.
889 if (GVSet.insert(GV)) 890 if (GVSet.insert(GV))
890 // A variable as yet unseen. Add in its size. 891 // A variable as yet unseen. Add in its size.
891 Size = addSizeOfGlobal(GV, Size); 892 Size = addSizeOfGlobal(GV, Size);
892 } 893 }
893 } 894 }
894 } 895 }
895 } 896 }
896 DOUT << "JIT: About to look through initializers\n"; 897 DEBUG(errs() << "JIT: About to look through initializers\n");
897 // Look for more globals that are referenced only from initializers. 898 // Look for more globals that are referenced only from initializers.
898 // 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.
899 for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin(); 900 for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin();
900 I != GVSet.end(); I++) { 901 I != GVSet.end(); I++) {
901 const GlobalVariable* GV = *I; 902 const GlobalVariable* GV = *I;
902 if (GV->hasInitializer()) 903 if (GV->hasInitializer())
903 Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size); 904 Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size);
904 } 905 }
905 906
906 return Size; 907 return Size;
907 } 908 }
908 909
909 void JITEmitter::startFunction(MachineFunction &F) { 910 void JITEmitter::startFunction(MachineFunction &F) {
910 DEBUG(errs() << "JIT: Starting CodeGen of Function " 911 DEBUG(errs() << "JIT: Starting CodeGen of Function "
911 << F.getFunction()->getName() << "\n"); 912 << F.getFunction()->getName() << "\n");
912 913
913 uintptr_t ActualSize = 0; 914 uintptr_t ActualSize = 0;
914 // Set the memory writable, if it's not already 915 // Set the memory writable, if it's not already
915 MemMgr->setMemoryWritable(); 916 MemMgr->setMemoryWritable();
916 if (MemMgr->NeedsExactSize()) { 917 if (MemMgr->NeedsExactSize()) {
917 DOUT << "JIT: ExactSize\n"; 918 DEBUG(errs() << "JIT: ExactSize\n");
918 const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); 919 const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
919 MachineJumpTableInfo *MJTI = F.getJumpTableInfo(); 920 MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
920 MachineConstantPool *MCP = F.getConstantPool(); 921 MachineConstantPool *MCP = F.getConstantPool();
921 922
922 // 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.
923 ActualSize = RoundUpToAlign(ActualSize, 16); 924 ActualSize = RoundUpToAlign(ActualSize, 16);
924 925
925 // Add the alignment of the constant pool 926 // Add the alignment of the constant pool
926 ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment()); 927 ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment());
927 928
928 // Add the constant pool size 929 // Add the constant pool size
929 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); 930 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
930 931
931 // Add the aligment of the jump table info 932 // Add the aligment of the jump table info
932 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); 933 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment());
933 934
934 // Add the jump table size 935 // Add the jump table size
935 ActualSize += GetJumpTableSizeInBytes(MJTI); 936 ActualSize += GetJumpTableSizeInBytes(MJTI);
936 937
937 // Add the alignment for the function 938 // Add the alignment for the function
938 ActualSize = RoundUpToAlign(ActualSize, 939 ActualSize = RoundUpToAlign(ActualSize,
939 std::max(F.getFunction()->getAlignment(), 8U)); 940 std::max(F.getFunction()->getAlignment(), 8U));
940 941
941 // Add the function size 942 // Add the function size
942 ActualSize += TII->GetFunctionSizeInBytes(F); 943 ActualSize += TII->GetFunctionSizeInBytes(F);
943 944
944 DOUT << "JIT: ActualSize before globals " << ActualSize << "\n"; 945 DEBUG(errs() << "JIT: ActualSize before globals " << ActualSize << "\n");
945 // 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.
946 // 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
947 // previously allocated. 948 // previously allocated.
948 ActualSize += GetSizeOfGlobalsInBytes(F); 949 ActualSize += GetSizeOfGlobalsInBytes(F);
949 DOUT << "JIT: ActualSize after globals " << ActualSize << "\n"; 950 DEBUG(errs() << "JIT: ActualSize after globals " << ActualSize << "\n");
950 } else if (SizeEstimate > 0) { 951 } else if (SizeEstimate > 0) {
951 // SizeEstimate will be non-zero on reallocation attempts. 952 // SizeEstimate will be non-zero on reallocation attempts.
952 ActualSize = SizeEstimate; 953 ActualSize = SizeEstimate;
953 } 954 }
954 955
955 BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), 956 BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
956 ActualSize); 957 ActualSize);
957 BufferEnd = BufferBegin+ActualSize; 958 BufferEnd = BufferBegin+ActualSize;
958 959
959 // 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.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 NumRelos += Relocations.size(); 997 NumRelos += Relocations.size();
997 998
998 // Resolve the relocations to concrete pointers. 999 // Resolve the relocations to concrete pointers.
999 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { 1000 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
1000 MachineRelocation &MR = Relocations[i]; 1001 MachineRelocation &MR = Relocations[i];
1001 void *ResultPtr = 0; 1002 void *ResultPtr = 0;
1002 if (!MR.letTargetResolve()) { 1003 if (!MR.letTargetResolve()) {
1003 if (MR.isExternalSymbol()) { 1004 if (MR.isExternalSymbol()) {
1004 ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(), 1005 ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(),
1005 false); 1006 false);
1006 DOUT << "JIT: Map \'" << MR.getExternalSymbol() << "\' to [" 1007 DEBUG(errs() << "JIT: Map \'" << MR.getExternalSymbol() << "\' to ["
1007 << ResultPtr << "]\n"; 1008 << ResultPtr << "]\n");
1008 1009
1009 // 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.
1010 if (!MR.doesntNeedStub()) { 1011 if (!MR.doesntNeedStub()) {
1011 if (!TheJIT->areDlsymStubsEnabled()) { 1012 if (!TheJIT->areDlsymStubsEnabled()) {
1012 ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); 1013 ResultPtr = Resolver.getExternalFunctionStub(ResultPtr);
1013 } else { 1014 } else {
1014 void *&Stub = ExtFnStubs[MR.getExternalSymbol()]; 1015 void *&Stub = ExtFnStubs[MR.getExternalSymbol()];
1015 if (!Stub) { 1016 if (!Stub) {
1016 Stub = Resolver.getExternalFunctionStub((void *)&Stub); 1017 Stub = Resolver.getExternalFunctionStub((void *)&Stub);
1017 AddStubToCurrentFunction(Stub); 1018 AddStubToCurrentFunction(Stub);
(...skipping 20 matching lines...) Expand all
1038 1039
1039 MR.setResultPointer(ResultPtr); 1040 MR.setResultPointer(ResultPtr);
1040 } 1041 }
1041 1042
1042 // 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,
1043 // give it one 1044 // give it one
1044 if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { 1045 if (MR.isGOTRelative() && MemMgr->isManagingGOT()) {
1045 unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); 1046 unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr);
1046 MR.setGOTIndex(idx); 1047 MR.setGOTIndex(idx);
1047 if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { 1048 if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) {
1048 DOUT << "JIT: GOT was out of date for " << ResultPtr 1049 DEBUG(errs() << "JIT: GOT was out of date for " << ResultPtr
1049 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 1050 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx]
1050 << "\n"; 1051 << "\n");
1051 ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; 1052 ((void**)MemMgr->getGOTBase())[idx] = ResultPtr;
1052 } 1053 }
1053 } 1054 }
1054 } 1055 }
1055 1056
1056 CurFn = 0; 1057 CurFn = 0;
1057 TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], 1058 TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0],
1058 Relocations.size(), MemMgr->getGOTBase()); 1059 Relocations.size(), MemMgr->getGOTBase());
1059 } 1060 }
1060 1061
1061 // 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.
1062 if (MemMgr->isManagingGOT()) { 1063 if (MemMgr->isManagingGOT()) {
1063 unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); 1064 unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin);
1064 if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { 1065 if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) {
1065 DOUT << "JIT: GOT was out of date for " << (void*)BufferBegin 1066 DEBUG(errs() << "JIT: GOT was out of date for " << (void*)BufferBegin
1066 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n"; 1067 << " pointing at " << ((void**)MemMgr->getGOTBase())[idx]
1068 << "\n");
1067 ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; 1069 ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin;
1068 } 1070 }
1069 } 1071 }
1070 1072
1071 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for 1073 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
1072 // global variables that were referenced in the relocations. 1074 // global variables that were referenced in the relocations.
1073 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); 1075 MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
1074 1076
1075 if (CurBufferPtr == BufferEnd) { 1077 if (CurBufferPtr == BufferEnd) {
1076 retryWithMoreMemory(F); 1078 retryWithMoreMemory(F);
(...skipping 17 matching lines...) Expand all
1094 << "] Function: " << F.getFunction()->getName() 1096 << "] Function: " << F.getFunction()->getName()
1095 << ": " << (FnEnd-FnStart) << " bytes of text, " 1097 << ": " << (FnEnd-FnStart) << " bytes of text, "
1096 << Relocations.size() << " relocations\n"); 1098 << Relocations.size() << " relocations\n");
1097 1099
1098 Relocations.clear(); 1100 Relocations.clear();
1099 ConstPoolAddresses.clear(); 1101 ConstPoolAddresses.clear();
1100 1102
1101 // 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.
1102 MemMgr->setMemoryExecutable(); 1104 MemMgr->setMemoryExecutable();
1103 1105
1104 #ifndef NDEBUG 1106 DEBUG(
1105 {
1106 if (sys::hasDisassembler()) { 1107 if (sys::hasDisassembler()) {
1107 DOUT << "JIT: Disassembled code:\n"; 1108 errs() << "JIT: Disassembled code:\n";
1108 DOUT << sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart) ; 1109 errs() << sys::disassembleBuffer(FnStart, FnEnd-FnStart,
1110 (uintptr_t)FnStart);
1109 } else { 1111 } else {
1110 DOUT << "JIT: Binary code:\n"; 1112 errs() << "JIT: Binary code:\n";
1111 DOUT << std::hex;
1112 uint8_t* q = FnStart; 1113 uint8_t* q = FnStart;
1113 for (int i = 0; q < FnEnd; q += 4, ++i) { 1114 for (int i = 0; q < FnEnd; q += 4, ++i) {
1114 if (i == 4) 1115 if (i == 4)
1115 i = 0; 1116 i = 0;
1116 if (i == 0) 1117 if (i == 0)
1117 DOUT << "JIT: " << std::setw(8) << std::setfill('0') 1118 errs() << "JIT: " << (long)(q - FnStart) << ": ";
1118 << (long)(q - FnStart) << ": ";
1119 bool Done = false; 1119 bool Done = false;
1120 for (int j = 3; j >= 0; --j) { 1120 for (int j = 3; j >= 0; --j) {
1121 if (q + j >= FnEnd) 1121 if (q + j >= FnEnd)
1122 Done = true; 1122 Done = true;
1123 else 1123 else
1124 DOUT << std::setw(2) << std::setfill('0') << (unsigned short)q[j]; 1124 errs() << (unsigned short)q[j];
1125 } 1125 }
1126 if (Done) 1126 if (Done)
1127 break; 1127 break;
1128 DOUT << ' '; 1128 errs() << ' ';
1129 if (i == 3) 1129 if (i == 3)
1130 DOUT << '\n'; 1130 errs() << '\n';
1131 } 1131 }
1132 DOUT << std::dec; 1132 errs()<< '\n';
1133 DOUT<< '\n'; 1133 }
1134 } 1134 );
1135 } 1135
1136 #endif
1137 if (DwarfExceptionHandling || JITEmitDebugInfo) { 1136 if (DwarfExceptionHandling || JITEmitDebugInfo) {
1138 uintptr_t ActualSize = 0; 1137 uintptr_t ActualSize = 0;
1139 SavedBufferBegin = BufferBegin; 1138 SavedBufferBegin = BufferBegin;
1140 SavedBufferEnd = BufferEnd; 1139 SavedBufferEnd = BufferEnd;
1141 SavedCurBufferPtr = CurBufferPtr; 1140 SavedCurBufferPtr = CurBufferPtr;
1142 1141
1143 if (MemMgr->NeedsExactSize()) { 1142 if (MemMgr->NeedsExactSize()) {
1144 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); 1143 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
1145 } 1144 }
1146 1145
1147 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 1146 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
1148 ActualSize); 1147 ActualSize);
1149 BufferEnd = BufferBegin+ActualSize; 1148 BufferEnd = BufferBegin+ActualSize;
1150 uint8_t* EhStart; 1149 uint8_t *EhStart;
1151 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, 1150 uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd,
1152 EhStart); 1151 EhStart);
1153 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 1152 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
1154 FrameRegister); 1153 FrameRegister);
1155 uint8_t* EhEnd = CurBufferPtr; 1154 uint8_t *EhEnd = CurBufferPtr;
1156 BufferBegin = SavedBufferBegin; 1155 BufferBegin = SavedBufferBegin;
1157 BufferEnd = SavedBufferEnd; 1156 BufferEnd = SavedBufferEnd;
1158 CurBufferPtr = SavedCurBufferPtr; 1157 CurBufferPtr = SavedCurBufferPtr;
1159 1158
1160 if (DwarfExceptionHandling) { 1159 if (DwarfExceptionHandling) {
1161 TheJIT->RegisterTable(FrameRegister); 1160 TheJIT->RegisterTable(FrameRegister);
1162 } 1161 }
1163 1162
1164 if (JITEmitDebugInfo) { 1163 if (JITEmitDebugInfo) {
1165 DebugInfo I; 1164 DebugInfo I;
1166 I.FnStart = FnStart; 1165 I.FnStart = FnStart;
1167 I.FnEnd = FnEnd; 1166 I.FnEnd = FnEnd;
1168 I.EhStart = EhStart; 1167 I.EhStart = EhStart;
1169 I.EhEnd = EhEnd; 1168 I.EhEnd = EhEnd;
1170 DR->RegisterFunction(F.getFunction(), I); 1169 DR->RegisterFunction(F.getFunction(), I);
1171 } 1170 }
1172 } 1171 }
1173 1172
1174 if (MMI) 1173 if (MMI)
1175 MMI->EndFunction(); 1174 MMI->EndFunction();
1176 1175
1177 return false; 1176 return false;
1178 } 1177 }
1179 1178
1180 void JITEmitter::retryWithMoreMemory(MachineFunction &F) { 1179 void JITEmitter::retryWithMoreMemory(MachineFunction &F) {
1181 DOUT << "JIT: Ran out of space for native code. Reattempting.\n"; 1180 DEBUG(errs() << "JIT: Ran out of space for native code. Reattempting.\n");
1182 Relocations.clear(); // Clear the old relocations or we'll reapply them. 1181 Relocations.clear(); // Clear the old relocations or we'll reapply them.
1183 ConstPoolAddresses.clear(); 1182 ConstPoolAddresses.clear();
1184 ++NumRetries; 1183 ++NumRetries;
1185 deallocateMemForFunction(F.getFunction()); 1184 deallocateMemForFunction(F.getFunction());
1186 // Try again with at least twice as much free space. 1185 // Try again with at least twice as much free space.
1187 SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin)); 1186 SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin));
1188 } 1187 }
1189 1188
1190 /// deallocateMemForFunction - Deallocate all memory for the specified 1189 /// deallocateMemForFunction - Deallocate all memory for the specified
1191 /// function body. Also drop any references the function has to stubs. 1190 /// function body. Also drop any references the function has to stubs.
(...skipping 20 matching lines...) Expand all
1212 if (StubFnRefs.count(Stub) == 0) 1211 if (StubFnRefs.count(Stub) == 0)
1213 continue; 1212 continue;
1214 1213
1215 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub]; 1214 SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub];
1216 FnRefs.erase(F); 1215 FnRefs.erase(F);
1217 1216
1218 // 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
1219 // in the JITResolver. Were there a memory manager deallocateStub routine, 1218 // in the JITResolver. Were there a memory manager deallocateStub routine,
1220 // we could call that at this point too. 1219 // we could call that at this point too.
1221 if (FnRefs.empty()) { 1220 if (FnRefs.empty()) {
1222 DOUT << "\nJIT: Invalidated Stub at [" << Stub << "]\n"; 1221 DEBUG(errs() << "\nJIT: Invalidated Stub at [" << Stub << "]\n");
1223 StubFnRefs.erase(Stub); 1222 StubFnRefs.erase(Stub);
1224 1223
1225 // 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
1226 // 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
1227 // 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.
1228 GlobalValue *GV = Resolver.invalidateStub(Stub); 1227 GlobalValue *GV = Resolver.invalidateStub(Stub);
1229 if (GV) { 1228 if (GV) {
1230 TheJIT->updateGlobalMapping(GV, 0); 1229 TheJIT->updateGlobalMapping(GV, 0);
1231 } else { 1230 } else {
1232 for (StringMapIterator<void*> i = ExtFnStubs.begin(), 1231 for (StringMapIterator<void*> i = ExtFnStubs.begin(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 1266 const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
1268 if (Constants.empty()) return; 1267 if (Constants.empty()) return;
1269 1268
1270 unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); 1269 unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
1271 unsigned Align = MCP->getConstantPoolAlignment(); 1270 unsigned Align = MCP->getConstantPoolAlignment();
1272 ConstantPoolBase = allocateSpace(Size, Align); 1271 ConstantPoolBase = allocateSpace(Size, Align);
1273 ConstantPool = MCP; 1272 ConstantPool = MCP;
1274 1273
1275 if (ConstantPoolBase == 0) return; // Buffer overflow. 1274 if (ConstantPoolBase == 0) return; // Buffer overflow.
1276 1275
1277 DOUT << "JIT: Emitted constant pool at [" << ConstantPoolBase 1276 DEBUG(errs() << "JIT: Emitted constant pool at [" << ConstantPoolBase
1278 << "] (size: " << Size << ", alignment: " << Align << ")\n"; 1277 << "] (size: " << Size << ", alignment: " << Align << ")\n");
1279 1278
1280 // Initialize the memory for all of the constant pool entries. 1279 // Initialize the memory for all of the constant pool entries.
1281 unsigned Offset = 0; 1280 unsigned Offset = 0;
1282 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 1281 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
1283 MachineConstantPoolEntry CPE = Constants[i]; 1282 MachineConstantPoolEntry CPE = Constants[i];
1284 unsigned AlignMask = CPE.getAlignment() - 1; 1283 unsigned AlignMask = CPE.getAlignment() - 1;
1285 Offset = (Offset + AlignMask) & ~AlignMask; 1284 Offset = (Offset + AlignMask) & ~AlignMask;
1286 1285
1287 uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; 1286 uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset;
1288 ConstPoolAddresses.push_back(CAddr); 1287 ConstPoolAddresses.push_back(CAddr);
1289 if (CPE.isMachineConstantPoolEntry()) { 1288 if (CPE.isMachineConstantPoolEntry()) {
1290 // FIXME: add support to lower machine constant pool values into bytes! 1289 // FIXME: add support to lower machine constant pool values into bytes!
1291 llvm_report_error("Initialize memory with machine specific constant pool" 1290 llvm_report_error("Initialize memory with machine specific constant pool"
1292 "entry has not been implemented!"); 1291 "entry has not been implemented!");
1293 } 1292 }
1294 TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); 1293 TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr);
1295 DOUT << "JIT: CP" << i << " at [0x" 1294 DEBUG(errs() << "JIT: CP" << i << " at [0x";
1296 << std::hex << CAddr << std::dec << "]\n"; 1295 errs().write_hex(CAddr) << "]\n");
1297 1296
1298 const Type *Ty = CPE.Val.ConstVal->getType(); 1297 const Type *Ty = CPE.Val.ConstVal->getType();
1299 Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); 1298 Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty);
1300 } 1299 }
1301 } 1300 }
1302 1301
1303 void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { 1302 void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
1304 if (TheJIT->getJITInfo().hasCustomJumpTables()) 1303 if (TheJIT->getJITInfo().hasCustomJumpTables())
1305 return; 1304 return;
1306 1305
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 // retranslated next time it is used. 1558 // retranslated next time it is used.
1560 void *OldPtr = updateGlobalMapping(F, 0); 1559 void *OldPtr = updateGlobalMapping(F, 0);
1561 1560
1562 if (OldPtr) 1561 if (OldPtr)
1563 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); 1562 TheJIT->NotifyFreeingMachineCode(*F, OldPtr);
1564 1563
1565 // Free the actual memory for the function body and related stuff. 1564 // Free the actual memory for the function body and related stuff.
1566 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); 1565 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?");
1567 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); 1566 cast<JITEmitter>(JCE)->deallocateMemForFunction(F);
1568 } 1567 }
LEFTRIGHT

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