asmjit 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/asmjit.gemspec +1 -1
  4. data/ext/asmjit/asmjit/.editorconfig +10 -0
  5. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  6. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  8. data/ext/asmjit/asmjit/.gitignore +6 -0
  9. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  10. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  11. data/ext/asmjit/asmjit/README.md +69 -0
  12. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  13. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  43. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  46. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  133. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  159. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  160. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  179. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  180. data/ext/asmjit/asmjit/test/broken.h +148 -0
  181. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  182. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  183. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  184. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  191. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  193. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  197. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  199. data/ext/asmjit/asmjit.cc +18 -0
  200. data/lib/asmjit/version.rb +1 -1
  201. metadata +197 -2
@@ -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