asmjit 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +5 -3
  4. data/asmjit.gemspec +1 -3
  5. data/ext/asmjit/asmjit/.editorconfig +10 -0
  6. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  8. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  9. data/ext/asmjit/asmjit/.gitignore +6 -0
  10. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  11. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  12. data/ext/asmjit/asmjit/README.md +69 -0
  13. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  43. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  46. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  133. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  159. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  160. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  179. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  180. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  181. data/ext/asmjit/asmjit/test/broken.h +148 -0
  182. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  183. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  184. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  191. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  193. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  197. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  199. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  200. data/ext/asmjit/asmjit.cc +167 -30
  201. data/ext/asmjit/extconf.rb +9 -9
  202. data/lib/asmjit/version.rb +1 -1
  203. data/lib/asmjit.rb +14 -4
  204. metadata +198 -17
@@ -0,0 +1,261 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #ifndef ASMJIT_CORE_JITALLOCATOR_H_INCLUDED
7
+ #define ASMJIT_CORE_JITALLOCATOR_H_INCLUDED
8
+
9
+ #include "../core/api-config.h"
10
+ #ifndef ASMJIT_NO_JIT
11
+
12
+ #include "../core/globals.h"
13
+ #include "../core/virtmem.h"
14
+
15
+ ASMJIT_BEGIN_NAMESPACE
16
+
17
+ //! \addtogroup asmjit_virtual_memory
18
+ //! \{
19
+
20
+ //! Options used by \ref JitAllocator.
21
+ enum class JitAllocatorOptions : uint32_t {
22
+ //! No options.
23
+ kNone = 0,
24
+
25
+ //! Enables the use of an anonymous memory-mapped memory that is mapped into two buffers having a different pointer.
26
+ //! The first buffer has read and execute permissions and the second buffer has read+write permissions.
27
+ //!
28
+ //! See \ref VirtMem::allocDualMapping() for more details about this feature.
29
+ kUseDualMapping = 0x00000001u,
30
+
31
+ //! Enables the use of multiple pools with increasing granularity instead of a single pool. This flag would enable
32
+ //! 3 internal pools in total having 64, 128, and 256 bytes granularity.
33
+ //!
34
+ //! This feature is only recommended for users that generate a lot of code and would like to minimize the overhead
35
+ //! of `JitAllocator` itself by having blocks of different allocation granularities. Using this feature only for
36
+ //! few allocations won't pay off as the allocator may need to create more blocks initially before it can take the
37
+ //! advantage of variable block granularity.
38
+ kUseMultiplePools = 0x00000002u,
39
+
40
+ //! Always fill reserved memory by a fill-pattern.
41
+ //!
42
+ //! Causes a new block to be cleared by the fill pattern and freshly released memory to be cleared before making
43
+ //! it ready for another use.
44
+ kFillUnusedMemory = 0x00000004u,
45
+
46
+ //! When this flag is set the allocator would immediately release unused blocks during `release()` or `reset()`.
47
+ //! When this flag is not set the allocator would keep one empty block in each pool to prevent excessive virtual
48
+ //! memory allocations and deallocations in border cases, which involve constantly allocating and deallocating a
49
+ //! single block caused by repetitive calling `alloc()` and `release()` when the allocator has either no blocks
50
+ //! or have all blocks fully occupied.
51
+ kImmediateRelease = 0x00000008u,
52
+
53
+ //! Use a custom fill pattern, must be combined with `kFlagFillUnusedMemory`.
54
+ kCustomFillPattern = 0x10000000u
55
+ };
56
+ ASMJIT_DEFINE_ENUM_FLAGS(JitAllocatorOptions)
57
+
58
+ //! A simple implementation of memory manager that uses `asmjit::VirtMem`
59
+ //! functions to manage virtual memory for JIT compiled code.
60
+ //!
61
+ //! Implementation notes:
62
+ //!
63
+ //! - Granularity of allocated blocks is different than granularity for a typical C malloc. In addition, the allocator
64
+ //! can use several memory pools having a different granularity to minimize the maintenance overhead. Multiple pools
65
+ //! feature requires `kFlagUseMultiplePools` flag to be set.
66
+ //!
67
+ //! - The allocator doesn't store any information in executable memory, instead, the implementation uses two
68
+ //! bit-vectors to manage allocated memory of each allocator-block. The first bit-vector called 'used' is used to
69
+ //! track used memory (where each bit represents memory size defined by granularity) and the second bit vector called
70
+ //! 'stop' is used as a sentinel to mark where the allocated area ends.
71
+ //!
72
+ //! - Internally, the allocator also uses RB tree to keep track of all blocks across all pools. Each inserted block is
73
+ //! added to the tree so it can be matched fast during `release()` and `shrink()`.
74
+ class JitAllocator {
75
+ public:
76
+ ASMJIT_NONCOPYABLE(JitAllocator)
77
+
78
+ struct Impl {
79
+ //! Allocator options.
80
+ JitAllocatorOptions options;
81
+ //! Base block size (0 if the allocator is not initialized).
82
+ uint32_t blockSize;
83
+ //! Base granularity (0 if the allocator is not initialized).
84
+ uint32_t granularity;
85
+ //! A pattern that is used to fill unused memory if secure mode is enabled.
86
+ uint32_t fillPattern;
87
+ };
88
+
89
+ //! Allocator implementation (private).
90
+ Impl* _impl;
91
+
92
+ //! \name Construction & Destruction
93
+ //! \{
94
+
95
+ //! Parameters that can be passed to `JitAllocator` constructor.
96
+ //!
97
+ //! Use it like this:
98
+ //!
99
+ //! ```
100
+ //! // Zero initialize (zero means the default value) and change what you need.
101
+ //! JitAllocator::CreateParams params {};
102
+ //! params.blockSize = 1024 * 1024;
103
+ //!
104
+ //! // Create the allocator.
105
+ //! JitAllocator allocator(&params);
106
+ //! ```
107
+ struct CreateParams {
108
+ //! Allocator options.
109
+ //!
110
+ //! No options are used by default.
111
+ JitAllocatorOptions options = JitAllocatorOptions::kNone;
112
+
113
+ //! Base size of a single block in bytes (default 64kB).
114
+ //!
115
+ //! \remarks Block size must be equal to or greater than page size and must be power of 2. If the input is not
116
+ //! valid then the default block size will be used instead.
117
+ uint32_t blockSize = 0;
118
+
119
+ //! Base granularity (and also natural alignment) of allocations in bytes (default 64).
120
+ //!
121
+ //! Since the `JitAllocator` uses bit-arrays to mark used memory the granularity also specifies how many bytes
122
+ //! correspond to a single bit in such bit-array. Higher granularity means more waste of virtual memory (as it
123
+ //! increases the natural alignment), but smaller bit-arrays as less bits would be required per a single block.
124
+ uint32_t granularity = 0;
125
+
126
+ //! Patter to use to fill unused memory.
127
+ //!
128
+ //! Only used if \ref JitAllocatorOptions::kCustomFillPattern is set.
129
+ uint32_t fillPattern = 0;
130
+
131
+ // Reset the content of `CreateParams`.
132
+ inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
133
+ };
134
+
135
+ //! Creates a `JitAllocator` instance.
136
+ ASMJIT_API explicit JitAllocator(const CreateParams* params = nullptr) noexcept;
137
+ //! Destroys the `JitAllocator` instance and release all blocks held.
138
+ ASMJIT_API ~JitAllocator() noexcept;
139
+
140
+ inline bool isInitialized() const noexcept { return _impl->blockSize == 0; }
141
+
142
+ //! Free all allocated memory - makes all pointers returned by `alloc()` invalid.
143
+ //!
144
+ //! \remarks This function is not thread-safe as it's designed to be used when nobody else is using allocator.
145
+ //! The reason is that there is no point of calling `reset()` when the allocator is still in use.
146
+ ASMJIT_API void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept;
147
+
148
+ //! \}
149
+
150
+ //! \name Accessors
151
+ //! \{
152
+
153
+ //! Returns allocator options, see `Flags`.
154
+ inline JitAllocatorOptions options() const noexcept { return _impl->options; }
155
+ //! Tests whether the allocator has the given `option` set.
156
+ inline bool hasOption(JitAllocatorOptions option) const noexcept { return uint32_t(_impl->options & option) != 0; }
157
+
158
+ //! Returns a base block size (a minimum size of block that the allocator would allocate).
159
+ inline uint32_t blockSize() const noexcept { return _impl->blockSize; }
160
+ //! Returns granularity of the allocator.
161
+ inline uint32_t granularity() const noexcept { return _impl->granularity; }
162
+ //! Returns pattern that is used to fill unused memory if `kFlagUseFillPattern` is set.
163
+ inline uint32_t fillPattern() const noexcept { return _impl->fillPattern; }
164
+
165
+ //! \}
166
+
167
+ //! \name Alloc & Release
168
+ //! \{
169
+
170
+ //! Allocates a new memory block of the requested `size`.
171
+ //!
172
+ //! When the function is successful it stores two pointers in `rxPtrOut` and `rwPtrOut`. The pointers will be
173
+ //! different only if `kOptionUseDualMapping` was used to setup the allocator (in that case the `rxPtrOut` would
174
+ //! point to a Read+Execute region and `rwPtrOut` would point to a Read+Write region of the same memory-mapped block.
175
+ ASMJIT_API Error alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcept;
176
+
177
+ //! Releases a memory block returned by `alloc()`.
178
+ //!
179
+ //! \remarks This function is thread-safe.
180
+ ASMJIT_API Error release(void* rxPtr) noexcept;
181
+
182
+ //! Frees extra memory allocated with `rxPtr` by shrinking it to the given `newSize`.
183
+ //!
184
+ //! \remarks This function is thread-safe.
185
+ ASMJIT_API Error shrink(void* rxPtr, size_t newSize) noexcept;
186
+
187
+ //! Queries information about an allocated memory block that contains the given `rxPtr`.
188
+ //!
189
+ //! The function returns `kErrorOk` when `rxPtr` is matched and fills `rxPtrOut`, `rwPtrOut`, and `sizeOut` output
190
+ //! arguments. The returned `rxPtrOut` and `rwPtrOut` pointers point to the beginning of the block, and `sizeOut`
191
+ //! describes the total amount of bytes this allocation uses - `sizeOut` will always be aligned to the allocation
192
+ //! granularity, so for example if an allocation was 1 byte and the size granularity is 64, the returned `sizeOut`
193
+ //! will be 64 bytes, because that's what the allocator sees.
194
+ ASMJIT_API Error query(void* rxPtr, void** rxPtrOut, void** rwPtrOut, size_t* sizeOut) const noexcept;
195
+
196
+ //! \}
197
+
198
+ //! \name Statistics
199
+ //! \{
200
+
201
+ //! Statistics about `JitAllocator`.
202
+ struct Statistics {
203
+ //! Number of blocks `JitAllocator` maintains.
204
+ size_t _blockCount;
205
+ //! Number of active allocations.
206
+ size_t _allocationCount;
207
+ //! How many bytes are currently used / allocated.
208
+ size_t _usedSize;
209
+ //! How many bytes are currently reserved by the allocator.
210
+ size_t _reservedSize;
211
+ //! Allocation overhead (in bytes) required to maintain all blocks.
212
+ size_t _overheadSize;
213
+
214
+ inline void reset() noexcept {
215
+ _blockCount = 0;
216
+ _usedSize = 0;
217
+ _reservedSize = 0;
218
+ _overheadSize = 0;
219
+ }
220
+
221
+ //! Returns count of blocks managed by `JitAllocator` at the moment.
222
+ inline size_t blockCount() const noexcept { return _blockCount; }
223
+ //! Returns the number of active allocations.
224
+ inline size_t allocationCount() const noexcept { return _allocationCount; }
225
+
226
+ //! Returns how many bytes are currently used.
227
+ inline size_t usedSize() const noexcept { return _usedSize; }
228
+ //! Returns the number of bytes unused by the allocator at the moment.
229
+ inline size_t unusedSize() const noexcept { return _reservedSize - _usedSize; }
230
+ //! Returns the total number of bytes bytes reserved by the allocator (sum of sizes of all blocks).
231
+ inline size_t reservedSize() const noexcept { return _reservedSize; }
232
+ //! Returns the number of bytes the allocator needs to manage the allocated memory.
233
+ inline size_t overheadSize() const noexcept { return _overheadSize; }
234
+
235
+ inline double usedSizeAsPercent() const noexcept {
236
+ return (double(usedSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
237
+ }
238
+
239
+ inline double unusedSizeAsPercent() const noexcept {
240
+ return (double(unusedSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
241
+ }
242
+
243
+ inline double overheadSizeAsPercent() const noexcept {
244
+ return (double(overheadSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
245
+ }
246
+ };
247
+
248
+ //! Returns JIT allocator statistics.
249
+ //!
250
+ //! \remarks This function is thread-safe.
251
+ ASMJIT_API Statistics statistics() const noexcept;
252
+
253
+ //! \}
254
+ };
255
+
256
+ //! \}
257
+
258
+ ASMJIT_END_NAMESPACE
259
+
260
+ #endif
261
+ #endif
@@ -0,0 +1,80 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #include "../core/api-build_p.h"
7
+ #ifndef ASMJIT_NO_JIT
8
+
9
+ #include "../core/cpuinfo.h"
10
+ #include "../core/jitruntime.h"
11
+
12
+ ASMJIT_BEGIN_NAMESPACE
13
+
14
+ JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept
15
+ : _allocator(params) {
16
+ _environment = Environment::host();
17
+ _environment.setObjectFormat(ObjectFormat::kJIT);
18
+ }
19
+
20
+ JitRuntime::~JitRuntime() noexcept {}
21
+
22
+ Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
23
+ *dst = nullptr;
24
+
25
+ ASMJIT_PROPAGATE(code->flatten());
26
+ ASMJIT_PROPAGATE(code->resolveUnresolvedLinks());
27
+
28
+ size_t estimatedCodeSize = code->codeSize();
29
+ if (ASMJIT_UNLIKELY(estimatedCodeSize == 0))
30
+ return DebugUtils::errored(kErrorNoCodeGenerated);
31
+
32
+ uint8_t* rx;
33
+ uint8_t* rw;
34
+ ASMJIT_PROPAGATE(_allocator.alloc((void**)&rx, (void**)&rw, estimatedCodeSize));
35
+
36
+ // Relocate the code.
37
+ Error err = code->relocateToBase(uintptr_t((void*)rx));
38
+ if (ASMJIT_UNLIKELY(err)) {
39
+ _allocator.release(rx);
40
+ return err;
41
+ }
42
+
43
+ // Recalculate the final code size and shrink the memory we allocated for it
44
+ // in case that some relocations didn't require records in an address table.
45
+ size_t codeSize = code->codeSize();
46
+ if (codeSize < estimatedCodeSize)
47
+ _allocator.shrink(rx, codeSize);
48
+
49
+ if (codeSize < estimatedCodeSize)
50
+ _allocator.shrink(rx, codeSize);
51
+
52
+ {
53
+ VirtMem::ProtectJitReadWriteScope rwScope(rx, codeSize);
54
+
55
+ for (Section* section : code->_sections) {
56
+ size_t offset = size_t(section->offset());
57
+ size_t bufferSize = size_t(section->bufferSize());
58
+ size_t virtualSize = size_t(section->virtualSize());
59
+
60
+ ASMJIT_ASSERT(offset + bufferSize <= codeSize);
61
+ memcpy(rw + offset, section->data(), bufferSize);
62
+
63
+ if (virtualSize > bufferSize) {
64
+ ASMJIT_ASSERT(offset + virtualSize <= codeSize);
65
+ memset(rw + offset + bufferSize, 0, virtualSize - bufferSize);
66
+ }
67
+ }
68
+ }
69
+
70
+ *dst = rx;
71
+ return kErrorOk;
72
+ }
73
+
74
+ Error JitRuntime::_release(void* p) noexcept {
75
+ return _allocator.release(p);
76
+ }
77
+
78
+ ASMJIT_END_NAMESPACE
79
+
80
+ #endif
@@ -0,0 +1,89 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #ifndef ASMJIT_CORE_JITRUNTIME_H_INCLUDED
7
+ #define ASMJIT_CORE_JITRUNTIME_H_INCLUDED
8
+
9
+ #include "../core/api-config.h"
10
+ #ifndef ASMJIT_NO_JIT
11
+
12
+ #include "../core/codeholder.h"
13
+ #include "../core/jitallocator.h"
14
+ #include "../core/target.h"
15
+
16
+ ASMJIT_BEGIN_NAMESPACE
17
+
18
+ class CodeHolder;
19
+
20
+ //! \addtogroup asmjit_virtual_memory
21
+ //! \{
22
+
23
+ //! JIT execution runtime is a special `Target` that is designed to store and
24
+ //! execute the generated code.
25
+ class ASMJIT_VIRTAPI JitRuntime : public Target {
26
+ public:
27
+ ASMJIT_NONCOPYABLE(JitRuntime)
28
+
29
+ //! Virtual memory allocator.
30
+ JitAllocator _allocator;
31
+
32
+ //! \name Construction & Destruction
33
+ //! \{
34
+
35
+ //! Creates a `JitRuntime` instance.
36
+ ASMJIT_API explicit JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept;
37
+ //! Destroys the `JitRuntime` instance.
38
+ ASMJIT_API virtual ~JitRuntime() noexcept;
39
+
40
+ inline void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept {
41
+ _allocator.reset(resetPolicy);
42
+ }
43
+
44
+ //! \}
45
+
46
+ //! \name Accessors
47
+ //! \{
48
+
49
+ //! Returns the associated `JitAllocator`.
50
+ inline JitAllocator* allocator() const noexcept { return const_cast<JitAllocator*>(&_allocator); }
51
+
52
+ //! \}
53
+
54
+ //! \name Utilities
55
+ //! \{
56
+
57
+ // NOTE: To allow passing function pointers to `add()` and `release()` the
58
+ // virtual methods are prefixed with `_` and called from templates instead.
59
+
60
+ //! Allocates memory needed for a code stored in the `CodeHolder` and relocates the code to the pointer allocated.
61
+ //!
62
+ //! The beginning of the memory allocated for the function is returned in `dst`. If failed `Error` code is returned
63
+ //! and `dst` is explicitly set to `nullptr` (this means that you don't have to set it to null before calling `add()`).
64
+ template<typename Func>
65
+ inline Error add(Func* dst, CodeHolder* code) noexcept {
66
+ return _add(Support::ptr_cast_impl<void**, Func*>(dst), code);
67
+ }
68
+
69
+ //! Releases `p` which was obtained by calling `add()`.
70
+ template<typename Func>
71
+ inline Error release(Func p) noexcept {
72
+ return _release(Support::ptr_cast_impl<void*, Func>(p));
73
+ }
74
+
75
+ //! Type-unsafe version of `add()`.
76
+ ASMJIT_API virtual Error _add(void** dst, CodeHolder* code) noexcept;
77
+
78
+ //! Type-unsafe version of `release()`.
79
+ ASMJIT_API virtual Error _release(void* p) noexcept;
80
+
81
+ //! \}
82
+ };
83
+
84
+ //! \}
85
+
86
+ ASMJIT_END_NAMESPACE
87
+
88
+ #endif
89
+ #endif
@@ -0,0 +1,69 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #include "../core/api-build_p.h"
7
+ #ifndef ASMJIT_NO_LOGGING
8
+
9
+ #include "../core/logger.h"
10
+ #include "../core/string.h"
11
+ #include "../core/support.h"
12
+
13
+ ASMJIT_BEGIN_NAMESPACE
14
+
15
+ // Logger - Implementation
16
+ // =======================
17
+
18
+ Logger::Logger() noexcept
19
+ : _options() {}
20
+ Logger::~Logger() noexcept {}
21
+
22
+ Error Logger::logf(const char* fmt, ...) noexcept {
23
+ Error err;
24
+ va_list ap;
25
+
26
+ va_start(ap, fmt);
27
+ err = logv(fmt, ap);
28
+ va_end(ap);
29
+
30
+ return err;
31
+ }
32
+
33
+ Error Logger::logv(const char* fmt, va_list ap) noexcept {
34
+ StringTmp<2048> sb;
35
+ ASMJIT_PROPAGATE(sb.appendVFormat(fmt, ap));
36
+ return log(sb);
37
+ }
38
+
39
+ // FileLogger - Implementation
40
+ // ===========================
41
+
42
+ FileLogger::FileLogger(FILE* file) noexcept
43
+ : _file(file) {}
44
+ FileLogger::~FileLogger() noexcept {}
45
+
46
+ Error FileLogger::_log(const char* data, size_t size) noexcept {
47
+ if (!_file)
48
+ return kErrorOk;
49
+
50
+ if (size == SIZE_MAX)
51
+ size = strlen(data);
52
+
53
+ fwrite(data, 1, size, _file);
54
+ return kErrorOk;
55
+ }
56
+
57
+ // StringLogger - Implementation
58
+ // =============================
59
+
60
+ StringLogger::StringLogger() noexcept {}
61
+ StringLogger::~StringLogger() noexcept {}
62
+
63
+ Error StringLogger::_log(const char* data, size_t size) noexcept {
64
+ return _content.append(data, size);
65
+ }
66
+
67
+ ASMJIT_END_NAMESPACE
68
+
69
+ #endif
@@ -0,0 +1,198 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #ifndef ASMJIT_CORE_LOGGING_H_INCLUDED
7
+ #define ASMJIT_CORE_LOGGING_H_INCLUDED
8
+
9
+ #include "../core/inst.h"
10
+ #include "../core/string.h"
11
+ #include "../core/formatter.h"
12
+
13
+ #ifndef ASMJIT_NO_LOGGING
14
+
15
+ ASMJIT_BEGIN_NAMESPACE
16
+
17
+ //! \addtogroup asmjit_logging
18
+ //! \{
19
+
20
+ //! Logging interface.
21
+ //!
22
+ //! This class can be inherited and reimplemented to fit into your own logging needs. When reimplementing a logger
23
+ //! use \ref Logger::_log() method to log customize the output.
24
+ //!
25
+ //! There are two `Logger` implementations offered by AsmJit:
26
+ //! - \ref FileLogger - logs into a `FILE*`.
27
+ //! - \ref StringLogger - concatenates all logs into a \ref String.
28
+ class ASMJIT_VIRTAPI Logger {
29
+ public:
30
+ ASMJIT_BASE_CLASS(Logger)
31
+ ASMJIT_NONCOPYABLE(Logger)
32
+
33
+ //! Format options.
34
+ FormatOptions _options;
35
+
36
+ //! \name Construction & Destruction
37
+ //! \{
38
+
39
+ //! Creates a `Logger` instance.
40
+ ASMJIT_API Logger() noexcept;
41
+ //! Destroys the `Logger` instance.
42
+ ASMJIT_API virtual ~Logger() noexcept;
43
+
44
+ //! \}
45
+
46
+ //! \name Format Options
47
+ //! \{
48
+
49
+ //! Returns \ref FormatOptions of this logger.
50
+ inline FormatOptions& options() noexcept { return _options; }
51
+ //! \overload
52
+ inline const FormatOptions& options() const noexcept { return _options; }
53
+ //! Sets formatting options of this Logger to `options`.
54
+ inline void setOptions(const FormatOptions& options) noexcept { _options = options; }
55
+ //! Resets formatting options of this Logger to defaults.
56
+ inline void resetOptions() noexcept { _options.reset(); }
57
+
58
+ //! Returns formatting flags.
59
+ inline FormatFlags flags() const noexcept { return _options.flags(); }
60
+ //! Tests whether the logger has the given `flag` enabled.
61
+ inline bool hasFlag(FormatFlags flag) const noexcept { return _options.hasFlag(flag); }
62
+ //! Sets formatting flags to `flags`.
63
+ inline void setFlags(FormatFlags flags) noexcept { _options.setFlags(flags); }
64
+ //! Enables the given formatting `flags`.
65
+ inline void addFlags(FormatFlags flags) noexcept { _options.addFlags(flags); }
66
+ //! Disables the given formatting `flags`.
67
+ inline void clearFlags(FormatFlags flags) noexcept { _options.clearFlags(flags); }
68
+
69
+ //! Returns indentation of a given indentation `group`.
70
+ inline uint32_t indentation(FormatIndentationGroup type) const noexcept { return _options.indentation(type); }
71
+ //! Sets indentation of the given indentation `group` to `n` spaces.
72
+ inline void setIndentation(FormatIndentationGroup type, uint32_t n) noexcept { _options.setIndentation(type, n); }
73
+ //! Resets indentation of the given indentation `group` to 0 spaces.
74
+ inline void resetIndentation(FormatIndentationGroup type) noexcept { _options.resetIndentation(type); }
75
+
76
+ //! Returns padding of a given padding `group`.
77
+ inline size_t padding(FormatPaddingGroup type) const noexcept { return _options.padding(type); }
78
+ //! Sets padding of a given padding `group` to `n`.
79
+ inline void setPadding(FormatPaddingGroup type, uint32_t n) noexcept { _options.setPadding(type, n); }
80
+ //! Resets padding of a given padding `group` to 0, which means that a default will be used.
81
+ inline void resetPadding(FormatPaddingGroup type) noexcept { _options.resetPadding(type); }
82
+
83
+ //! \}
84
+
85
+ //! \name Logging Interface
86
+ //! \{
87
+
88
+ //! Logs `str` - must be reimplemented.
89
+ //!
90
+ //! The function can accept either a null terminated string if `size` is `SIZE_MAX` or a non-null terminated
91
+ //! string of the given `size`. The function cannot assume that the data is null terminated and must handle
92
+ //! non-null terminated inputs.
93
+ virtual Error _log(const char* data, size_t size) noexcept = 0;
94
+
95
+ //! Logs string `str`, which is either null terminated or having size `size`.
96
+ inline Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); }
97
+ //! Logs content of a string `str`.
98
+ inline Error log(const String& str) noexcept { return _log(str.data(), str.size()); }
99
+
100
+ //! Formats the message by using `snprintf()` and then passes the formatted string to \ref _log().
101
+ ASMJIT_API Error logf(const char* fmt, ...) noexcept;
102
+
103
+ //! Formats the message by using `vsnprintf()` and then passes the formatted string to \ref _log().
104
+ ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept;
105
+
106
+ //! \}
107
+ };
108
+
109
+ //! Logger that can log to a `FILE*`.
110
+ class ASMJIT_VIRTAPI FileLogger : public Logger {
111
+ public:
112
+ ASMJIT_NONCOPYABLE(FileLogger)
113
+
114
+ FILE* _file;
115
+
116
+ //! \name Construction & Destruction
117
+ //! \{
118
+
119
+ //! Creates a new `FileLogger` that logs to `FILE*`.
120
+ ASMJIT_API FileLogger(FILE* file = nullptr) noexcept;
121
+ //! Destroys the `FileLogger`.
122
+ ASMJIT_API virtual ~FileLogger() noexcept;
123
+
124
+ //! \}
125
+
126
+ //! \name Accessors
127
+ //! \{
128
+
129
+ //! Returns the logging output stream or null if the logger has no output stream.
130
+ inline FILE* file() const noexcept { return _file; }
131
+
132
+ //! Sets the logging output stream to `stream` or null.
133
+ //!
134
+ //! \note If the `file` is null the logging will be disabled. When a logger is attached to `CodeHolder` or any
135
+ //! emitter the logging API will always be called regardless of the output file. This means that if you really
136
+ //! want to disable logging at emitter level you must not attach a logger to it.
137
+ inline void setFile(FILE* file) noexcept { _file = file; }
138
+
139
+ //! \}
140
+
141
+ ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override;
142
+ };
143
+
144
+ //! Logger that stores everything in an internal string buffer.
145
+ class ASMJIT_VIRTAPI StringLogger : public Logger {
146
+ public:
147
+ ASMJIT_NONCOPYABLE(StringLogger)
148
+
149
+ //! Logger data as string.
150
+ String _content;
151
+
152
+ //! \name Construction & Destruction
153
+ //! \{
154
+
155
+ //! Create new `StringLogger`.
156
+ ASMJIT_API StringLogger() noexcept;
157
+ //! Destroys the `StringLogger`.
158
+ ASMJIT_API virtual ~StringLogger() noexcept;
159
+
160
+ //! \}
161
+
162
+ //! \name Logger Data Accessors
163
+ //! \{
164
+
165
+ //! Returns the content of the logger as \ref String.
166
+ //!
167
+ //! It can be moved, if desired.
168
+ inline String& content() noexcept { return _content; }
169
+ //! \overload
170
+ inline const String& content() const noexcept { return _content; }
171
+
172
+ //! Returns aggregated logger data as `char*` pointer.
173
+ //!
174
+ //! The pointer is owned by `StringLogger`, it can't be modified or freed.
175
+ inline const char* data() const noexcept { return _content.data(); }
176
+ //! Returns size of the data returned by `data()`.
177
+ inline size_t dataSize() const noexcept { return _content.size(); }
178
+
179
+ //! \}
180
+
181
+ //! \name Logger Data Manipulation
182
+ //! \{
183
+
184
+ //! Clears the accumulated logger data.
185
+ inline void clear() noexcept { _content.clear(); }
186
+
187
+ //! \}
188
+
189
+ ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override;
190
+ };
191
+
192
+ //! \}
193
+
194
+ ASMJIT_END_NAMESPACE
195
+
196
+ #endif
197
+
198
+ #endif // ASMJIT_CORE_LOGGER_H_INCLUDED