[llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JIT.cpp JITEmitter.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Thu Jul 28 05:44:25 PDT 2005



Changes in directory llvm/lib/ExecutionEngine/JIT:

JIT.cpp updated: 1.57 -> 1.58
JITEmitter.cpp updated: 1.72 -> 1.73
---
Log message:

Like constants, globals on some platforms are GOT relative.  This means they have to be allocated
near the GOT, which new doesn't do.  So break out the allocate into a new function.

Also move GOT index handling into JITResolver.  This lets it update the mapping when a Lazy
function is JITed.  It doesn't managed the table, just the mapping.  Note that this is
still non-ideal, as any function that takes a function address should also take a GOT
index, but that is a lot of changes.  The relocation resolve process updates any GOT entry
it sees is out of date.



---
Diffs of the changes:  (+78 -14)

 JIT.cpp        |    3 +
 JITEmitter.cpp |   89 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 78 insertions(+), 14 deletions(-)


Index: llvm/lib/ExecutionEngine/JIT/JIT.cpp
diff -u llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.57 llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.58
--- llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.57	Wed Jul 27 01:12:33 2005
+++ llvm/lib/ExecutionEngine/JIT/JIT.cpp	Thu Jul 28 07:44:13 2005
@@ -294,7 +294,8 @@
     // actually initialize the global after current function has finished
     // compilation.
     uint64_t S = getTargetData().getTypeSize(GV->getType()->getElementType());
-    Ptr = new char[(size_t)S];
+    unsigned char A =  getTargetData().getTypeAlignment(GV->getType()->getElementType());
+    Ptr = MCE->allocateGlobal(S, A);
     state.getPendingGlobals(locked).push_back(GV);
   }
   addGlobalMapping(GV, Ptr);


Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp
diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.72 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.73
--- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.72	Wed Jul 27 01:12:33 2005
+++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp	Thu Jul 28 07:44:13 2005
@@ -60,6 +60,8 @@
     inline unsigned char *allocateStub(unsigned StubSize);
     inline unsigned char *allocateConstant(unsigned ConstantSize,
                                            unsigned Alignment);
+    inline unsigned char* allocateGlobal(unsigned Size, 
+                                         unsigned Alignment);
     inline unsigned char *startFunctionBody();
     inline void endFunctionBody(unsigned char *FunctionEnd);
     inline unsigned char* getGOTBase() const;
@@ -115,6 +117,21 @@
   return CurConstantPtr;
 }
 
+unsigned char *JITMemoryManager::allocateGlobal(unsigned Size,
+                                                unsigned Alignment) {
+  // For now, intersperse them with Constants
+  // Reserve space and align pointer.
+  CurConstantPtr -= Size;
+  CurConstantPtr =
+    (unsigned char *)((intptr_t)CurConstantPtr & ~((intptr_t)Alignment - 1));
+
+  if (CurConstantPtr < ConstantPool) {
+    std::cerr << "JIT ran out of memory for Globals!\n";
+    abort();
+  }
+  return CurConstantPtr;
+}
+
 unsigned char *JITMemoryManager::startFunctionBody() {
   // Round up to an even multiple of 8 bytes, this should eventually be target
   // specific.
@@ -175,8 +192,13 @@
     /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for
     /// external functions.
     std::map<void*, void*> ExternalFnToStubMap;
+
+    //map addresses to indexes in the GOT
+    std::map<void*, unsigned> revGOTMap;
+    unsigned nextGOTIndex;
+
   public:
-    JITResolver(MachineCodeEmitter &mce) : MCE(mce) {
+    JITResolver(MachineCodeEmitter &mce) : MCE(mce), nextGOTIndex(0) {
       LazyResolverFn =
         TheJIT->getJITInfo().getLazyResolverFunction(JITCompilerFn);
     }
@@ -199,6 +221,11 @@
       return (void*)LazyResolverFn;
     }
 
+    /// getGOTIndexForAddress - Return a new or existing index in the GOT for
+    /// and address.  This function only manages slots, it does not manage the
+    /// contents of the slots or the memory associated with the GOT.
+    unsigned getGOTIndexForAddr(void* addr);
+
     /// JITCompilerFn - This function is called to resolve a stub to a compiled
     /// address.  If the LLVM Function corresponding to the stub has not yet
     /// been compiled, this function compiles it first.
@@ -261,6 +288,17 @@
   return Stub;
 }
 
