[llvm-commits] [llvm] r66648 - /llvm/branches/Apple/Dib/lib/ExecutionEngine/JIT/JITEmitter.cpp

Bill Wendling isanbard at gmail.com
Wed Mar 11 00:14:15 PDT 2009


Author: void
Date: Wed Mar 11 02:14:14 2009
New Revision: 66648

URL: http://llvm.org/viewvc/llvm-project?rev=66648&view=rev
Log:
Merge r66646 into Dib:

Allow cross-process JIT to handle MachineRelocations of the ExternalSymbol
variety.  For example, an i64 div might turn into a call to __divdi3 during
legalization.

Modified:
    llvm/branches/Apple/Dib/lib/ExecutionEngine/JIT/JITEmitter.cpp

Modified: llvm/branches/Apple/Dib/lib/ExecutionEngine/JIT/JITEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=66648&r1=66647&r2=66648&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
+++ llvm/branches/Apple/Dib/lib/ExecutionEngine/JIT/JITEmitter.cpp Wed Mar 11 02:14:14 2009
@@ -309,7 +309,7 @@
     return F;
   }
   
-  // Otherwise, it must be an indirect symbol stub.  Find it and remove it.
+  // Otherwise, it might be an indirect symbol stub.  Find it and remove it.
   for (std::map<GlobalValue*,void*>::iterator i = GM.begin(), e = GM.end();
        i != e; ++i) {
     if (i->second != Stub)
@@ -319,6 +319,15 @@
     return GV;
   }
   
+  // Lastly, check to see if it's in the ExternalFnToStubMap.
+  for (std::map<void *, void *>::iterator i = ExternalFnToStubMap.begin(),
+       e = ExternalFnToStubMap.end(); i != e; ++i) {
+    if (i->second != Stub)
+      continue;
+    ExternalFnToStubMap.erase(i);
+    break;
+  }
+  
   return 0;
 }
 
@@ -591,6 +600,10 @@
     // the stub is unused.
     DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
     
+    // ExtFnStubs - A map of external function names to stubs which have entries
+    // in the JITResolver's ExternalFnToStubMap.
+    StringMap<void *> ExtFnStubs;
+    
   public:
     JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit), CurFn(0) {
       MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
@@ -652,11 +665,18 @@
       return MBBLocations[MBB->getNumber()];
     }
 
-    void AddStubToCurrentFunction(void *Stub);
-    
     /// deallocateMemForFunction - Deallocate all memory for the specified
     /// function body.
     void deallocateMemForFunction(Function *F);
+
+    /// AddStubToCurrentFunction - Mark the current function being JIT'd as
+    /// using the stub at the specified address. Allows
+    /// deallocateMemForFunction to also remove stubs no longer referenced.
+    void AddStubToCurrentFunction(void *Stub);
+    
+    /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for
+    /// MachineRelocations that reference external functions by name.
+    const StringMap<void*> &getExternalFnStubs() const { return ExtFnStubs; }
     
     virtual void emitLabel(uint64_t LabelID) {
       if (LabelLocations.size() <= LabelID)
@@ -1033,8 +1053,18 @@
                << ResultPtr << "]\n";  
 
           // If the target REALLY wants a stub for this function, emit it now.
-          if (!MR.doesntNeedStub())
-            ResultPtr = Resolver.getExternalFunctionStub(ResultPtr);
+          if (!MR.doesntNeedStub()) {
+            if (!TheJIT->areDlsymStubsEnabled()) {
+              ResultPtr = Resolver.getExternalFunctionStub(ResultPtr);
+            } else {
+              void *&Stub = ExtFnStubs[MR.getExternalSymbol()];
+              if (!Stub) {
+                Stub = Resolver.getExternalFunctionStub((void *)&Stub);
+                AddStubToCurrentFunction(Stub);
+              }
+              ResultPtr = Stub;
+            }
+          }
         } else if (MR.isGlobalValue()) {
           ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
                                          BufferBegin+MR.getMachineCodeOffset(),
@@ -1189,6 +1219,11 @@
   SmallVectorImpl<void *> &StubList = CurFnStubUses[F];
   for (unsigned i = 0, e = StubList.size(); i != e; ++i) {
     void *Stub = StubList[i];
+    
+    // If we already invalidated this stub for this function, continue.
+    if (StubFnRefs.count(Stub) == 0)
+      continue;
+      
     SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub];
     FnRefs.erase(F);
     
@@ -1197,9 +1232,23 @@
     // we could call that at this point too.
     if (FnRefs.empty()) {
       DOUT << "\nJIT: Invalidated Stub at [" << Stub << "]\n";
+      StubFnRefs.erase(Stub);
+
+      // Invalidate the stub.  If it is a GV stub, update the JIT's global
+      // mapping for that GV to zero, otherwise, search the string map of
+      // external function names to stubs and remove the entry for this stub.
       GlobalValue *GV = Resolver.invalidateStub(Stub);
-      TheJIT->updateGlobalMapping(GV, 0);
-      StubFnRefs.erase(F);
+      if (GV) {
+        TheJIT->updateGlobalMapping(GV, 0);
+      } else {
+        for (StringMapIterator<void*> i = ExtFnStubs.begin(),
+             e = ExtFnStubs.end(); i != e; ++i) {
+          if (i->second == Stub) {
+            ExtFnStubs.erase(i);
+            break;
+          }
+        }
+      }
     }
   }
   CurFnStubUses.erase(F);
