[llvm-commits] [llvm] r57013 - in /llvm/trunk: include/llvm/ExecutionEngine/JITMemoryManager.h include/llvm/System/Memory.h lib/ExecutionEngine/JIT/JITEmitter.cpp lib/ExecutionEngine/JIT/JITMemoryManager.cpp lib/System/Memory.cpp lib/System/Unix/Memory.inc

Jim Grosbach grosbach at apple.com
Fri Oct 3 09:17:20 PDT 2008


Author: grosbach
Date: Fri Oct  3 11:17:20 2008
New Revision: 57013

URL: http://llvm.org/viewvc/llvm-project?rev=57013&view=rev
Log:
On Darwin ARM, memory needs special handling to do JIT. This patch expands
this handling to work properly for modifying stub functions, relocations
back to entry points after JIT compilation, etc..

Modified:
    llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h
    llvm/trunk/include/llvm/System/Memory.h
    llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
    llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
    llvm/trunk/lib/System/Memory.cpp
    llvm/trunk/lib/System/Unix/Memory.inc

Modified: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h?rev=57013&r1=57012&r2=57013&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Fri Oct  3 11:17:20 2008
@@ -35,6 +35,14 @@
   /// JIT Memory Manager if the client does not provide one to the JIT.
   static JITMemoryManager *CreateDefaultMemManager();
   
+  /// setMemoryWritable - When code generation is in progress,
+  /// the code pages may need permissions changed.
+  virtual void setMemoryWritable(void) = 0;
+
+  /// setMemoryExecutable - When code generation is done and we're ready to
+  /// start execution, the code pages may need permissions changed.
+  virtual void setMemoryExecutable(void) = 0;
+
   //===--------------------------------------------------------------------===//
   // Global Offset Table Management
   //===--------------------------------------------------------------------===//

Modified: llvm/trunk/include/llvm/System/Memory.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/System/Memory.h?rev=57013&r1=57012&r2=57013&view=diff

==============================================================================
--- llvm/trunk/include/llvm/System/Memory.h (original)
+++ llvm/trunk/include/llvm/System/Memory.h Fri Oct  3 11:17:20 2008
@@ -70,10 +70,15 @@
     /// platforms.
     static void InvalidateInstructionCache(const void *Addr, size_t Len);
 
-    /// SetRXPrivilege - Before the JIT can run a block of code, it has to be
+    /// setExecutable - Before the JIT can run a block of code, it has to be
     /// given read and executable privilege. Return true if it is already r-x
     /// or the system is able to change its previlege.
-    static bool SetRXPrivilege(const void *Addr, size_t Size);
+    static bool setExecutable (MemoryBlock &M, std::string *ErrMsg = 0);
+
+    /// setWritable - When adding to a block of code, the JIT may need
+    /// to mark a block of code as RW since the protections are on page
+    /// boundaries, and the JIT internal allocations are not page aligned.
+    static bool setWritable (MemoryBlock &M, std::string *ErrMsg = 0);
   };
 }
 }

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=57013&r1=57012&r2=57013&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Fri Oct  3 11:17:20 2008
@@ -560,6 +560,10 @@
       if (ExceptionHandling) DE->setModuleInfo(Info);
     }
 
+    void setMemoryExecutable(void) {
+      MemMgr->setMemoryExecutable();
+    }
+
   private:
     void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
     void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
@@ -791,6 +795,8 @@
 
 void JITEmitter::startFunction(MachineFunction &F) {
   uintptr_t ActualSize = 0;
+  // Set the memory writable, if it's not already
+  MemMgr->setMemoryWritable();
   if (MemMgr->NeedsExactSize()) {
     DOUT << "ExactSize\n";
     const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
@@ -938,7 +944,7 @@
   Relocations.clear();
 
   // Mark code region readable and executable if it's not so already.
-  sys::Memory::SetRXPrivilege(FnStart, FnEnd-FnStart);
+  MemMgr->setMemoryExecutable();
 
 #ifndef NDEBUG
   {
@@ -1086,6 +1092,10 @@
 
 void *JITEmitter::finishFunctionStub(const GlobalValue* F) {
   NumBytes += getCurrentPCOffset();
+
+  // Invalidate the icache if necessary.
+  sys::Memory::InvalidateInstructionCache(BufferBegin, NumBytes);
+
   std::swap(SavedBufferBegin, BufferBegin);
   BufferEnd = SavedBufferEnd;
   CurBufferPtr = SavedCurBufferPtr;

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp?rev=57013&r1=57012&r2=57013&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp Fri Oct  3 11:17:20 2008
@@ -365,6 +365,21 @@
       // Finally, remove this entry from TableBlocks.
       TableBlocks.erase(I);
     }
+
+    /// setMemoryWritable - When code generation is in progress,
+    /// the code pages may need permissions changed.
+    void setMemoryWritable(void)
+    {
+      for (unsigned i = 0, e = Blocks.size(); i != e; ++i)
+        sys::Memory::setWritable(Blocks[i]);
+    }
+    /// setMemoryExecutable - When code generation is done and we're ready to
+    /// start execution, the code pages may need permissions changed.
+    void setMemoryExecutable(void)
+    {
+      for (unsigned i = 0, e = Blocks.size(); i != e; ++i)
+        sys::Memory::setExecutable(Blocks[i]);
+    }
   };
 }
 

Modified: llvm/trunk/lib/System/Memory.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Memory.cpp?rev=57013&r1=57012&r2=57013&view=diff

==============================================================================
--- llvm/trunk/lib/System/Memory.cpp (original)
+++ llvm/trunk/lib/System/Memory.cpp Fri Oct  3 11:17:20 2008
@@ -58,14 +58,3 @@
 #endif  // end PPC
 
 }
-
-bool llvm::sys::Memory::SetRXPrivilege(const void *Addr, size_t Size) {
-#if defined(__APPLE__) && defined(__arm__)
-  kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
-                                (vm_size_t)Size, 0,
-                                VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
-  return KERN_SUCCESS == kr;
-#else
-  return true;
-#endif
-}

Modified: llvm/trunk/lib/System/Unix/Memory.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Memory.inc?rev=57013&r1=57012&r2=57013&view=diff

==============================================================================
--- llvm/trunk/lib/System/Unix/Memory.inc (original)
+++ llvm/trunk/lib/System/Unix/Memory.inc Fri Oct  3 11:17:20 2008
@@ -76,7 +76,7 @@
                                 (vm_size_t)(pageSize*NumPages), 0,
                                 VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
   if (KERN_SUCCESS != kr) {
-    MakeErrMsg(ErrMsg, "vm_protect max RWX failed\n");
+    MakeErrMsg(ErrMsg, "vm_protect max RX failed\n");
     return sys::MemoryBlock();
   }
 
@@ -103,3 +103,27 @@
   return false;
 }
 
+bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
+#if defined(__APPLE__) && defined(__arm__)
+  if (M.Address == 0 || M.Size == 0) return false;
+  sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
+  kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
+    (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE);
+  return KERN_SUCCESS == kr;
+#else
+  return true;
+#endif
+}
+
+bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
+#if defined(__APPLE__) && defined(__arm__)
+  if (M.Address == 0 || M.Size == 0) return false;
+  sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
+  kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
+    (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+  return KERN_SUCCESS == kr;
+#else
+  return false;
+#endif
+}
+





More information about the llvm-commits mailing list