Memory.h revision 221345
1218885Sdim//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim//
10218885Sdim// This file declares the llvm::sys::Memory class.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14218885Sdim#ifndef LLVM_SYSTEM_MEMORY_H
15218885Sdim#define LLVM_SYSTEM_MEMORY_H
16218885Sdim
17218885Sdim#include "llvm/Support/DataTypes.h"
18218885Sdim#include <string>
19218885Sdim
20218885Sdimnamespace llvm {
21218885Sdimnamespace sys {
22218885Sdim
23218885Sdim  /// This class encapsulates the notion of a memory block which has an address
24218885Sdim  /// and a size. It is used by the Memory class (a friend) as the result of
25218885Sdim  /// various memory allocation operations.
26218885Sdim  /// @see Memory
27218885Sdim  /// @brief Memory block abstraction.
28218885Sdim  class MemoryBlock {
29218885Sdim  public:
30218885Sdim    MemoryBlock() : Address(0), Size(0) { }
31218885Sdim    MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
32218885Sdim    void *base() const { return Address; }
33218885Sdim    size_t size() const { return Size; }
34218885Sdim  private:
35218885Sdim    void *Address;    ///< Address of first byte of memory area
36218885Sdim    size_t Size;      ///< Size, in bytes of the memory area
37218885Sdim    friend class Memory;
38218885Sdim  };
39218885Sdim
40218885Sdim  /// This class provides various memory handling functions that manipulate
41218885Sdim  /// MemoryBlock instances.
42218885Sdim  /// @since 1.4
43218885Sdim  /// @brief An abstraction for memory operations.
44218885Sdim  class Memory {
45218885Sdim  public:
46218885Sdim    /// This method allocates a block of Read/Write/Execute memory that is
47218885Sdim    /// suitable for executing dynamically generated code (e.g. JIT). An
48218885Sdim    /// attempt to allocate \p NumBytes bytes of virtual memory is made.
49218885Sdim    /// \p NearBlock may point to an existing allocation in which case
50218885Sdim    /// an attempt is made to allocate more memory near the existing block.
51218885Sdim    ///
52218885Sdim    /// On success, this returns a non-null memory block, otherwise it returns
53218885Sdim    /// a null memory block and fills in *ErrMsg.
54218885Sdim    ///
55218885Sdim    /// @brief Allocate Read/Write/Execute memory.
56218885Sdim    static MemoryBlock AllocateRWX(size_t NumBytes,
57218885Sdim                                   const MemoryBlock *NearBlock,
58218885Sdim                                   std::string *ErrMsg = 0);
59218885Sdim
60218885Sdim    /// This method releases a block of Read/Write/Execute memory that was
61218885Sdim    /// allocated with the AllocateRWX method. It should not be used to
62218885Sdim    /// release any memory block allocated any other way.
63218885Sdim    ///
64218885Sdim    /// On success, this returns false, otherwise it returns true and fills
65218885Sdim    /// in *ErrMsg.
66218885Sdim    /// @brief Release Read/Write/Execute memory.
67218885Sdim    static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
68218885Sdim
69218885Sdim
70218885Sdim    /// InvalidateInstructionCache - Before the JIT can run a block of code
71218885Sdim    /// that has been emitted it must invalidate the instruction cache on some
72218885Sdim    /// platforms.
73218885Sdim    static void InvalidateInstructionCache(const void *Addr, size_t Len);
74218885Sdim
75218885Sdim    /// setExecutable - Before the JIT can run a block of code, it has to be
76218885Sdim    /// given read and executable privilege. Return true if it is already r-x
77218885Sdim    /// or the system is able to change its previlege.
78221345Sdim    static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0);
79218885Sdim
80218885Sdim    /// setWritable - When adding to a block of code, the JIT may need
81218885Sdim    /// to mark a block of code as RW since the protections are on page
82218885Sdim    /// boundaries, and the JIT internal allocations are not page aligned.
83221345Sdim    static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0);
84218885Sdim
85218885Sdim    /// setRangeExecutable - Mark the page containing a range of addresses
86218885Sdim    /// as executable.
87218885Sdim    static bool setRangeExecutable(const void *Addr, size_t Size);
88218885Sdim
89218885Sdim    /// setRangeWritable - Mark the page containing a range of addresses
90218885Sdim    /// as writable.
91218885Sdim    static bool setRangeWritable(const void *Addr, size_t Size);
92218885Sdim  };
93218885Sdim}
94218885Sdim}
95218885Sdim
96218885Sdim#endif
97