@@ -1428,35 +1477,43 @@
   
   SmallVector<GlobalValue*, 8> GVs;
   SmallVector<void*, 8> Ptrs;
+  const StringMap<void *> &ExtFns = JE->getExternalFnStubs();
 
   JE->getJITResolver().getRelocatableGVs(GVs, Ptrs);
 
+  unsigned nStubs = GVs.size() + ExtFns.size();
+  
   // If there are no relocatable stubs, return.
-  if (GVs.empty())
+  if (nStubs == 0)
     return;
 
   // If there are no new relocatable stubs, return.
   void *CurTable = JE->getMemMgr()->getDlsymTable();
-  if (CurTable && (*(unsigned *)CurTable == GVs.size()))
+  if (CurTable && (*(unsigned *)CurTable == nStubs))
     return;
   
   // Calculate the size of the stub info
-  unsigned offset    = 4 + 4 * GVs.size() + sizeof(intptr_t) * GVs.size();
+  unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs;
   
   SmallVector<unsigned, 8> Offsets;
   for (unsigned i = 0; i != GVs.size(); ++i) {
     Offsets.push_back(offset);
     offset += GVs[i]->getName().length() + 1;
   }
+  for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end(); 
+       i != e; ++i) {
+    Offsets.push_back(offset);
+    offset += strlen(i->first()) + 1;
+  }
   
   // Allocate space for the new "stub", which contains the dlsym table.
   JE->startGVStub(0, offset, 4);
   
   // Emit the number of records
-  MCE->emitInt32(GVs.size());
+  MCE->emitInt32(nStubs);
   
   // Emit the string offsets
-  for (unsigned i = 0; i != GVs.size(); ++i)
+  for (unsigned i = 0; i != nStubs; ++i)
     MCE->emitInt32(Offsets[i]);
   
   // Emit the pointers.  Verify that they are at least 2-byte aligned, and set
@@ -1470,7 +1527,16 @@
     if (isa<Function>(GVs[i]))
       Ptr |= (intptr_t)1;
            
-    if (sizeof(void *) == 8)
+    if (sizeof(Ptr) == 8)
+      MCE->emitInt64(Ptr);
+    else
+      MCE->emitInt32(Ptr);
+  }
+  for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end(); 
+       i != e; ++i) {
+    intptr_t Ptr = (intptr_t)i->second | 1;
+
+    if (sizeof(Ptr) == 8)
       MCE->emitInt64(Ptr);
     else
       MCE->emitInt32(Ptr);
@@ -1479,6 +1545,9 @@
   // Emit the strings.
   for (unsigned i = 0; i != GVs.size(); ++i)
     MCE->emitString(GVs[i]->getName());
+  for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end(); 
+       i != e; ++i)
+    MCE->emitString(i->first());
   
   // Tell the JIT memory manager where it is.  The JIT Memory Manager will
   // deallocate space for the old one, if one existed.





More information about the llvm-commits mailing list