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,356 @@
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
+ #include "../core/support.h"
8
+ #include "../core/zone.h"
9
+ #include "../core/zonevector.h"
10
+
11
+ ASMJIT_BEGIN_NAMESPACE
12
+
13
+ // ZoneVectorBase - Helpers
14
+ // ========================
15
+
16
+ Error ZoneVectorBase::_grow(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
17
+ uint32_t threshold = Globals::kGrowThreshold / sizeOfT;
18
+ uint32_t capacity = _capacity;
19
+ uint32_t after = _size;
20
+
21
+ if (ASMJIT_UNLIKELY(std::numeric_limits<uint32_t>::max() - n < after))
22
+ return DebugUtils::errored(kErrorOutOfMemory);
23
+
24
+ after += n;
25
+ if (capacity >= after)
26
+ return kErrorOk;
27
+
28
+ // ZoneVector is used as an array to hold short-lived data structures used
29
+ // during code generation. The growing strategy is simple - use small capacity
30
+ // at the beginning (very good for ZoneAllocator) and then grow quicker to
31
+ // prevent successive reallocations.
32
+ if (capacity < 4)
33
+ capacity = 4;
34
+ else if (capacity < 8)
35
+ capacity = 8;
36
+ else if (capacity < 16)
37
+ capacity = 16;
38
+ else if (capacity < 64)
39
+ capacity = 64;
40
+ else if (capacity < 256)
41
+ capacity = 256;
42
+
43
+ while (capacity < after) {
44
+ if (capacity < threshold)
45
+ capacity *= 2;
46
+ else
47
+ capacity += threshold;
48
+ }
49
+
50
+ return _reserve(allocator, sizeOfT, capacity);
51
+ }
52
+
53
+ Error ZoneVectorBase::_reserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
54
+ uint32_t oldCapacity = _capacity;
55
+ if (oldCapacity >= n) return kErrorOk;
56
+
57
+ uint32_t nBytes = n * sizeOfT;
58
+ if (ASMJIT_UNLIKELY(nBytes < n))
59
+ return DebugUtils::errored(kErrorOutOfMemory);
60
+
61
+ size_t allocatedBytes;
62
+ uint8_t* newData = static_cast<uint8_t*>(allocator->alloc(nBytes, allocatedBytes));
63
+
64
+ if (ASMJIT_UNLIKELY(!newData))
65
+ return DebugUtils::errored(kErrorOutOfMemory);
66
+
67
+ void* oldData = _data;
68
+ if (_size)
69
+ memcpy(newData, oldData, size_t(_size) * sizeOfT);
70
+
71
+ if (oldData)
72
+ allocator->release(oldData, size_t(oldCapacity) * sizeOfT);
73
+
74
+ _capacity = uint32_t(allocatedBytes / sizeOfT);
75
+ ASMJIT_ASSERT(_capacity >= n);
76
+
77
+ _data = newData;
78
+ return kErrorOk;
79
+ }
80
+
81
+ Error ZoneVectorBase::_resize(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
82
+ uint32_t size = _size;
83
+
84
+ if (_capacity < n) {
85
+ ASMJIT_PROPAGATE(_grow(allocator, sizeOfT, n - size));
86
+ ASMJIT_ASSERT(_capacity >= n);
87
+ }
88
+
89
+ if (size < n)
90
+ memset(static_cast<uint8_t*>(_data) + size_t(size) * sizeOfT, 0, size_t(n - size) * sizeOfT);
91
+
92
+ _size = n;
93
+ return kErrorOk;
94
+ }
95
+
96
+ // ZoneBitVector - Operations
97
+ // ==========================
98
+
99
+ Error ZoneBitVector::copyFrom(ZoneAllocator* allocator, const ZoneBitVector& other) noexcept {
100
+ BitWord* data = _data;
101
+ uint32_t newSize = other.size();
102
+
103
+ if (!newSize) {
104
+ _size = 0;
105
+ return kErrorOk;
106
+ }
107
+
108
+ if (newSize > _capacity) {
109
+ // Realloc needed... Calculate the minimum capacity (in bytes) required.
110
+ uint32_t minimumCapacityInBits = Support::alignUp<uint32_t>(newSize, kBitWordSizeInBits);
111
+ if (ASMJIT_UNLIKELY(minimumCapacityInBits < newSize))
112
+ return DebugUtils::errored(kErrorOutOfMemory);
113
+
114
+ // Normalize to bytes.
115
+ uint32_t minimumCapacity = minimumCapacityInBits / 8;
116
+ size_t allocatedCapacity;
117
+
118
+ BitWord* newData = static_cast<BitWord*>(allocator->alloc(minimumCapacity, allocatedCapacity));
119
+ if (ASMJIT_UNLIKELY(!newData))
120
+ return DebugUtils::errored(kErrorOutOfMemory);
121
+
122
+ // `allocatedCapacity` now contains number in bytes, we need bits.
123
+ size_t allocatedCapacityInBits = allocatedCapacity * 8;
124
+
125
+ // Arithmetic overflow should normally not happen. If it happens we just
126
+ // change the `allocatedCapacityInBits` to the `minimumCapacityInBits` as
127
+ // this value is still safe to be used to call `_allocator->release(...)`.
128
+ if (ASMJIT_UNLIKELY(allocatedCapacityInBits < allocatedCapacity))
129
+ allocatedCapacityInBits = minimumCapacityInBits;
130
+
131
+ if (data)
132
+ allocator->release(data, _capacity / 8);
133
+ data = newData;
134
+
135
+ _data = data;
136
+ _capacity = uint32_t(allocatedCapacityInBits);
137
+ }
138
+
139
+ _size = newSize;
140
+ _copyBits(data, other.data(), _wordsPerBits(newSize));
141
+
142
+ return kErrorOk;
143
+ }
144
+
145
+ Error ZoneBitVector::_resize(ZoneAllocator* allocator, uint32_t newSize, uint32_t idealCapacity, bool newBitsValue) noexcept {
146
+ ASMJIT_ASSERT(idealCapacity >= newSize);
147
+
148
+ if (newSize <= _size) {
149
+ // The size after the resize is lesser than or equal to the current size.
150
+ uint32_t idx = newSize / kBitWordSizeInBits;
151
+ uint32_t bit = newSize % kBitWordSizeInBits;
152
+
153
+ // Just set all bits outside of the new size in the last word to zero.
154
+ // There is a case that there are not bits to set if `bit` is zero. This
155
+ // happens when `newSize` is a multiply of `kBitWordSizeInBits` like 64, 128,
156
+ // and so on. In that case don't change anything as that would mean settings
157
+ // bits outside of the `_size`.
158
+ if (bit)
159
+ _data[idx] &= (BitWord(1) << bit) - 1u;
160
+
161
+ _size = newSize;
162
+ return kErrorOk;
163
+ }
164
+
165
+ uint32_t oldSize = _size;
166
+ BitWord* data = _data;
167
+
168
+ if (newSize > _capacity) {
169
+ // Realloc needed, calculate the minimum capacity (in bytes) required.
170
+ uint32_t minimumCapacityInBits = Support::alignUp<uint32_t>(idealCapacity, kBitWordSizeInBits);
171
+
172
+ if (ASMJIT_UNLIKELY(minimumCapacityInBits < newSize))
173
+ return DebugUtils::errored(kErrorOutOfMemory);
174
+
175
+ // Normalize to bytes.
176
+ uint32_t minimumCapacity = minimumCapacityInBits / 8;
177
+ size_t allocatedCapacity;
178
+
179
+ BitWord* newData = static_cast<BitWord*>(allocator->alloc(minimumCapacity, allocatedCapacity));
180
+ if (ASMJIT_UNLIKELY(!newData))
181
+ return DebugUtils::errored(kErrorOutOfMemory);
182
+
183
+ // `allocatedCapacity` now contains number in bytes, we need bits.
184
+ size_t allocatedCapacityInBits = allocatedCapacity * 8;
185
+
186
+ // Arithmetic overflow should normally not happen. If it happens we just
187
+ // change the `allocatedCapacityInBits` to the `minimumCapacityInBits` as
188
+ // this value is still safe to be used to call `_allocator->release(...)`.
189
+ if (ASMJIT_UNLIKELY(allocatedCapacityInBits < allocatedCapacity))
190
+ allocatedCapacityInBits = minimumCapacityInBits;
191
+
192
+ _copyBits(newData, data, _wordsPerBits(oldSize));
193
+
194
+ if (data)
195
+ allocator->release(data, _capacity / 8);
196
+ data = newData;
197
+
198
+ _data = data;
199
+ _capacity = uint32_t(allocatedCapacityInBits);
200
+ }
201
+
202
+ // Start (of the old size) and end (of the new size) bits
203
+ uint32_t idx = oldSize / kBitWordSizeInBits;
204
+ uint32_t startBit = oldSize % kBitWordSizeInBits;
205
+ uint32_t endBit = newSize % kBitWordSizeInBits;
206
+
207
+ // Set new bits to either 0 or 1. The `pattern` is used to set multiple
208
+ // bits per bit-word and contains either all zeros or all ones.
209
+ BitWord pattern = Support::bitMaskFromBool<BitWord>(newBitsValue);
210
+
211
+ // First initialize the last bit-word of the old size.
212
+ if (startBit) {
213
+ uint32_t nBits = 0;
214
+
215
+ if (idx == (newSize / kBitWordSizeInBits)) {
216
+ // The number of bit-words is the same after the resize. In that case
217
+ // we need to set only bits necessary in the current last bit-word.
218
+ ASMJIT_ASSERT(startBit < endBit);
219
+ nBits = endBit - startBit;
220
+ }
221
+ else {
222
+ // There is be more bit-words after the resize. In that case we don't
223
+ // have to be extra careful about the last bit-word of the old size.
224
+ nBits = kBitWordSizeInBits - startBit;
225
+ }
226
+
227
+ data[idx++] |= pattern << nBits;
228
+ }
229
+
230
+ // Initialize all bit-words after the last bit-word of the old size.
231
+ uint32_t endIdx = _wordsPerBits(newSize);
232
+ while (idx < endIdx) data[idx++] = pattern;
233
+
234
+ // Clear unused bits of the last bit-word.
235
+ if (endBit)
236
+ data[endIdx - 1] = pattern & ((BitWord(1) << endBit) - 1);
237
+
238
+ _size = newSize;
239
+ return kErrorOk;
240
+ }
241
+
242
+ Error ZoneBitVector::_append(ZoneAllocator* allocator, bool value) noexcept {
243
+ uint32_t kThreshold = Globals::kGrowThreshold * 8;
244
+ uint32_t newSize = _size + 1;
245
+ uint32_t idealCapacity = _capacity;
246
+
247
+ if (idealCapacity < 128)
248
+ idealCapacity = 128;
249
+ else if (idealCapacity <= kThreshold)
250
+ idealCapacity *= 2;
251
+ else
252
+ idealCapacity += kThreshold;
253
+
254
+ if (ASMJIT_UNLIKELY(idealCapacity < _capacity)) {
255
+ if (ASMJIT_UNLIKELY(_size == std::numeric_limits<uint32_t>::max()))
256
+ return DebugUtils::errored(kErrorOutOfMemory);
257
+ idealCapacity = newSize;
258
+ }
259
+
260
+ return _resize(allocator, newSize, idealCapacity, value);
261
+ }
262
+
263
+ // ZoneVector / ZoneBitVector - Tests
264
+ // ==================================
265
+
266
+ #if defined(ASMJIT_TEST)
267
+ template<typename T>
268
+ static void test_zone_vector(ZoneAllocator* allocator, const char* typeName) {
269
+ int i;
270
+ int kMax = 100000;
271
+
272
+ ZoneVector<T> vec;
273
+
274
+ INFO("ZoneVector<%s> basic tests", typeName);
275
+ EXPECT(vec.append(allocator, 0) == kErrorOk);
276
+ EXPECT(vec.empty() == false);
277
+ EXPECT(vec.size() == 1);
278
+ EXPECT(vec.capacity() >= 1);
279
+ EXPECT(vec.indexOf(0) == 0);
280
+ EXPECT(vec.indexOf(-11) == Globals::kNotFound);
281
+
282
+ vec.clear();
283
+ EXPECT(vec.empty());
284
+ EXPECT(vec.size() == 0);
285
+ EXPECT(vec.indexOf(0) == Globals::kNotFound);
286
+
287
+ for (i = 0; i < kMax; i++) {
288
+ EXPECT(vec.append(allocator, T(i)) == kErrorOk);
289
+ }
290
+ EXPECT(vec.empty() == false);
291
+ EXPECT(vec.size() == uint32_t(kMax));
292
+ EXPECT(vec.indexOf(T(kMax - 1)) == uint32_t(kMax - 1));
293
+
294
+ EXPECT(vec.rbegin()[0] == kMax - 1);
295
+
296
+ vec.release(allocator);
297
+ }
298
+
299
+ static void test_zone_bitvector(ZoneAllocator* allocator) {
300
+ Zone zone(8096 - Zone::kBlockOverhead);
301
+
302
+ uint32_t i, count;
303
+ uint32_t kMaxCount = 100;
304
+
305
+ ZoneBitVector vec;
306
+ EXPECT(vec.empty());
307
+ EXPECT(vec.size() == 0);
308
+
309
+ INFO("ZoneBitVector::resize()");
310
+ for (count = 1; count < kMaxCount; count++) {
311
+ vec.clear();
312
+ EXPECT(vec.resize(allocator, count, false) == kErrorOk);
313
+ EXPECT(vec.size() == count);
314
+
315
+ for (i = 0; i < count; i++)
316
+ EXPECT(vec.bitAt(i) == false);
317
+
318
+ vec.clear();
319
+ EXPECT(vec.resize(allocator, count, true) == kErrorOk);
320
+ EXPECT(vec.size() == count);
321
+
322
+ for (i = 0; i < count; i++)
323
+ EXPECT(vec.bitAt(i) == true);
324
+ }
325
+
326
+ INFO("ZoneBitVector::fillBits() / clearBits()");
327
+ for (count = 1; count < kMaxCount; count += 2) {
328
+ vec.clear();
329
+ EXPECT(vec.resize(allocator, count) == kErrorOk);
330
+ EXPECT(vec.size() == count);
331
+
332
+ for (i = 0; i < (count + 1) / 2; i++) {
333
+ bool value = bool(i & 1);
334
+ if (value)
335
+ vec.fillBits(i, count - i * 2);
336
+ else
337
+ vec.clearBits(i, count - i * 2);
338
+ }
339
+
340
+ for (i = 0; i < count; i++) {
341
+ EXPECT(vec.bitAt(i) == bool(i & 1));
342
+ }
343
+ }
344
+ }
345
+
346
+ UNIT(zone_vector) {
347
+ Zone zone(8096 - Zone::kBlockOverhead);
348
+ ZoneAllocator allocator(&zone);
349
+
350
+ test_zone_vector<int>(&allocator, "int");
351
+ test_zone_vector<int64_t>(&allocator, "int64_t");
352
+ test_zone_bitvector(&allocator);
353
+ }
354
+ #endif
355
+
356
+ ASMJIT_END_NAMESPACE