@shd101wyy/yo 0.0.2

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 (339) hide show
  1. package/LICENSE.md +17 -0
  2. package/README.md +80 -0
  3. package/out/cjs/index.cjs +51 -0
  4. package/out/cjs/yo-cli.cjs +2158 -0
  5. package/out/esm/index.mjs +51 -0
  6. package/out/types/src/codegen/async/runtime.d.ts +2 -0
  7. package/out/types/src/codegen/async/state-code-gen.d.ts +10 -0
  8. package/out/types/src/codegen/async/state-machine.d.ts +13 -0
  9. package/out/types/src/codegen/c/collection.d.ts +3 -0
  10. package/out/types/src/codegen/codegen-c.d.ts +12 -0
  11. package/out/types/src/codegen/constants.d.ts +3 -0
  12. package/out/types/src/codegen/expressions/array.d.ts +4 -0
  13. package/out/types/src/codegen/expressions/generation.d.ts +11 -0
  14. package/out/types/src/codegen/expressions/index.d.ts +2 -0
  15. package/out/types/src/codegen/functions/collection.d.ts +5 -0
  16. package/out/types/src/codegen/functions/context.d.ts +57 -0
  17. package/out/types/src/codegen/functions/generation.d.ts +25 -0
  18. package/out/types/src/codegen/functions/index.d.ts +2 -0
  19. package/out/types/src/codegen/index.d.ts +20 -0
  20. package/out/types/src/codegen/parallelism/runtime.d.ts +2 -0
  21. package/out/types/src/codegen/types/collection.d.ts +8 -0
  22. package/out/types/src/codegen/types/generation.d.ts +13 -0
  23. package/out/types/src/codegen/types/index.d.ts +2 -0
  24. package/out/types/src/codegen/utils/fixup.d.ts +2 -0
  25. package/out/types/src/codegen/utils/index.d.ts +77 -0
  26. package/out/types/src/codegen/values/index.d.ts +1 -0
  27. package/out/types/src/emitter.d.ts +11 -0
  28. package/out/types/src/env.d.ts +85 -0
  29. package/out/types/src/error.d.ts +45 -0
  30. package/out/types/src/evaluator/async/await-analysis-types.d.ts +23 -0
  31. package/out/types/src/evaluator/async/await-analysis.d.ts +5 -0
  32. package/out/types/src/evaluator/builtins/alignof.d.ts +8 -0
  33. package/out/types/src/evaluator/builtins/and_or.d.ts +8 -0
  34. package/out/types/src/evaluator/builtins/arc_fns.d.ts +58 -0
  35. package/out/types/src/evaluator/builtins/array_fns.d.ts +0 -0
  36. package/out/types/src/evaluator/builtins/as.d.ts +8 -0
  37. package/out/types/src/evaluator/builtins/async_fns.d.ts +8 -0
  38. package/out/types/src/evaluator/builtins/compt_assert.d.ts +8 -0
  39. package/out/types/src/evaluator/builtins/compt_boolean_fns.d.ts +8 -0
  40. package/out/types/src/evaluator/builtins/compt_expect_error.d.ts +8 -0
  41. package/out/types/src/evaluator/builtins/compt_list_fns.d.ts +33 -0
  42. package/out/types/src/evaluator/builtins/compt_print.d.ts +8 -0
  43. package/out/types/src/evaluator/builtins/compt_string_fns.d.ts +8 -0
  44. package/out/types/src/evaluator/builtins/consume.d.ts +8 -0
  45. package/out/types/src/evaluator/builtins/drop.d.ts +8 -0
  46. package/out/types/src/evaluator/builtins/dup.d.ts +8 -0
  47. package/out/types/src/evaluator/builtins/expr_fns.d.ts +33 -0
  48. package/out/types/src/evaluator/builtins/future_fns.d.ts +8 -0
  49. package/out/types/src/evaluator/builtins/gc.d.ts +8 -0
  50. package/out/types/src/evaluator/builtins/gensym.d.ts +8 -0
  51. package/out/types/src/evaluator/builtins/impl_constraint.d.ts +8 -0
  52. package/out/types/src/evaluator/builtins/macro_expand.d.ts +8 -0
  53. package/out/types/src/evaluator/builtins/numeric_fns.d.ts +8 -0
  54. package/out/types/src/evaluator/builtins/panic.d.ts +8 -0
  55. package/out/types/src/evaluator/builtins/ptr_fns.d.ts +8 -0
  56. package/out/types/src/evaluator/builtins/quote.d.ts +13 -0
  57. package/out/types/src/evaluator/builtins/rc.d.ts +8 -0
  58. package/out/types/src/evaluator/builtins/sizeof.d.ts +8 -0
  59. package/out/types/src/evaluator/builtins/the.d.ts +8 -0
  60. package/out/types/src/evaluator/builtins/type_fns.d.ts +28 -0
  61. package/out/types/src/evaluator/builtins/va_start.d.ts +8 -0
  62. package/out/types/src/evaluator/builtins/var_fns.d.ts +18 -0
  63. package/out/types/src/evaluator/calls/array.d.ts +13 -0
  64. package/out/types/src/evaluator/calls/array_type.d.ts +11 -0
  65. package/out/types/src/evaluator/calls/closure_type.d.ts +11 -0
  66. package/out/types/src/evaluator/calls/compt_function.d.ts +19 -0
  67. package/out/types/src/evaluator/calls/compt_list_type.d.ts +11 -0
  68. package/out/types/src/evaluator/calls/function.d.ts +16 -0
  69. package/out/types/src/evaluator/calls/function_type.d.ts +15 -0
  70. package/out/types/src/evaluator/calls/helper.d.ts +42 -0
  71. package/out/types/src/evaluator/calls/iso.d.ts +15 -0
  72. package/out/types/src/evaluator/calls/module_type.d.ts +11 -0
  73. package/out/types/src/evaluator/calls/numeric_type.d.ts +15 -0
  74. package/out/types/src/evaluator/calls/pointer.d.ts +8 -0
  75. package/out/types/src/evaluator/calls/pointer_type.d.ts +14 -0
  76. package/out/types/src/evaluator/calls/type.d.ts +12 -0
  77. package/out/types/src/evaluator/context.d.ts +169 -0
  78. package/out/types/src/evaluator/exprs/_expr.d.ts +8 -0
  79. package/out/types/src/evaluator/exprs/assignment.d.ts +9 -0
  80. package/out/types/src/evaluator/exprs/begin.d.ts +10 -0
  81. package/out/types/src/evaluator/exprs/binding.d.ts +12 -0
  82. package/out/types/src/evaluator/exprs/c_include.d.ts +8 -0
  83. package/out/types/src/evaluator/exprs/cond.d.ts +8 -0
  84. package/out/types/src/evaluator/exprs/destructuring_assignment.d.ts +33 -0
  85. package/out/types/src/evaluator/exprs/exists.d.ts +0 -0
  86. package/out/types/src/evaluator/exprs/expr.d.ts +9 -0
  87. package/out/types/src/evaluator/exprs/extern.d.ts +8 -0
  88. package/out/types/src/evaluator/exprs/identifer_and_operator.d.ts +9 -0
  89. package/out/types/src/evaluator/exprs/import.d.ts +9 -0
  90. package/out/types/src/evaluator/exprs/initialization_assignment.d.ts +8 -0
  91. package/out/types/src/evaluator/exprs/match.d.ts +8 -0
  92. package/out/types/src/evaluator/exprs/open.d.ts +8 -0
  93. package/out/types/src/evaluator/exprs/property_access.d.ts +8 -0
  94. package/out/types/src/evaluator/exprs/recur.d.ts +8 -0
  95. package/out/types/src/evaluator/exprs/subtype_of.d.ts +21 -0
  96. package/out/types/src/evaluator/exprs/test.d.ts +8 -0
  97. package/out/types/src/evaluator/exprs/typeof.d.ts +8 -0
  98. package/out/types/src/evaluator/exprs/while.d.ts +8 -0
  99. package/out/types/src/evaluator/index.d.ts +26 -0
  100. package/out/types/src/evaluator/types/array.d.ts +8 -0
  101. package/out/types/src/evaluator/types/closure.d.ts +8 -0
  102. package/out/types/src/evaluator/types/compt_list.d.ts +8 -0
  103. package/out/types/src/evaluator/types/concrete_module.d.ts +8 -0
  104. package/out/types/src/evaluator/types/dyn.d.ts +8 -0
  105. package/out/types/src/evaluator/types/enum.d.ts +8 -0
  106. package/out/types/src/evaluator/types/expr_synthesizer.d.ts +14 -0
  107. package/out/types/src/evaluator/types/field.d.ts +14 -0
  108. package/out/types/src/evaluator/types/fn_module.d.ts +8 -0
  109. package/out/types/src/evaluator/types/function.d.ts +58 -0
  110. package/out/types/src/evaluator/types/future_module.d.ts +8 -0
  111. package/out/types/src/evaluator/types/module.d.ts +19 -0
  112. package/out/types/src/evaluator/types/newtype.d.ts +8 -0
  113. package/out/types/src/evaluator/types/object.d.ts +8 -0
  114. package/out/types/src/evaluator/types/proofs.d.ts +0 -0
  115. package/out/types/src/evaluator/types/slice.d.ts +8 -0
  116. package/out/types/src/evaluator/types/struct.d.ts +8 -0
  117. package/out/types/src/evaluator/types/synthesizer.d.ts +16 -0
  118. package/out/types/src/evaluator/types/tuple.d.ts +18 -0
  119. package/out/types/src/evaluator/types/union.d.ts +8 -0
  120. package/out/types/src/evaluator/types/utils.d.ts +71 -0
  121. package/out/types/src/evaluator/types/validation.d.ts +3 -0
  122. package/out/types/src/evaluator/utils/array-utils.d.ts +15 -0
  123. package/out/types/src/evaluator/utils/closure.d.ts +35 -0
  124. package/out/types/src/evaluator/utils.d.ts +4 -0
  125. package/out/types/src/evaluator/values/anonymous_function.d.ts +8 -0
  126. package/out/types/src/evaluator/values/anonymous_module.d.ts +17 -0
  127. package/out/types/src/evaluator/values/anonymous_struct.d.ts +8 -0
  128. package/out/types/src/evaluator/values/array.d.ts +8 -0
  129. package/out/types/src/evaluator/values/boolean.d.ts +3 -0
  130. package/out/types/src/evaluator/values/char.d.ts +3 -0
  131. package/out/types/src/evaluator/values/compt_list.d.ts +8 -0
  132. package/out/types/src/evaluator/values/dyn.d.ts +8 -0
  133. package/out/types/src/evaluator/values/float.d.ts +4 -0
  134. package/out/types/src/evaluator/values/integer.d.ts +4 -0
  135. package/out/types/src/evaluator/values/module.d.ts +58 -0
  136. package/out/types/src/evaluator/values/string.d.ts +3 -0
  137. package/out/types/src/evaluator/values/tuple.d.ts +32 -0
  138. package/out/types/src/expr.d.ts +456 -0
  139. package/out/types/src/function-value.d.ts +42 -0
  140. package/out/types/src/index.d.ts +4 -0
  141. package/out/types/src/lexer.d.ts +2 -0
  142. package/out/types/src/logger.d.ts +1 -0
  143. package/out/types/src/module-manager.d.ts +30 -0
  144. package/out/types/src/naming-checker.d.ts +4 -0
  145. package/out/types/src/parser.d.ts +33 -0
  146. package/out/types/src/test-runner.d.ts +30 -0
  147. package/out/types/src/tests/codegen.test.d.ts +1 -0
  148. package/out/types/src/tests/fixme.test.d.ts +1 -0
  149. package/out/types/src/tests/module-manager.test.d.ts +1 -0
  150. package/out/types/src/tests/parser.test.d.ts +1 -0
  151. package/out/types/src/tests/sample.test.d.ts +0 -0
  152. package/out/types/src/tests/std.test.d.ts +1 -0
  153. package/out/types/src/token.d.ts +40 -0
  154. package/out/types/src/type-value.d.ts +7 -0
  155. package/out/types/src/types/compatibility.d.ts +16 -0
  156. package/out/types/src/types/creators.d.ts +73 -0
  157. package/out/types/src/types/definitions.d.ts +218 -0
  158. package/out/types/src/types/guards.d.ts +70 -0
  159. package/out/types/src/types/hierarchy.d.ts +4 -0
  160. package/out/types/src/types/index.d.ts +7 -0
  161. package/out/types/src/types/module_field.d.ts +2 -0
  162. package/out/types/src/types/tags.d.ts +45 -0
  163. package/out/types/src/types/utils.d.ts +50 -0
  164. package/out/types/src/unit-value.d.ts +7 -0
  165. package/out/types/src/utils.d.ts +6 -0
  166. package/out/types/src/value-tag.d.ts +29 -0
  167. package/out/types/src/value.d.ts +110 -0
  168. package/out/types/src/yo-cli.d.ts +1 -0
  169. package/out/types/tsconfig.tsbuildinfo +1 -0
  170. package/package.json +57 -0
  171. package/scripts/check-liburing.js +76 -0
  172. package/std/alg/hash.yo +50 -0
  173. package/std/allocator.yo +113 -0
  174. package/std/allocators/c_allocator.yo +118 -0
  175. package/std/async.yo +13 -0
  176. package/std/collections/array_list.yo +415 -0
  177. package/std/collections/hash_map.yo +482 -0
  178. package/std/collections/hash_set.yo +706 -0
  179. package/std/collections/index.yo +11 -0
  180. package/std/collections/linked_list.yo +439 -0
  181. package/std/error.yo +0 -0
  182. package/std/gc.yo +10 -0
  183. package/std/index.yo +12 -0
  184. package/std/io/file.yo +191 -0
  185. package/std/io/index.yo +5 -0
  186. package/std/libc/assert.yo +39 -0
  187. package/std/libc/ctype.yo +57 -0
  188. package/std/libc/errno.yo +182 -0
  189. package/std/libc/float.yo +87 -0
  190. package/std/libc/index.yo +29 -0
  191. package/std/libc/limits.yo +65 -0
  192. package/std/libc/math.yo +679 -0
  193. package/std/libc/signal.yo +101 -0
  194. package/std/libc/stdatomic.yo +213 -0
  195. package/std/libc/stdint.yo +214 -0
  196. package/std/libc/stdio.yo +225 -0
  197. package/std/libc/stdlib.yo +204 -0
  198. package/std/libc/string.yo +151 -0
  199. package/std/libc/time.yo +92 -0
  200. package/std/libc/unistd.yo +130 -0
  201. package/std/monad.yo +152 -0
  202. package/std/prelude.yo +3094 -0
  203. package/std/string/index.yo +8 -0
  204. package/std/string/rune.yo +82 -0
  205. package/std/string/string.yo +288 -0
  206. package/std/sync.yo +95 -0
  207. package/std/thread.yo +36 -0
  208. package/std/time.yo +13 -0
  209. package/std/worker.yo +36 -0
  210. package/vendor/mimalloc/.gitattributes +12 -0
  211. package/vendor/mimalloc/CMakeLists.txt +763 -0
  212. package/vendor/mimalloc/LICENSE +21 -0
  213. package/vendor/mimalloc/SECURITY.md +41 -0
  214. package/vendor/mimalloc/azure-pipelines.yml +251 -0
  215. package/vendor/mimalloc/bin/mimalloc-redirect-arm64.dll +0 -0
  216. package/vendor/mimalloc/bin/mimalloc-redirect-arm64.lib +0 -0
  217. package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.dll +0 -0
  218. package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.lib +0 -0
  219. package/vendor/mimalloc/bin/mimalloc-redirect.dll +0 -0
  220. package/vendor/mimalloc/bin/mimalloc-redirect.lib +0 -0
  221. package/vendor/mimalloc/bin/mimalloc-redirect32.dll +0 -0
  222. package/vendor/mimalloc/bin/mimalloc-redirect32.lib +0 -0
  223. package/vendor/mimalloc/bin/minject-arm64.exe +0 -0
  224. package/vendor/mimalloc/bin/minject.exe +0 -0
  225. package/vendor/mimalloc/bin/minject32.exe +0 -0
  226. package/vendor/mimalloc/bin/readme.md +118 -0
  227. package/vendor/mimalloc/cmake/JoinPaths.cmake +23 -0
  228. package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +19 -0
  229. package/vendor/mimalloc/cmake/mimalloc-config.cmake +14 -0
  230. package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +23 -0
  231. package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +28 -0
  232. package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +28 -0
  233. package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +23 -0
  234. package/vendor/mimalloc/contrib/docker/readme.md +10 -0
  235. package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +64 -0
  236. package/vendor/mimalloc/contrib/vcpkg/readme.md +40 -0
  237. package/vendor/mimalloc/contrib/vcpkg/usage +20 -0
  238. package/vendor/mimalloc/contrib/vcpkg/vcpkg-cmake-wrapper.cmake +20 -0
  239. package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +48 -0
  240. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg +887 -0
  241. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg +1185 -0
  242. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg +757 -0
  243. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg +1028 -0
  244. package/vendor/mimalloc/doc/bench-2020/bench-r5a-1.svg +769 -0
  245. package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg +868 -0
  246. package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg +1157 -0
  247. package/vendor/mimalloc/doc/bench-2020/bench-r5a-2.svg +983 -0
  248. package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg +683 -0
  249. package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg +854 -0
  250. package/vendor/mimalloc/doc/bench-2020/bench-spec-rss.svg +713 -0
  251. package/vendor/mimalloc/doc/bench-2020/bench-spec.svg +713 -0
  252. package/vendor/mimalloc/doc/bench-2020/bench-z4-1.svg +890 -0
  253. package/vendor/mimalloc/doc/bench-2020/bench-z4-2.svg +1146 -0
  254. package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-1.svg +796 -0
  255. package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-2.svg +974 -0
  256. package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg +952 -0
  257. package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg +1255 -0
  258. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg +955 -0
  259. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg +1269 -0
  260. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg +836 -0
  261. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg +1131 -0
  262. package/vendor/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg +766 -0
  263. package/vendor/mimalloc/doc/doxyfile +2895 -0
  264. package/vendor/mimalloc/doc/ds-logo.jpg +0 -0
  265. package/vendor/mimalloc/doc/ds-logo.png +0 -0
  266. package/vendor/mimalloc/doc/mimalloc-doc.h +1452 -0
  267. package/vendor/mimalloc/doc/mimalloc-doxygen.css +60 -0
  268. package/vendor/mimalloc/doc/mimalloc-logo-100.png +0 -0
  269. package/vendor/mimalloc/doc/mimalloc-logo.png +0 -0
  270. package/vendor/mimalloc/doc/mimalloc-logo.svg +161 -0
  271. package/vendor/mimalloc/doc/spades-logo.png +0 -0
  272. package/vendor/mimalloc/doc/unreal-logo.svg +43 -0
  273. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +500 -0
  274. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj.filters +108 -0
  275. package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj +508 -0
  276. package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj.filters +111 -0
  277. package/vendor/mimalloc/ide/vs2022/mimalloc-override-test-dep.vcxproj +355 -0
  278. package/vendor/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj +360 -0
  279. package/vendor/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj +295 -0
  280. package/vendor/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj +292 -0
  281. package/vendor/mimalloc/ide/vs2022/mimalloc-test.vcxproj +289 -0
  282. package/vendor/mimalloc/ide/vs2022/mimalloc.sln +151 -0
  283. package/vendor/mimalloc/include/mimalloc/atomic.h +557 -0
  284. package/vendor/mimalloc/include/mimalloc/internal.h +1153 -0
  285. package/vendor/mimalloc/include/mimalloc/prim.h +421 -0
  286. package/vendor/mimalloc/include/mimalloc/track.h +145 -0
  287. package/vendor/mimalloc/include/mimalloc/types.h +685 -0
  288. package/vendor/mimalloc/include/mimalloc-new-delete.h +66 -0
  289. package/vendor/mimalloc/include/mimalloc-override.h +68 -0
  290. package/vendor/mimalloc/include/mimalloc-stats.h +103 -0
  291. package/vendor/mimalloc/include/mimalloc.h +612 -0
  292. package/vendor/mimalloc/mimalloc.pc.in +11 -0
  293. package/vendor/mimalloc/readme.md +946 -0
  294. package/vendor/mimalloc/src/alloc-aligned.c +360 -0
  295. package/vendor/mimalloc/src/alloc-override.c +316 -0
  296. package/vendor/mimalloc/src/alloc-posix.c +185 -0
  297. package/vendor/mimalloc/src/alloc.c +692 -0
  298. package/vendor/mimalloc/src/arena-abandon.c +346 -0
  299. package/vendor/mimalloc/src/arena.c +1043 -0
  300. package/vendor/mimalloc/src/bitmap.c +441 -0
  301. package/vendor/mimalloc/src/bitmap.h +119 -0
  302. package/vendor/mimalloc/src/free.c +572 -0
  303. package/vendor/mimalloc/src/heap.c +733 -0
  304. package/vendor/mimalloc/src/init.c +714 -0
  305. package/vendor/mimalloc/src/libc.c +334 -0
  306. package/vendor/mimalloc/src/options.c +663 -0
  307. package/vendor/mimalloc/src/os.c +770 -0
  308. package/vendor/mimalloc/src/page-queue.c +390 -0
  309. package/vendor/mimalloc/src/page.c +1049 -0
  310. package/vendor/mimalloc/src/prim/emscripten/prim.c +249 -0
  311. package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +461 -0
  312. package/vendor/mimalloc/src/prim/osx/prim.c +9 -0
  313. package/vendor/mimalloc/src/prim/prim.c +76 -0
  314. package/vendor/mimalloc/src/prim/readme.md +9 -0
  315. package/vendor/mimalloc/src/prim/unix/prim.c +934 -0
  316. package/vendor/mimalloc/src/prim/wasi/prim.c +284 -0
  317. package/vendor/mimalloc/src/prim/windows/etw-mimalloc.wprp +61 -0
  318. package/vendor/mimalloc/src/prim/windows/etw.h +905 -0
  319. package/vendor/mimalloc/src/prim/windows/etw.man +0 -0
  320. package/vendor/mimalloc/src/prim/windows/prim.c +878 -0
  321. package/vendor/mimalloc/src/prim/windows/readme.md +17 -0
  322. package/vendor/mimalloc/src/random.c +258 -0
  323. package/vendor/mimalloc/src/segment-map.c +142 -0
  324. package/vendor/mimalloc/src/segment.c +1702 -0
  325. package/vendor/mimalloc/src/static.c +41 -0
  326. package/vendor/mimalloc/src/stats.c +635 -0
  327. package/vendor/mimalloc/test/CMakeLists.txt +56 -0
  328. package/vendor/mimalloc/test/main-override-dep.cpp +51 -0
  329. package/vendor/mimalloc/test/main-override-dep.h +11 -0
  330. package/vendor/mimalloc/test/main-override-static.c +539 -0
  331. package/vendor/mimalloc/test/main-override.c +36 -0
  332. package/vendor/mimalloc/test/main-override.cpp +497 -0
  333. package/vendor/mimalloc/test/main.c +46 -0
  334. package/vendor/mimalloc/test/readme.md +16 -0
  335. package/vendor/mimalloc/test/test-api-fill.c +343 -0
  336. package/vendor/mimalloc/test/test-api.c +466 -0
  337. package/vendor/mimalloc/test/test-stress.c +428 -0
  338. package/vendor/mimalloc/test/test-wrong.c +92 -0
  339. package/vendor/mimalloc/test/testhelper.h +49 -0