+unsigned JITResolver::getGOTIndexForAddr(void* addr) {
+  unsigned idx = revGOTMap[addr];
+  if (!idx) {
+    idx = ++nextGOTIndex;
+    revGOTMap[addr] = idx;
+    DEBUG(std::cerr << "Adding GOT entry " << idx
+          << " for addr " << addr << "\n");
+    //    ((void**)MemMgr.getGOTBase())[idx] = addr;
+  }
+  return idx;
+}
 
 /// JITCompilerFn - This function is called when a lazy compilation stub has
 /// been entered.  It looks up which function this stub corresponds to, compiles
@@ -294,6 +332,15 @@
   JR.state.getFunctionToStubMap(locked).erase(F);
 
   // FIXME: We could rewrite all references to this stub if we knew them.
+
+  // What we will do is set the compiled function address to map to the 
+  // same GOT entry as the stub so that later clients may update the GOT 
+  // if they see it still using the stub address.
+  // Note: this is done so the Resolver doesn't have to manage GOT memory
+  // Do this without allocating map space if the target isn't using a GOT
+  if(JR.revGOTMap.find(Stub) != JR.revGOTMap.end())
+    JR.revGOTMap[Result] = JR.revGOTMap[Stub];
+
   return Result;
 }
 
@@ -340,8 +387,7 @@
 
   public:
     JITEmitter(JIT &jit)
-      :MemMgr(jit.getJITInfo().needsGOT()),
-       nextGOTIndex(0)
+      :MemMgr(jit.getJITInfo().needsGOT())
     {
       TheJIT = &jit;
       DEBUG(std::cerr <<
@@ -365,11 +411,10 @@
     virtual uint64_t getCurrentPCValue();
     virtual uint64_t getCurrentPCOffset();
     virtual uint64_t getConstantPoolEntryAddress(unsigned Entry);
+    virtual unsigned char* allocateGlobal(unsigned size, unsigned alignment);
 
   private:
     void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
-    unsigned nextGOTIndex;
-    std::map<void*, unsigned> revGOTMap;
   };
 }
 
@@ -441,14 +486,17 @@
 
       MR.setResultPointer(ResultPtr);
 
-      // if we are managing the got, check to see if this pointer has all ready
-      // been allocated a GOT entry.  If not, give it the next one.
-      if (MemMgr.isManagingGOT()) {
-        if (!revGOTMap[ResultPtr])
-          revGOTMap[ResultPtr] = ++nextGOTIndex;
-        ((void**)MemMgr.getGOTBase())[revGOTMap[ResultPtr]] = ResultPtr;
-        if(MR.isGOTRelative())
-          MR.setGOTIndex(revGOTMap[ResultPtr]);
+      // if we are managing the GOT and the relocation wants an index,
+      // give it one
+      if (MemMgr.isManagingGOT() && !MR.isConstantPoolIndex() &&
+          MR.isGOTRelative()) {
+        unsigned idx = getJITResolver(this).getGOTIndexForAddr(ResultPtr);
+        MR.setGOTIndex(idx);
+        if (((void**)MemMgr.getGOTBase())[idx] != ResultPtr) {
+          DEBUG(std::cerr << "GOT was out of date for " << ResultPtr
+                << " pointing at " << ((void**)MemMgr.getGOTBase())[idx] << "\n");
+          ((void**)MemMgr.getGOTBase())[idx] = ResultPtr;
+        }
       }
     }
 
@@ -456,6 +504,16 @@
                                   Relocations.size(), MemMgr.getGOTBase());
   }
 
+  //Update the GOT entry for F to point to the new code.
+  if(MemMgr.isManagingGOT()) {
+    unsigned idx = getJITResolver(this).getGOTIndexForAddr((void*)CurBlock);
+    if (((void**)MemMgr.getGOTBase())[idx] != (void*)CurBlock) {
+      DEBUG(std::cerr << "GOT was out of date for " << (void*)CurBlock 
+            << " pointing at " << ((void**)MemMgr.getGOTBase())[idx] << "\n");
+      ((void**)MemMgr.getGOTBase())[idx] = (void*)CurBlock;
+    }
+  }
+
   DEBUG(std::cerr << "JIT: Finished CodeGen of [" << (void*)CurBlock
                   << "] Function: " << F.getFunction()->getName()
                   << ": " << CurByte-CurBlock << " bytes of text, "
@@ -516,6 +574,11 @@
   return (intptr_t)ConstantPoolAddresses[ConstantNum];
 }
 
+unsigned char* JITEmitter::allocateGlobal(unsigned size, unsigned alignment)
+{
+  return MemMgr.allocateGlobal(size, alignment);
+}
+
 // getCurrentPCValue - This returns the address that the next emitted byte
 // will be output to.
 //






More information about the llvm-commits mailing list