Add a new InvalidateInstructionCache method to sys::Memory.
authorChris Lattner <sabre@nondot.org>
Wed, 25 Jun 2008 17:14:10 +0000 (17:14 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 25 Jun 2008 17:14:10 +0000 (17:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52731 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/Memory.h
lib/System/Memory.cpp

index 52e1f3f14b7ea8e189314e25706d4cc0d9a8a88f..014633c8c55071ede98ccebb59aef6e75bf9f346 100644 (file)
@@ -39,33 +39,36 @@ namespace sys {
   /// @since 1.4
   /// @brief An abstraction for memory operations.
   class Memory {
-    /// @name Functions
-    /// @{
-    public:
-      /// This method allocates a block of Read/Write/Execute memory that is
-      /// suitable for executing dynamically generated code (e.g. JIT). An
-      /// attempt to allocate \p NumBytes bytes of virtual memory is made.
-      /// \p NearBlock may point to an existing allocation in which case
-      /// an attempt is made to allocate more memory near the existing block.
-      ///
-      /// On success, this returns a non-null memory block, otherwise it returns
-      /// a null memory block and fills in *ErrMsg.
-      /// 
-      /// @brief Allocate Read/Write/Execute memory.
-      static MemoryBlock AllocateRWX(unsigned NumBytes,
-                                     const MemoryBlock *NearBlock,
-                                     std::string *ErrMsg = 0);
+  public:
+    /// This method allocates a block of Read/Write/Execute memory that is
+    /// suitable for executing dynamically generated code (e.g. JIT). An
+    /// attempt to allocate \p NumBytes bytes of virtual memory is made.
+    /// \p NearBlock may point to an existing allocation in which case
+    /// an attempt is made to allocate more memory near the existing block.
+    ///
+    /// On success, this returns a non-null memory block, otherwise it returns
+    /// a null memory block and fills in *ErrMsg.
+    /// 
+    /// @brief Allocate Read/Write/Execute memory.
+    static MemoryBlock AllocateRWX(unsigned NumBytes,
+                                   const MemoryBlock *NearBlock,
+                                   std::string *ErrMsg = 0);
 
-      /// This method releases a block of Read/Write/Execute memory that was
-      /// allocated with the AllocateRWX method. It should not be used to
-      /// release any memory block allocated any other way.
-      ///
-      /// On success, this returns false, otherwise it returns true and fills
-      /// in *ErrMsg.
-      /// @throws std::string if an error occurred.
-      /// @brief Release Read/Write/Execute memory.
-      static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
-    /// @}
+    /// This method releases a block of Read/Write/Execute memory that was
+    /// allocated with the AllocateRWX method. It should not be used to
+    /// release any memory block allocated any other way.
+    ///
+    /// On success, this returns false, otherwise it returns true and fills
+    /// in *ErrMsg.
+    /// @throws std::string if an error occurred.
+    /// @brief Release Read/Write/Execute memory.
+    static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
+    
+    
+    /// InvalidateInstructionCache - Before the JIT can run a block of code
+    /// that has been emitted it must invalidate the instruction cache on some
+    /// platforms.
+    static void InvalidateInstructionCache(const void *Addr, size_t Len);
   };
 }
 }
index 054cc966a3e7b71bb1dd75d6d634bed11d6f9111..bbb7917dca3b4266e771ca73b54d62f96dbc81c1 100644 (file)
 
 namespace llvm {
 using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//===          independent code.
-//===----------------------------------------------------------------------===//
-
 }
 
 // Include the platform-specific parts of this class.
@@ -32,3 +26,34 @@ using namespace sys;
 #ifdef LLVM_ON_WIN32
 #include "Win32/Memory.inc"
 #endif
+
+/// InvalidateInstructionCache - Before the JIT can run a block of code
+/// that has been emitted it must invalidate the instruction cache on some
+/// platforms.
+void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
+                                                   size_t Len) {
+  
+// icache invalidation for PPC.
+#if (defined(__POWERPC__) || defined (__ppc__) || \
+     defined(_POWER) || defined(_ARCH_PPC))
+   #if defined(__APPLE__)
+       extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
+       sys_icache_invalidate(Addr, len);
+   #elif defined(__GNUC__)
+        const size_t LineSize = 32;
+
+        const intptr_t Mask = ~(LineSize - 1);
+        const intptr_t StartLine = ((intptr_t) Addr) & Mask;
+        const intptr_t EndLine = ((intptr_t) Addr + len + LineSize - 1) & Mask;
+
+        for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+          asm volatile("dcbf 0, %0" : : "r"(Line));
+        asm volatile("sync");
+
+        for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+          asm volatile("icbi 0, %0" : : "r"(Line));
+        asm volatile("isync");
+   #endif
+#endif  // end PPC
+
+}
\ No newline at end of file