vmem.h 5.26 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.

// [Guard]
#ifndef _ASMJIT_BASE_VMEM_H
#define _ASMJIT_BASE_VMEM_H

11
12
13
// [Dependencies]
#include "../base/globals.h"
#include "../base/osutils.h"
14
15

// [Api-Begin]
16
#include "../asmjit_apibegin.h"
17
18
19

namespace asmjit {

20
//! \addtogroup asmjit_base
21
22
23
24
25
26
27
28
//! \{

// ============================================================================
// [asmjit::VMemMgr]
// ============================================================================

//! Reference implementation of memory manager that uses `VMemUtil` to allocate
//! chunks of virtual memory and bit arrays to manage it.
29
30
31
32
33
34
35
36
37
38
class VMemMgr {
public:
  //! Type of virtual memory allocation, see `VMemMgr::alloc()`.
  ASMJIT_ENUM(AllocType) {
    //! Normal memory allocation, has to be freed by `VMemMgr::release()`.
    kAllocFreeable = 0,
    //! Allocate permanent memory, can't be freed.
    kAllocPermanent = 1
  };

39
40
41
42
  // --------------------------------------------------------------------------
  // [Construction / Destruction]
  // --------------------------------------------------------------------------

43
#if !ASMJIT_OS_WINDOWS
44
  //! Create a `VMemMgr` instance.
45
  ASMJIT_API VMemMgr() noexcept;
46
47
48
#else
  //! Create a `VMemMgr` instance.
  //!
49
50
51
52
  //! NOTE: When running on Windows it's possible to specify a `hProcess` to
  //! be used for memory allocation. Using `hProcess` allows to allocate memory
  //! of a remote process.
  ASMJIT_API VMemMgr(HANDLE hProcess = static_cast<HANDLE>(0)) noexcept;
53
54
55
#endif // ASMJIT_OS_WINDOWS

  //! Destroy the `VMemMgr` instance and free all blocks.
56
  ASMJIT_API ~VMemMgr() noexcept;
57
58
59
60
61
62

  // --------------------------------------------------------------------------
  // [Reset]
  // --------------------------------------------------------------------------

  //! Free all allocated memory.
63
  ASMJIT_API void reset() noexcept;
64
65
66
67
68

  // --------------------------------------------------------------------------
  // [Accessors]
  // --------------------------------------------------------------------------

69
#if ASMJIT_OS_WINDOWS
70
  //! Get the handle of the process memory manager is bound to.
71
  ASMJIT_INLINE HANDLE getProcessHandle() const noexcept { return _hProcess; }
72
73
74
#endif // ASMJIT_OS_WINDOWS

  //! Get how many bytes are currently allocated.
75
  ASMJIT_INLINE size_t getAllocatedBytes() const noexcept { return _allocatedBytes; }
76
  //! Get how many bytes are currently used.
77
  ASMJIT_INLINE size_t getUsedBytes() const noexcept { return _usedBytes; }
78
79
80
81

  //! Get whether to keep allocated memory after the `VMemMgr` is destroyed.
  //!
  //! \sa \ref setKeepVirtualMemory.
82
83
  ASMJIT_INLINE bool getKeepVirtualMemory() const noexcept { return _keepVirtualMemory; }
  //! Set whether to keep allocated memory after the memory manager is destroyed.
84
85
86
87
88
89
90
  //!
  //! This method is usable when patching code of remote process. You need to
  //! allocate process memory, store generated assembler into it and patch the
  //! method you want to redirect (into your code). This method affects only
  //! VMemMgr destructor. After destruction all internal
  //! structures are freed, only the process virtual memory remains.
  //!
91
  //! NOTE: Memory allocated with kAllocPermanent is always kept.
92
93
  //!
  //! \sa \ref getKeepVirtualMemory.
94
  ASMJIT_INLINE void setKeepVirtualMemory(bool val) noexcept { _keepVirtualMemory = val; }
95
96
97
98
99
100
101
102
103
104

  // --------------------------------------------------------------------------
  // [Alloc / Release]
  // --------------------------------------------------------------------------

  //! Allocate a `size` bytes of virtual memory.
  //!
  //! Note that if you are implementing your own virtual memory manager then you
  //! can quitly ignore type of allocation. This is mainly for AsmJit to memory
  //! manager that allocated memory will be never freed.
105
  ASMJIT_API void* alloc(size_t size, uint32_t type = kAllocFreeable) noexcept;
106
  //! Free previously allocated memory at a given `address`.
107
  ASMJIT_API Error release(void* p) noexcept;
108
  //! Free extra memory allocated with `p`.
109
  ASMJIT_API Error shrink(void* p, size_t used) noexcept;
110
111
112
113
114

  // --------------------------------------------------------------------------
  // [Members]
  // --------------------------------------------------------------------------

115
116
#if ASMJIT_OS_WINDOWS
  HANDLE _hProcess;                      //!< Process passed to `VirtualAllocEx` and `VirtualFree`.
117
#endif // ASMJIT_OS_WINDOWS
118
  Lock _lock;                            //!< Lock to enable thread-safe functionality.
119

120
121
122
  size_t _blockSize;                     //!< Default block size.
  size_t _blockDensity;                  //!< Default block density.
  bool _keepVirtualMemory;               //!< Keep virtual memory after destroyed.
123

124
125
  size_t _allocatedBytes;                //!< How many bytes are currently allocated.
  size_t _usedBytes;                     //!< How many bytes are currently used.
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

  //! \internal
  //! \{

  struct RbNode;
  struct MemNode;
  struct PermanentNode;

  // Memory nodes root.
  MemNode* _root;
  // Memory nodes list.
  MemNode* _first;
  MemNode* _last;
  MemNode* _optimal;
  // Permanent memory.
  PermanentNode* _permanent;

  //! \}
};

//! \}

} // asmjit namespace

// [Api-End]
151
#include "../asmjit_apiend.h"
152
153
154

// [Guard]
#endif // _ASMJIT_BASE_VMEM_H