Add a new InvalidateInstructionCache method to sys::Memory.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52731 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-06-25 17:14:10 +00:00
parent c4ab7acc0b
commit 93bb4aa0ce
2 changed files with 60 additions and 32 deletions

View 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);
};
}
}

View File

@ -17,12 +17,6 @@
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
}