@@ -0,0 +1,685 @@
1
+ /* ----------------------------------------------------------------------------
2
+ Copyright (c) 2018-2024, Microsoft Research, Daan Leijen
3
+ This is free software; you can redistribute it and/or modify it under the
4
+ terms of the MIT license. A copy of the license can be found in the file
5
+ "LICENSE" at the root of this distribution.
6
+ -----------------------------------------------------------------------------*/
7
+ #pragma once
8
+ #ifndef MIMALLOC_TYPES_H
9
+ #define MIMALLOC_TYPES_H
10
+
11
+ // --------------------------------------------------------------------------
12
+ // This file contains the main type definitions for mimalloc:
13
+ // mi_heap_t : all data for a thread-local heap, contains
14
+ // lists of all managed heap pages.
15
+ // mi_segment_t : a larger chunk of memory (32GiB) from where pages
16
+ // are allocated. A segment is divided in slices (64KiB) from
17
+ // which pages are allocated.
18
+ // mi_page_t : a "mimalloc" page (usually 64KiB or 512KiB) from
19
+ // where objects are allocated.
20
+ // Note: we write "OS page" for OS memory pages while
21
+ // using plain "page" for mimalloc pages (`mi_page_t`).
22
+ // --------------------------------------------------------------------------
23
+
24
+
25
+ #include <mimalloc-stats.h>
26
+ #include <stddef.h> // ptrdiff_t
27
+ #include <stdint.h> // uintptr_t, uint16_t, etc
28
+ #include "atomic.h" // _Atomic
29
+
30
+ #ifdef _MSC_VER
31
+ #pragma warning(disable:4214) // bitfield is not int
32
+ #endif
33
+
34
+ // Minimal alignment necessary. On most platforms 16 bytes are needed
35
+ // due to SSE registers for example. This must be at least `sizeof(void*)`
36
+ #ifndef MI_MAX_ALIGN_SIZE
37
+ #define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t)
38
+ #endif
39
+
40
+ // ------------------------------------------------------
41
+ // Variants
42
+ // ------------------------------------------------------
43
+
44
+ // Define NDEBUG in the release version to disable assertions.
45
+ // #define NDEBUG
46
+
47
+ // Define MI_TRACK_<tool> to enable tracking support
48
+ // #define MI_TRACK_VALGRIND 1
49
+ // #define MI_TRACK_ASAN 1
50
+ // #define MI_TRACK_ETW 1
51
+
52
+ // Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance).
53
+ // #define MI_STAT 1
54
+
55
+ // Define MI_SECURE to enable security mitigations
56
+ // #define MI_SECURE 1 // guard page around metadata
57
+ // #define MI_SECURE 2 // guard page around each mimalloc page
58
+ // #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)
59
+ // #define MI_SECURE 4 // checks for double free. (may be more expensive)
60
+
61
+ #if !defined(MI_SECURE)
62
+ #define MI_SECURE 0
63
+ #endif
64
+
65
+ // Define MI_DEBUG for debug mode
66
+ // #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free.
67
+ // #define MI_DEBUG 2 // + internal assertion checks
68
+ // #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON)
69
+ #if !defined(MI_DEBUG)
70
+ #if defined(MI_BUILD_RELEASE) || defined(NDEBUG)
71
+ #define MI_DEBUG 0
72
+ #else
73
+ #define MI_DEBUG 2
74
+ #endif
75
+ #endif
76
+
77
+ // Use guard pages behind objects of a certain size (set by the MIMALLOC_DEBUG_GUARDED_MIN/MAX options)
78
+ // Padding should be disabled when using guard pages
79
+ // #define MI_GUARDED 1
80
+ #if defined(MI_GUARDED)
81
+ #define MI_PADDING 0
82
+ #endif
83
+
84
+ // Reserve extra padding at the end of each block to be more resilient against heap block overflows.
85
+ // The padding can detect buffer overflow on free.
86
+ #if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW))
87
+ #define MI_PADDING 1
88
+ #endif
89
+
90
+ // Check padding bytes; allows byte-precise buffer overflow detection
91
+ #if !defined(MI_PADDING_CHECK) && MI_PADDING && (MI_SECURE>=3 || MI_DEBUG>=1)
92
+ #define MI_PADDING_CHECK 1
93
+ #endif
94
+
95
+
96
+ // Encoded free lists allow detection of corrupted free lists
97
+ // and can detect buffer overflows, modify after free, and double `free`s.
98
+ #if (MI_SECURE>=3 || MI_DEBUG>=1)
99
+ #define MI_ENCODE_FREELIST 1
100
+ #endif
101
+
102
+
103
+ // We used to abandon huge pages in order to eagerly deallocate it if freed from another thread.
104
+ // Unfortunately, that makes it not possible to visit them during a heap walk or include them in a
105
+ // `mi_heap_destroy`. We therefore instead reset/decommit the huge blocks nowadays if freed from
106
+ // another thread so the memory becomes "virtually" available (and eventually gets properly freed by
107
+ // the owning thread).
108
+ // #define MI_HUGE_PAGE_ABANDON 1
109
+
110
+
111
+ // ------------------------------------------------------
112
+ // Platform specific values
113
+ // ------------------------------------------------------
114
+
115
+ // ------------------------------------------------------
116
+ // Size of a pointer.
117
+ // We assume that `sizeof(void*)==sizeof(intptr_t)`
118
+ // and it holds for all platforms we know of.
119
+ //
120
+ // However, the C standard only requires that:
121
+ // p == (void*)((intptr_t)p))
122
+ // but we also need:
123
+ // i == (intptr_t)((void*)i)
124
+ // or otherwise one might define an intptr_t type that is larger than a pointer...
125
+ // ------------------------------------------------------
126
+
127
+ #if INTPTR_MAX > INT64_MAX
128
+ # define MI_INTPTR_SHIFT (4) // assume 128-bit (as on arm CHERI for example)
129
+ #elif INTPTR_MAX == INT64_MAX
130
+ # define MI_INTPTR_SHIFT (3)
131
+ #elif INTPTR_MAX == INT32_MAX
132
+ # define MI_INTPTR_SHIFT (2)
133
+ #else
134
+ #error platform pointers must be 32, 64, or 128 bits
135
+ #endif
136
+
137
+ #if SIZE_MAX == UINT64_MAX
138
+ # define MI_SIZE_SHIFT (3)
139
+ typedef int64_t mi_ssize_t;
140
+ #elif SIZE_MAX == UINT32_MAX
141
+ # define MI_SIZE_SHIFT (2)
142
+ typedef int32_t mi_ssize_t;
143
+ #else
144
+ #error platform objects must be 32 or 64 bits
145
+ #endif
146
+
147
+ #if (SIZE_MAX/2) > LONG_MAX
148
+ # define MI_ZU(x) x##ULL
149
+ # define MI_ZI(x) x##LL
150
+ #else
151
+ # define MI_ZU(x) x##UL
152
+ # define MI_ZI(x) x##L
153
+ #endif
154
+
155
+ #define MI_INTPTR_SIZE (1<<MI_INTPTR_SHIFT)
156
+ #define MI_INTPTR_BITS (MI_INTPTR_SIZE*8)
157
+
158
+ #define MI_SIZE_SIZE (1<<MI_SIZE_SHIFT)
159
+ #define MI_SIZE_BITS (MI_SIZE_SIZE*8)
160
+
161
+ #define MI_KiB (MI_ZU(1024))
162
+ #define MI_MiB (MI_KiB*MI_KiB)
163
+ #define MI_GiB (MI_MiB*MI_KiB)
164
+
165
+
166
+ // ------------------------------------------------------
167
+ // Main internal data-structures
168
+ // ------------------------------------------------------
169
+
170
+ // Main tuning parameters for segment and page sizes
171
+ // Sizes for 64-bit (usually divide by two for 32-bit)
172
+ #ifndef MI_SEGMENT_SLICE_SHIFT
173
+ #define MI_SEGMENT_SLICE_SHIFT (13 + MI_INTPTR_SHIFT) // 64KiB (32KiB on 32-bit)
174
+ #endif
175
+
176
+ #ifndef MI_SEGMENT_SHIFT
177
+ #if MI_INTPTR_SIZE > 4
178
+ #define MI_SEGMENT_SHIFT ( 9 + MI_SEGMENT_SLICE_SHIFT) // 32MiB
179
+ #else
180
+ #define MI_SEGMENT_SHIFT ( 7 + MI_SEGMENT_SLICE_SHIFT) // 4MiB on 32-bit
181
+ #endif
182
+ #endif
183
+
184
+ #ifndef MI_SMALL_PAGE_SHIFT
185
+ #define MI_SMALL_PAGE_SHIFT (MI_SEGMENT_SLICE_SHIFT) // 64KiB
186
+ #endif
187
+ #ifndef MI_MEDIUM_PAGE_SHIFT
188
+ #define MI_MEDIUM_PAGE_SHIFT ( 3 + MI_SMALL_PAGE_SHIFT) // 512KiB
189
+ #endif
190
+
191
+ // Derived constants
192
+ #define MI_SEGMENT_SIZE (MI_ZU(1)<<MI_SEGMENT_SHIFT)
193
+ #define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE
194
+ #define MI_SEGMENT_MASK ((uintptr_t)(MI_SEGMENT_ALIGN - 1))
195
+ #define MI_SEGMENT_SLICE_SIZE (MI_ZU(1)<< MI_SEGMENT_SLICE_SHIFT)
196
+ #define MI_SLICES_PER_SEGMENT (MI_SEGMENT_SIZE / MI_SEGMENT_SLICE_SIZE) // 1024
197
+
198
+ #define MI_SMALL_PAGE_SIZE (MI_ZU(1)<<MI_SMALL_PAGE_SHIFT)
199
+ #define MI_MEDIUM_PAGE_SIZE (MI_ZU(1)<<MI_MEDIUM_PAGE_SHIFT)
200
+
201
+ #define MI_SMALL_OBJ_SIZE_MAX (MI_SMALL_PAGE_SIZE/8) // 8 KiB on 64-bit
202
+ #define MI_MEDIUM_OBJ_SIZE_MAX (MI_MEDIUM_PAGE_SIZE/8) // 64 KiB on 64-bit
203
+ #define MI_MEDIUM_OBJ_WSIZE_MAX (MI_MEDIUM_OBJ_SIZE_MAX/MI_INTPTR_SIZE)
204
+ #define MI_LARGE_OBJ_SIZE_MAX (MI_SEGMENT_SIZE/2) // 16 MiB on 64-bit
205
+ #define MI_LARGE_OBJ_WSIZE_MAX (MI_LARGE_OBJ_SIZE_MAX/MI_INTPTR_SIZE)
206
+
207
+ // Maximum number of size classes. (spaced exponentially in 12.5% increments)
208
+ #if MI_BIN_HUGE != 73U
209
+ #error "mimalloc internal: expecting 73 bins"
210
+ #endif
211
+
212
+ #if (MI_MEDIUM_OBJ_WSIZE_MAX >= 655360)
213
+ #error "mimalloc internal: define more bins"
214
+ #endif
215
+
216
+ // Maximum block size for which blocks are guaranteed to be block size aligned. (see `segment.c:_mi_segment_page_start`)
217
+ #define MI_MAX_ALIGN_GUARANTEE (MI_MEDIUM_OBJ_SIZE_MAX)
218
+
219
+ // Alignments over MI_BLOCK_ALIGNMENT_MAX are allocated in dedicated huge page segments
220
+ #define MI_BLOCK_ALIGNMENT_MAX (MI_SEGMENT_SIZE >> 1)
221
+
222
+ // Maximum slice count (255) for which we can find the page for interior pointers
223
+ #define MI_MAX_SLICE_OFFSET_COUNT ((MI_BLOCK_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1)
224
+
225
+ // we never allocate more than PTRDIFF_MAX (see also <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)
226
+ // on 64-bit+ systems we also limit the maximum allocation size such that the slice count fits in 32-bits. (issue #877)
227
+ #if (PTRDIFF_MAX > INT32_MAX) && (PTRDIFF_MAX >= (MI_SEGMENT_SLIZE_SIZE * UINT32_MAX))
228
+ #define MI_MAX_ALLOC_SIZE (MI_SEGMENT_SLICE_SIZE * (UINT32_MAX-1))
229
+ #else
230
+ #define MI_MAX_ALLOC_SIZE PTRDIFF_MAX
231
+ #endif
232
+
233
+
234
+ // ------------------------------------------------------
235
+ // Mimalloc pages contain allocated blocks
236
+ // ------------------------------------------------------
237
+
238
+ // The free lists use encoded next fields
239
+ // (Only actually encodes when MI_ENCODED_FREELIST is defined.)
240
+ typedef uintptr_t mi_encoded_t;
241
+
242
+ // thread id's
243
+ typedef size_t mi_threadid_t;
244
+
245
+ // free lists contain blocks
246
+ typedef struct mi_block_s {
247
+ mi_encoded_t next;
248
+ } mi_block_t;
249
+
250
+ #if MI_GUARDED
251
+ // we always align guarded pointers in a block at an offset
252
+ // the block `next` field is then used as a tag to distinguish regular offset aligned blocks from guarded ones
253
+ #define MI_BLOCK_TAG_ALIGNED ((mi_encoded_t)(0))
254
+ #define MI_BLOCK_TAG_GUARDED (~MI_BLOCK_TAG_ALIGNED)
255
+ #endif
256
+
257
+
258
+ // The delayed flags are used for efficient multi-threaded free-ing
259
+ typedef enum mi_delayed_e {
260
+ MI_USE_DELAYED_FREE = 0, // push on the owning heap thread delayed list
261
+ MI_DELAYED_FREEING = 1, // temporary: another thread is accessing the owning heap
262
+ MI_NO_DELAYED_FREE = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list
263
+ MI_NEVER_DELAYED_FREE = 3 // sticky: used for abandoned pages without a owning heap; this only resets on page reclaim
264
+ } mi_delayed_t;
265
+
266
+
267
+ // The `in_full` and `has_aligned` page flags are put in a union to efficiently
268
+ // test if both are false (`full_aligned == 0`) in the `mi_free` routine.
269
+ #if !MI_TSAN
270
+ typedef union mi_page_flags_s {
271
+ uint8_t full_aligned;
272
+ struct {
273
+ uint8_t in_full : 1;
274
+ uint8_t has_aligned : 1;
275
+ } x;
276
+ } mi_page_flags_t;
277
+ #else
278
+ // under thread sanitizer, use a byte for each flag to suppress warning, issue #130
279
+ typedef union mi_page_flags_s {
280
+ uint32_t full_aligned;
281
+ struct {
282
+ uint8_t in_full;
283
+ uint8_t has_aligned;
284
+ } x;
285
+ } mi_page_flags_t;
286
+ #endif
287
+
288
+ // Thread free list.
289
+ // We use the bottom 2 bits of the pointer for mi_delayed_t flags
290
+ typedef uintptr_t mi_thread_free_t;
291
+
292
+ // A page contains blocks of one specific size (`block_size`).
293
+ // Each page has three list of free blocks:
294
+ // `free` for blocks that can be allocated,
295
+ // `local_free` for freed blocks that are not yet available to `mi_malloc`
296
+ // `thread_free` for freed blocks by other threads
297
+ // The `local_free` and `thread_free` lists are migrated to the `free` list
298
+ // when it is exhausted. The separate `local_free` list is necessary to
299
+ // implement a monotonic heartbeat. The `thread_free` list is needed for
300
+ // avoiding atomic operations in the common case.
301
+ //
302
+ // `used - |thread_free|` == actual blocks that are in use (alive)
303
+ // `used - |thread_free| + |free| + |local_free| == capacity`
304
+ //
305
+ // We don't count `freed` (as |free|) but use `used` to reduce
306
+ // the number of memory accesses in the `mi_page_all_free` function(s).
307
+ //
308
+ // Notes:
309
+ // - Access is optimized for `free.c:mi_free` and `alloc.c:mi_page_alloc`
310
+ // - Using `uint16_t` does not seem to slow things down
311
+ // - The size is 12 words on 64-bit which helps the page index calculations
312
+ // (and 14 words on 32-bit, and encoded free lists add 2 words)
313
+ // - `xthread_free` uses the bottom bits as a delayed-free flags to optimize
314
+ // concurrent frees where only the first concurrent free adds to the owning
315
+ // heap `thread_delayed_free` list (see `free.c:mi_free_block_mt`).
316
+ // The invariant is that no-delayed-free is only set if there is
317
+ // at least one block that will be added, or as already been added, to
318
+ // the owning heap `thread_delayed_free` list. This guarantees that pages
319
+ // will be freed correctly even if only other threads free blocks.
320
+ typedef struct mi_page_s {
321
+ // "owned" by the segment
322
+ uint32_t slice_count; // slices in this page (0 if not a page)
323
+ uint32_t slice_offset; // distance from the actual page data slice (0 if a page)
324
+ uint8_t is_committed:1; // `true` if the page virtual memory is committed
325
+ uint8_t is_zero_init:1; // `true` if the page was initially zero initialized
326
+ uint8_t is_huge:1; // `true` if the page is in a huge segment (`segment->kind == MI_SEGMENT_HUGE`)
327
+ // padding
328
+ // layout like this to optimize access in `mi_malloc` and `mi_free`
329
+ uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear`
330
+ uint16_t reserved; // number of blocks reserved in memory
331
+ mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits)
332
+ uint8_t free_is_zero:1; // `true` if the blocks in the free list are zero initialized
333
+ uint8_t retire_expire:7; // expiration count for retired blocks
334
+
335
+ mi_block_t* free; // list of available free blocks (`malloc` allocates from this list)
336
+ mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`)
337
+ uint16_t used; // number of blocks in use (including blocks in `thread_free`)
338
+ uint8_t block_size_shift; // if not zero, then `(1 << block_size_shift) == block_size` (only used for fast path in `free.c:_mi_page_ptr_unalign`)
339
+ uint8_t heap_tag; // tag of the owning heap, used to separate heaps by object type
340
+ // padding
341
+ size_t block_size; // size available in each block (always `>0`)
342
+ uint8_t* page_start; // start of the page area containing the blocks
343
+
344
+ #if (MI_ENCODE_FREELIST || MI_PADDING)
345
+ uintptr_t keys[2]; // two random keys to encode the free lists (see `_mi_block_next`) or padding canary
346
+ #endif
347
+
348
+ _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads
349
+ _Atomic(uintptr_t) xheap;
350
+
351
+ struct mi_page_s* next; // next page owned by this thread with the same `block_size`
352
+ struct mi_page_s* prev; // previous page owned by this thread with the same `block_size`
353
+
354
+ // 64-bit 11 words, 32-bit 13 words, (+2 for secure)
355
+ void* padding[1];
356
+ } mi_page_t;
357
+
358
+
359
+
360
+ // ------------------------------------------------------
361
+ // Mimalloc segments contain mimalloc pages
362
+ // ------------------------------------------------------
363
+
364
+ typedef enum mi_page_kind_e {
365
+ MI_PAGE_SMALL, // small blocks go into 64KiB pages inside a segment
366
+ MI_PAGE_MEDIUM, // medium blocks go into 512KiB pages inside a segment
367
+ MI_PAGE_LARGE, // larger blocks go into a single page spanning a whole segment
368
+ MI_PAGE_HUGE // a huge page is a single page in a segment of variable size
369
+ // used for blocks `> MI_LARGE_OBJ_SIZE_MAX` or an aligment `> MI_BLOCK_ALIGNMENT_MAX`.
370
+ } mi_page_kind_t;
371
+
372
+ typedef enum mi_segment_kind_e {
373
+ MI_SEGMENT_NORMAL, // MI_SEGMENT_SIZE size with pages inside.
374
+ MI_SEGMENT_HUGE, // segment with just one huge page inside.
375
+ } mi_segment_kind_t;
376
+
377
+ // ------------------------------------------------------
378
+ // A segment holds a commit mask where a bit is set if
379
+ // the corresponding MI_COMMIT_SIZE area is committed.
380
+ // The MI_COMMIT_SIZE must be a multiple of the slice
381
+ // size. If it is equal we have the most fine grained
382
+ // decommit (but setting it higher can be more efficient).
383
+ // The MI_MINIMAL_COMMIT_SIZE is the minimal amount that will
384
+ // be committed in one go which can be set higher than
385
+ // MI_COMMIT_SIZE for efficiency (while the decommit mask
386
+ // is still tracked in fine-grained MI_COMMIT_SIZE chunks)
387
+ // ------------------------------------------------------
388
+
389
+ #define MI_MINIMAL_COMMIT_SIZE (1*MI_SEGMENT_SLICE_SIZE)
390
+ #define MI_COMMIT_SIZE (MI_SEGMENT_SLICE_SIZE) // 64KiB
391
+ #define MI_COMMIT_MASK_BITS (MI_SEGMENT_SIZE / MI_COMMIT_SIZE)
392
+ #define MI_COMMIT_MASK_FIELD_BITS MI_SIZE_BITS
393
+ #define MI_COMMIT_MASK_FIELD_COUNT (MI_COMMIT_MASK_BITS / MI_COMMIT_MASK_FIELD_BITS)
394
+
395
+ #if (MI_COMMIT_MASK_BITS != (MI_COMMIT_MASK_FIELD_COUNT * MI_COMMIT_MASK_FIELD_BITS))
396
+ #error "the segment size must be exactly divisible by the (commit size * size_t bits)"
397
+ #endif
398
+
399
+ typedef struct mi_commit_mask_s {
400
+ size_t mask[MI_COMMIT_MASK_FIELD_COUNT];
401
+ } mi_commit_mask_t;
402
+
403
+ typedef mi_page_t mi_slice_t;
404
+ typedef int64_t mi_msecs_t;
405
+
406
+
407
+ // ---------------------------------------------------------------
408
+ // a memory id tracks the provenance of arena/OS allocated memory
409
+ // ---------------------------------------------------------------
410
+
411
+ // Memory can reside in arena's, direct OS allocated, or statically allocated. The memid keeps track of this.
412
+ typedef enum mi_memkind_e {
413
+ MI_MEM_NONE, // not allocated
414
+ MI_MEM_EXTERNAL, // not owned by mimalloc but provided externally (via `mi_manage_os_memory` for example)
415
+ MI_MEM_STATIC, // allocated in a static area and should not be freed (for arena meta data for example)
416
+ MI_MEM_OS, // allocated from the OS
417
+ MI_MEM_OS_HUGE, // allocated as huge OS pages (usually 1GiB, pinned to physical memory)
418
+ MI_MEM_OS_REMAP, // allocated in a remapable area (i.e. using `mremap`)
419
+ MI_MEM_ARENA // allocated from an arena (the usual case)
420
+ } mi_memkind_t;
421
+
422
+ static inline bool mi_memkind_is_os(mi_memkind_t memkind) {
423
+ return (memkind >= MI_MEM_OS && memkind <= MI_MEM_OS_REMAP);
424
+ }
425
+
426
+ typedef struct mi_memid_os_info {
427
+ void* base; // actual base address of the block (used for offset aligned allocations)
428
+ size_t size; // full allocation size
429
+ } mi_memid_os_info_t;
430
+
431
+ typedef struct mi_memid_arena_info {
432
+ size_t block_index; // index in the arena
433
+ mi_arena_id_t id; // arena id (>= 1)
434
+ bool is_exclusive; // this arena can only be used for specific arena allocations
435
+ } mi_memid_arena_info_t;
436
+
437
+ typedef struct mi_memid_s {
438
+ union {
439
+ mi_memid_os_info_t os; // only used for MI_MEM_OS
440
+ mi_memid_arena_info_t arena; // only used for MI_MEM_ARENA
441
+ } mem;
442
+ bool is_pinned; // `true` if we cannot decommit/reset/protect in this memory (e.g. when allocated using large (2Mib) or huge (1GiB) OS pages)
443
+ bool initially_committed;// `true` if the memory was originally allocated as committed
444
+ bool initially_zero; // `true` if the memory was originally zero initialized
445
+ mi_memkind_t memkind;
446
+ } mi_memid_t;
447
+
448
+
449
+ // -----------------------------------------------------------------------------------------
450
+ // Segments are large allocated memory blocks (32mb on 64 bit) from arenas or the OS.
451
+ //
452
+ // Inside segments we allocated fixed size mimalloc pages (`mi_page_t`) that contain blocks.
453
+ // The start of a segment is this structure with a fixed number of slice entries (`slices`)
454
+ // usually followed by a guard OS page and the actual allocation area with pages.
455
+ // While a page is not allocated, we view it's data as a `mi_slice_t` (instead of a `mi_page_t`).
456
+ // Of any free area, the first slice has the info and `slice_offset == 0`; for any subsequent
457
+ // slices part of the area, the `slice_offset` is the byte offset back to the first slice
458
+ // (so we can quickly find the page info on a free, `internal.h:_mi_segment_page_of`).
459
+ // For slices, the `block_size` field is repurposed to signify if a slice is used (`1`) or not (`0`).
460
+ // Small and medium pages use a fixed amount of slices to reduce slice fragmentation, while
461
+ // large and huge pages span a variable amount of slices.
462
+
463
+ typedef struct mi_subproc_s mi_subproc_t;
464
+
465
+ typedef struct mi_segment_s {
466
+ // constant fields
467
+ mi_memid_t memid; // memory id for arena/OS allocation
468
+ bool allow_decommit; // can we decommmit the memory
469
+ bool allow_purge; // can we purge the memory (reset or decommit)
470
+ size_t segment_size;
471
+ mi_subproc_t* subproc; // segment belongs to sub process
472
+
473
+ // segment fields
474
+ mi_msecs_t purge_expire; // purge slices in the `purge_mask` after this time
475
+ mi_commit_mask_t purge_mask; // slices that can be purged
476
+ mi_commit_mask_t commit_mask; // slices that are currently committed
477
+
478
+ // from here is zero initialized
479
+ struct mi_segment_s* next; // the list of freed segments in the cache (must be first field, see `segment.c:mi_segment_init`)
480
+ bool was_reclaimed; // true if it was reclaimed (used to limit on-free reclamation)
481
+ bool dont_free; // can be temporarily true to ensure the segment is not freed
482
+
483
+ size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`)
484
+ size_t abandoned_visits; // count how often this segment is visited during abondoned reclamation (to force reclaim if it takes too long)
485
+ size_t used; // count of pages in use
486
+ uintptr_t cookie; // verify addresses in debug mode: `mi_ptr_cookie(segment) == segment->cookie`
487
+
488
+ struct mi_segment_s* abandoned_os_next; // only used for abandoned segments outside arena's, and only if `mi_option_visit_abandoned` is enabled
489
+ struct mi_segment_s* abandoned_os_prev;
490
+
491
+ size_t segment_slices; // for huge segments this may be different from `MI_SLICES_PER_SEGMENT`
492
+ size_t segment_info_slices; // initial count of slices that we are using for segment info and possible guard pages.
493
+
494
+ // layout like this to optimize access in `mi_free`
495
+ mi_segment_kind_t kind;
496
+ size_t slice_entries; // entries in the `slices` array, at most `MI_SLICES_PER_SEGMENT`
497
+ _Atomic(mi_threadid_t) thread_id; // unique id of the thread owning this segment
498
+
499
+ mi_slice_t slices[MI_SLICES_PER_SEGMENT+1]; // one extra final entry for huge blocks with large alignment
500
+ } mi_segment_t;
501
+
502
+
503
+ // ------------------------------------------------------
504
+ // Heaps
505
+ // Provide first-class heaps to allocate from.
506
+ // A heap just owns a set of pages for allocation and
507
+ // can only be allocate/reallocate from the thread that created it.
508
+ // Freeing blocks can be done from any thread though.
509
+ // Per thread, the segments are shared among its heaps.
510
+ // Per thread, there is always a default heap that is
511
+ // used for allocation; it is initialized to statically
512
+ // point to an empty heap to avoid initialization checks
513
+ // in the fast path.
514
+ // ------------------------------------------------------
515
+
516
+ // Thread local data
517
+ typedef struct mi_tld_s mi_tld_t;
518
+
519
+ // Pages of a certain block size are held in a queue.
520
+ typedef struct mi_page_queue_s {
521
+ mi_page_t* first;
522
+ mi_page_t* last;
523
+ size_t block_size;
524
+ } mi_page_queue_t;
525
+
526
+ #define MI_BIN_FULL (MI_BIN_HUGE+1)
527
+
528
+ // Random context
529
+ typedef struct mi_random_cxt_s {
530
+ uint32_t input[16];
531
+ uint32_t output[16];
532
+ int output_available;
533
+ bool weak;
534
+ } mi_random_ctx_t;
535
+
536
+
537
+ // In debug mode there is a padding structure at the end of the blocks to check for buffer overflows
538
+ #if (MI_PADDING)
539
+ typedef struct mi_padding_s {
540
+ uint32_t canary; // encoded block value to check validity of the padding (in case of overflow)
541
+ uint32_t delta; // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes)
542
+ } mi_padding_t;
543
+ #define MI_PADDING_SIZE (sizeof(mi_padding_t))
544
+ #define MI_PADDING_WSIZE ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE)
545
+ #else
546
+ #define MI_PADDING_SIZE 0
547
+ #define MI_PADDING_WSIZE 0
548
+ #endif
549
+
550
+ #define MI_PAGES_DIRECT (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1)
551
+
552
+
553
+ // A heap owns a set of pages.
554
+ struct mi_heap_s {
555
+ mi_tld_t* tld;
556
+ _Atomic(mi_block_t*) thread_delayed_free;
557
+ mi_threadid_t thread_id; // thread this heap belongs too
558
+ mi_arena_id_t arena_id; // arena id if the heap belongs to a specific arena (or 0)
559
+ uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`)
560
+ uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list
561
+ mi_random_ctx_t random; // random number context used for secure allocation
562
+ size_t page_count; // total number of pages in the `pages` queues.
563
+ size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues)
564
+ size_t page_retired_max; // largest retired index into the `pages` array.
565
+ long generic_count; // how often is `_mi_malloc_generic` called?
566
+ long generic_collect_count; // how often is `_mi_malloc_generic` called without collecting?
567
+ mi_heap_t* next; // list of heaps per thread
568
+ bool no_reclaim; // `true` if this heap should not reclaim abandoned pages
569
+ uint8_t tag; // custom tag, can be used for separating heaps based on the object types
570
+ #if MI_GUARDED
571
+ size_t guarded_size_min; // minimal size for guarded objects
572
+ size_t guarded_size_max; // maximal size for guarded objects
573
+ size_t guarded_sample_rate; // sample rate (set to 0 to disable guarded pages)
574
+ size_t guarded_sample_count; // current sample count (counting down to 0)
575
+ #endif
576
+ mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size.
577
+ mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin")
578
+ };
579
+
580
+
581
+ // ------------------------------------------------------
582
+ // Sub processes do not reclaim or visit segments
583
+ // from other sub processes. These are essentially the
584
+ // static variables of a process.
585
+ // ------------------------------------------------------
586
+
587
+ struct mi_subproc_s {
588
+ _Atomic(size_t) abandoned_count; // count of abandoned segments for this sub-process
589
+ _Atomic(size_t) abandoned_os_list_count; // count of abandoned segments in the os-list
590
+ mi_lock_t abandoned_os_lock; // lock for the abandoned os segment list (outside of arena's) (this lock protect list operations)
591
+ mi_lock_t abandoned_os_visit_lock; // ensure only one thread per subproc visits the abandoned os list
592
+ mi_segment_t* abandoned_os_list; // doubly-linked list of abandoned segments outside of arena's (in OS allocated memory)
593
+ mi_segment_t* abandoned_os_list_tail; // the tail-end of the list
594
+ mi_memid_t memid; // provenance of this memory block
595
+ };
596
+
597
+
598
+ // ------------------------------------------------------
599
+ // Thread Local data
600
+ // ------------------------------------------------------
601
+
602
+ // A "span" is is an available range of slices. The span queues keep
603
+ // track of slice spans of at most the given `slice_count` (but more than the previous size class).
604
+ typedef struct mi_span_queue_s {
605
+ mi_slice_t* first;
606
+ mi_slice_t* last;
607
+ size_t slice_count;
608
+ } mi_span_queue_t;
609
+
610
+ #define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT)
611
+
612
+ // Segments thread local data
613
+ typedef struct mi_segments_tld_s {
614
+ mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments
615
+ size_t count; // current number of segments;
616
+ size_t peak_count; // peak number of segments
617
+ size_t current_size; // current size of all segments
618
+ size_t peak_size; // peak size of all segments
619
+ size_t reclaim_count;// number of reclaimed (abandoned) segments
620
+ mi_subproc_t* subproc; // sub-process this thread belongs to.
621
+ mi_stats_t* stats; // points to tld stats
622
+ } mi_segments_tld_t;
623
+
624
+ // Thread local data
625
+ struct mi_tld_s {
626
+ unsigned long long heartbeat; // monotonic heartbeat count
627
+ bool recurse; // true if deferred was called; used to prevent infinite recursion.
628
+ mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted)
629
+ mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates)
630
+ mi_segments_tld_t segments; // segment tld
631
+ mi_stats_t stats; // statistics
632
+ };
633
+
634
+
635
+ // ------------------------------------------------------
636
+ // Debug
637
+ // ------------------------------------------------------
638
+
639
+ #if !defined(MI_DEBUG_UNINIT)
640
+ #define MI_DEBUG_UNINIT (0xD0)
641
+ #endif
642
+ #if !defined(MI_DEBUG_FREED)
643
+ #define MI_DEBUG_FREED (0xDF)
644
+ #endif
645
+ #if !defined(MI_DEBUG_PADDING)
646
+ #define MI_DEBUG_PADDING (0xDE)
647
+ #endif
648
+
649
+
650
+ // ------------------------------------------------------
651
+ // Statistics
652
+ // ------------------------------------------------------
653
+ #ifndef MI_STAT
654
+ #if (MI_DEBUG>0)
655
+ #define MI_STAT 2
656
+ #else
657
+ #define MI_STAT 0
658
+ #endif
659
+ #endif
660
+
661
+ // add to stat keeping track of the peak
662
+ void _mi_stat_increase(mi_stat_count_t* stat, size_t amount);
663
+ void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount);
664
+ void _mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount);
665
+ // counters can just be increased
666
+ void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);
667
+
668
+ #if (MI_STAT)
669
+ #define mi_stat_increase(stat,amount) _mi_stat_increase( &(stat), amount)
670
+ #define mi_stat_decrease(stat,amount) _mi_stat_decrease( &(stat), amount)
671
+ #define mi_stat_adjust_decrease(stat,amount) _mi_stat_adjust_decrease( &(stat), amount)
672
+ #define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount)
673
+ #else
674
+ #define mi_stat_increase(stat,amount) ((void)0)
675
+ #define mi_stat_decrease(stat,amount) ((void)0)
676
+ #define mi_stat_adjust_decrease(stat,amount) ((void)0)
677
+ #define mi_stat_counter_increase(stat,amount) ((void)0)
678
+ #endif
679
+
680
+ #define mi_heap_stat_counter_increase(heap,stat,amount) mi_stat_counter_increase( (heap)->tld->stats.stat, amount)
681
+ #define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount)
682
+ #define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount)
683
+ #define mi_heap_stat_adjust_decrease(heap,stat,amount) mi_stat_adjust_decrease( (heap)->tld->stats.stat, amount)
684
+
685
+ #endif