"plugins/amoeba/openmmapi/vscode:/vscode.git/clone" did not exist on "111844a2c2d9645e8c305f6cf916c45c0650d7d2"
runtime.cpp 4.55 KB
Newer Older
1
2
3
4
5
6
7
8
9
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.

// [Export]
#define ASMJIT_EXPORTS

10
// [Dependencies]
11
12
13
14
15
#include "../base/assembler.h"
#include "../base/cpuinfo.h"
#include "../base/runtime.h"

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

namespace asmjit {

20
21
22
23
24
25
26
27
28
29
30
static ASMJIT_INLINE void hostFlushInstructionCache(const void* p, size_t size) noexcept {
  // Only useful on non-x86 architectures.
#if !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64
# if ASMJIT_OS_WINDOWS
  // Windows has a built-in support in kernel32.dll.
  ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size);
# endif // ASMJIT_OS_WINDOWS
#else
  ASMJIT_UNUSED(p);
  ASMJIT_UNUSED(size);
#endif // !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64
31
32
}

33
34
static ASMJIT_INLINE uint32_t hostDetectNaturalStackAlignment() noexcept {
  // Alignment is assumed to match the pointer-size by default.
35
36
  uint32_t alignment = sizeof(intptr_t);

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  // X86 & X64
  // ---------
  //
  //   - 32-bit X86 requires stack to be aligned to 4 bytes. Modern Linux, Mac
  //     and UNIX guarantees 16-byte stack alignment even on 32-bit. I'm not
  //     sure about all other UNIX operating systems, because 16-byte alignment
  //!    is addition to an older specification.
  //   - 64-bit X86 requires stack to be aligned to at least 16 bytes.
#if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
  int kIsModernOS = ASMJIT_OS_LINUX  || // Linux & ANDROID.
                    ASMJIT_OS_MAC    || // OSX and iOS.
                    ASMJIT_OS_BSD    ;  // BSD variants.
  alignment = ASMJIT_ARCH_X64 || kIsModernOS ? 16 : 4;
#endif

  // ARM32 & ARM64
  // -------------
  //
  //   - 32-bit ARM requires stack to be aligned to 8 bytes.
  //   - 64-bit ARM requires stack to be aligned to 16 bytes.
#if ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
  alignment = ASMJIT_ARCH_ARM32 ? 8 : 16;
59
60
61
62
63
64
65
#endif

  return alignment;
}


// ============================================================================
66
// [asmjit::Runtime - Construction / Destruction]
67
68
// ============================================================================

69
70
71
72
73
Runtime::Runtime() noexcept
  : _codeInfo(),
    _runtimeType(kRuntimeNone),
    _allocType(VMemMgr::kAllocFreeable) {}
Runtime::~Runtime() noexcept {}
74
75

// ============================================================================
76
// [asmjit::HostRuntime - Construction / Destruction]
77
78
// ============================================================================

79
80
HostRuntime::HostRuntime() noexcept {
  _runtimeType = kRuntimeJit;
81

82
83
84
85
86
87
  // Setup the CodeInfo of this Runtime.
  _codeInfo._archInfo       = CpuInfo::getHost().getArchInfo();
  _codeInfo._stackAlignment = static_cast<uint8_t>(hostDetectNaturalStackAlignment());
  _codeInfo._cdeclCallConv  = CallConv::kIdHostCDecl;
  _codeInfo._stdCallConv    = CallConv::kIdHostStdCall;
  _codeInfo._fastCallConv   = CallConv::kIdHostFastCall;
88
}
89
HostRuntime::~HostRuntime() noexcept {}
90

91
92
93
94
95
96
// ============================================================================
// [asmjit::HostRuntime - Interface]
// ============================================================================

void HostRuntime::flush(const void* p, size_t size) noexcept {
  hostFlushInstructionCache(p, size);
97
98
99
100
101
102
}

// ============================================================================
// [asmjit::JitRuntime - Construction / Destruction]
// ============================================================================

103
104
JitRuntime::JitRuntime() noexcept {}
JitRuntime::~JitRuntime() noexcept {}
105
106
107
108
109

// ============================================================================
// [asmjit::JitRuntime - Interface]
// ============================================================================

110
111
112
113
114
Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
  size_t codeSize = code->getCodeSize();
  if (ASMJIT_UNLIKELY(codeSize == 0)) {
    *dst = nullptr;
    return DebugUtils::errored(kErrorNoCodeGenerated);
115
116
117
  }

  void* p = _memMgr.alloc(codeSize, getAllocType());
118
119
120
  if (ASMJIT_UNLIKELY(!p)) {
    *dst = nullptr;
    return DebugUtils::errored(kErrorNoVirtualMemory);
121
122
123
  }

  // Relocate the code and release the unused memory back to `VMemMgr`.
124
125
126
127
128
  size_t relocSize = code->relocate(p);
  if (ASMJIT_UNLIKELY(relocSize == 0)) {
    *dst = nullptr;
    _memMgr.release(p);
    return DebugUtils::errored(kErrorInvalidState);
129
130
  }

131
132
133
  if (relocSize < codeSize)
    _memMgr.shrink(p, relocSize);

134
135
136
137
138
139
  flush(p, relocSize);
  *dst = p;

  return kErrorOk;
}

140
Error JitRuntime::_release(void* p) noexcept {
141
142
143
144
145
146
  return _memMgr.release(p);
}

} // asmjit namespace

// [Api-End]
147
#include "../asmjit_apiend.h"