@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,714 @@
1
+ /* ----------------------------------------------------------------------------
2
+ Copyright (c) 2018-2022, 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
+ #include "mimalloc.h"
8
+ #include "mimalloc/internal.h"
9
+ #include "mimalloc/prim.h"
10
+
11
+ #include <string.h> // memcpy, memset
12
+ #include <stdlib.h> // atexit
13
+
14
+
15
+ // Empty page used to initialize the small free pages array
16
+ const mi_page_t _mi_page_empty = {
17
+ 0,
18
+ false, false, false, false,
19
+ 0, // capacity
20
+ 0, // reserved capacity
21
+ { 0 }, // flags
22
+ false, // is_zero
23
+ 0, // retire_expire
24
+ NULL, // free
25
+ NULL, // local_free
26
+ 0, // used
27
+ 0, // block size shift
28
+ 0, // heap tag
29
+ 0, // block_size
30
+ NULL, // page_start
31
+ #if (MI_PADDING || MI_ENCODE_FREELIST)
32
+ { 0, 0 },
33
+ #endif
34
+ MI_ATOMIC_VAR_INIT(0), // xthread_free
35
+ MI_ATOMIC_VAR_INIT(0), // xheap
36
+ NULL, NULL
37
+ , { 0 } // padding
38
+ };
39
+
40
+ #define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty)
41
+
42
+ #if (MI_SMALL_WSIZE_MAX==128)
43
+ #if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8)
44
+ #define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() }
45
+ #elif (MI_PADDING>0)
46
+ #define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() }
47
+ #else
48
+ #define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() }
49
+ #endif
50
+ #else
51
+ #error "define right initialization sizes corresponding to MI_SMALL_WSIZE_MAX"
52
+ #endif
53
+
54
+ // Empty page queues for every bin
55
+ #define QNULL(sz) { NULL, NULL, (sz)*sizeof(uintptr_t) }
56
+ #define MI_PAGE_QUEUES_EMPTY \
57
+ { QNULL(1), \
58
+ QNULL( 1), QNULL( 2), QNULL( 3), QNULL( 4), QNULL( 5), QNULL( 6), QNULL( 7), QNULL( 8), /* 8 */ \
59
+ QNULL( 10), QNULL( 12), QNULL( 14), QNULL( 16), QNULL( 20), QNULL( 24), QNULL( 28), QNULL( 32), /* 16 */ \
60
+ QNULL( 40), QNULL( 48), QNULL( 56), QNULL( 64), QNULL( 80), QNULL( 96), QNULL( 112), QNULL( 128), /* 24 */ \
61
+ QNULL( 160), QNULL( 192), QNULL( 224), QNULL( 256), QNULL( 320), QNULL( 384), QNULL( 448), QNULL( 512), /* 32 */ \
62
+ QNULL( 640), QNULL( 768), QNULL( 896), QNULL( 1024), QNULL( 1280), QNULL( 1536), QNULL( 1792), QNULL( 2048), /* 40 */ \
63
+ QNULL( 2560), QNULL( 3072), QNULL( 3584), QNULL( 4096), QNULL( 5120), QNULL( 6144), QNULL( 7168), QNULL( 8192), /* 48 */ \
64
+ QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \
65
+ QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \
66
+ QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \
67
+ QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \
68
+ QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 2) /* Full queue */ }
69
+
70
+ #define MI_STAT_COUNT_NULL() {0,0,0}
71
+
72
+ // Empty statistics
73
+ #define MI_STATS_NULL \
74
+ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
75
+ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
76
+ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
77
+ { 0 }, { 0 }, { 0 }, { 0 }, \
78
+ { 0 }, { 0 }, { 0 }, { 0 }, \
79
+ \
80
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, \
81
+ MI_INIT4(MI_STAT_COUNT_NULL), \
82
+ { 0 }, { 0 }, { 0 }, { 0 }, \
83
+ \
84
+ { MI_INIT4(MI_STAT_COUNT_NULL) }, \
85
+ { { 0 }, { 0 }, { 0 }, { 0 } }, \
86
+ \
87
+ { MI_INIT74(MI_STAT_COUNT_NULL) }, \
88
+ { MI_INIT74(MI_STAT_COUNT_NULL) }
89
+
90
+
91
+ // Empty slice span queues for every bin
92
+ #define SQNULL(sz) { NULL, NULL, sz }
93
+ #define MI_SEGMENT_SPAN_QUEUES_EMPTY \
94
+ { SQNULL(1), \
95
+ SQNULL( 1), SQNULL( 2), SQNULL( 3), SQNULL( 4), SQNULL( 5), SQNULL( 6), SQNULL( 7), SQNULL( 10), /* 8 */ \
96
+ SQNULL( 12), SQNULL( 14), SQNULL( 16), SQNULL( 20), SQNULL( 24), SQNULL( 28), SQNULL( 32), SQNULL( 40), /* 16 */ \
97
+ SQNULL( 48), SQNULL( 56), SQNULL( 64), SQNULL( 80), SQNULL( 96), SQNULL( 112), SQNULL( 128), SQNULL( 160), /* 24 */ \
98
+ SQNULL( 192), SQNULL( 224), SQNULL( 256), SQNULL( 320), SQNULL( 384), SQNULL( 448), SQNULL( 512), SQNULL( 640), /* 32 */ \
99
+ SQNULL( 768), SQNULL( 896), SQNULL( 1024) /* 35 */ }
100
+
101
+
102
+ // --------------------------------------------------------
103
+ // Statically allocate an empty heap as the initial
104
+ // thread local value for the default heap,
105
+ // and statically allocate the backing heap for the main
106
+ // thread so it can function without doing any allocation
107
+ // itself (as accessing a thread local for the first time
108
+ // may lead to allocation itself on some platforms)
109
+ // --------------------------------------------------------
110
+
111
+ mi_decl_cache_align const mi_heap_t _mi_heap_empty = {
112
+ NULL,
113
+ MI_ATOMIC_VAR_INIT(NULL),
114
+ 0, // tid
115
+ 0, // cookie
116
+ 0, // arena id
117
+ { 0, 0 }, // keys
118
+ { {0}, {0}, 0, true }, // random
119
+ 0, // page count
120
+ MI_BIN_FULL, 0, // page retired min/max
121
+ 0, 0, // generic count
122
+ NULL, // next
123
+ false, // can reclaim
124
+ 0, // tag
125
+ #if MI_GUARDED
126
+ 0, 0, 0, 1, // count is 1 so we never write to it (see `internal.h:mi_heap_malloc_use_guarded`)
127
+ #endif
128
+ MI_SMALL_PAGES_EMPTY,
129
+ MI_PAGE_QUEUES_EMPTY
130
+ };
131
+
132
+ static mi_decl_cache_align mi_subproc_t mi_subproc_default;
133
+
134
+ #define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats)))
135
+
136
+ mi_decl_cache_align static const mi_tld_t tld_empty = {
137
+ 0,
138
+ false,
139
+ NULL, NULL,
140
+ { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, tld_empty_stats }, // segments
141
+ { MI_STAT_VERSION, MI_STATS_NULL } // stats
142
+ };
143
+
144
+ mi_threadid_t _mi_thread_id(void) mi_attr_noexcept {
145
+ return _mi_prim_thread_id();
146
+ }
147
+
148
+ // the thread-local default heap for allocation
149
+ mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;
150
+
151
+ extern mi_decl_hidden mi_heap_t _mi_heap_main;
152
+
153
+ static mi_decl_cache_align mi_tld_t tld_main = {
154
+ 0, false,
155
+ &_mi_heap_main, & _mi_heap_main,
156
+ { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, &tld_main.stats }, // segments
157
+ { MI_STAT_VERSION, MI_STATS_NULL } // stats
158
+ };
159
+
160
+ mi_decl_cache_align mi_heap_t _mi_heap_main = {
161
+ &tld_main,
162
+ MI_ATOMIC_VAR_INIT(NULL),
163
+ 0, // thread id
164
+ 0, // initial cookie
165
+ 0, // arena id
166
+ { 0, 0 }, // the key of the main heap can be fixed (unlike page keys that need to be secure!)
167
+ { {0x846ca68b}, {0}, 0, true }, // random
168
+ 0, // page count
169
+ MI_BIN_FULL, 0, // page retired min/max
170
+ 0, 0, // generic count
171
+ NULL, // next heap
172
+ false, // can reclaim
173
+ 0, // tag
174
+ #if MI_GUARDED
175
+ 0, 0, 0, 0,
176
+ #endif
177
+ MI_SMALL_PAGES_EMPTY,
178
+ MI_PAGE_QUEUES_EMPTY
179
+ };
180
+
181
+ bool _mi_process_is_initialized = false; // set to `true` in `mi_process_init`.
182
+
183
+ mi_stats_t _mi_stats_main = { MI_STAT_VERSION, MI_STATS_NULL };
184
+
185
+ #if MI_GUARDED
186
+ mi_decl_export void mi_heap_guarded_set_sample_rate(mi_heap_t* heap, size_t sample_rate, size_t seed) {
187
+ heap->guarded_sample_rate = sample_rate;
188
+ heap->guarded_sample_count = sample_rate; // count down samples
189
+ if (heap->guarded_sample_rate > 1) {
190
+ if (seed == 0) {
191
+ seed = _mi_heap_random_next(heap);
192
+ }
193
+ heap->guarded_sample_count = (seed % heap->guarded_sample_rate) + 1; // start at random count between 1 and `sample_rate`
194
+ }
195
+ }
196
+
197
+ mi_decl_export void mi_heap_guarded_set_size_bound(mi_heap_t* heap, size_t min, size_t max) {
198
+ heap->guarded_size_min = min;
199
+ heap->guarded_size_max = (min > max ? min : max);
200
+ }
201
+
202
+ void _mi_heap_guarded_init(mi_heap_t* heap) {
203
+ mi_heap_guarded_set_sample_rate(heap,
204
+ (size_t)mi_option_get_clamp(mi_option_guarded_sample_rate, 0, LONG_MAX),
205
+ (size_t)mi_option_get(mi_option_guarded_sample_seed));
206
+ mi_heap_guarded_set_size_bound(heap,
207
+ (size_t)mi_option_get_clamp(mi_option_guarded_min, 0, LONG_MAX),
208
+ (size_t)mi_option_get_clamp(mi_option_guarded_max, 0, LONG_MAX) );
209
+ }
210
+ #else
211
+ mi_decl_export void mi_heap_guarded_set_sample_rate(mi_heap_t* heap, size_t sample_rate, size_t seed) {
212
+ MI_UNUSED(heap); MI_UNUSED(sample_rate); MI_UNUSED(seed);
213
+ }
214
+
215
+ mi_decl_export void mi_heap_guarded_set_size_bound(mi_heap_t* heap, size_t min, size_t max) {
216
+ MI_UNUSED(heap); MI_UNUSED(min); MI_UNUSED(max);
217
+ }
218
+ void _mi_heap_guarded_init(mi_heap_t* heap) {
219
+ MI_UNUSED(heap);
220
+ }
221
+ #endif
222
+
223
+
224
+ static void mi_heap_main_init(void) {
225
+ if (_mi_heap_main.cookie == 0) {
226
+ _mi_heap_main.thread_id = _mi_thread_id();
227
+ _mi_heap_main.cookie = 1;
228
+ #if defined(_WIN32) && !defined(MI_SHARED_LIB)
229
+ _mi_random_init_weak(&_mi_heap_main.random); // prevent allocation failure during bcrypt dll initialization with static linking
230
+ #else
231
+ _mi_random_init(&_mi_heap_main.random);
232
+ #endif
233
+ _mi_heap_main.cookie = _mi_heap_random_next(&_mi_heap_main);
234
+ _mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main);
235
+ _mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main);
236
+ mi_lock_init(&mi_subproc_default.abandoned_os_lock);
237
+ mi_lock_init(&mi_subproc_default.abandoned_os_visit_lock);
238
+ _mi_heap_guarded_init(&_mi_heap_main);
239
+ }
240
+ }
241
+
242
+ mi_heap_t* _mi_heap_main_get(void) {
243
+ mi_heap_main_init();
244
+ return &_mi_heap_main;
245
+ }
246
+
247
+ /* -----------------------------------------------------------
248
+ Sub process
249
+ ----------------------------------------------------------- */
250
+
251
+ mi_subproc_id_t mi_subproc_main(void) {
252
+ return NULL;
253
+ }
254
+
255
+ mi_subproc_id_t mi_subproc_new(void) {
256
+ mi_memid_t memid = _mi_memid_none();
257
+ mi_subproc_t* subproc = (mi_subproc_t*)_mi_arena_meta_zalloc(sizeof(mi_subproc_t), &memid);
258
+ if (subproc == NULL) return NULL;
259
+ subproc->memid = memid;
260
+ subproc->abandoned_os_list = NULL;
261
+ mi_lock_init(&subproc->abandoned_os_lock);
262
+ mi_lock_init(&subproc->abandoned_os_visit_lock);
263
+ return subproc;
264
+ }
265
+
266
+ mi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id) {
267
+ return (subproc_id == NULL ? &mi_subproc_default : (mi_subproc_t*)subproc_id);
268
+ }
269
+
270
+ void mi_subproc_delete(mi_subproc_id_t subproc_id) {
271
+ if (subproc_id == NULL) return;
272
+ mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);
273
+ // check if there are no abandoned segments still..
274
+ bool safe_to_delete = false;
275
+ mi_lock(&subproc->abandoned_os_lock) {
276
+ if (subproc->abandoned_os_list == NULL) {
277
+ safe_to_delete = true;
278
+ }
279
+ }
280
+ if (!safe_to_delete) return;
281
+ // safe to release
282
+ // todo: should we refcount subprocesses?
283
+ mi_lock_done(&subproc->abandoned_os_lock);
284
+ mi_lock_done(&subproc->abandoned_os_visit_lock);
285
+ _mi_arena_meta_free(subproc, subproc->memid, sizeof(mi_subproc_t));
286
+ }
287
+
288
+ void mi_subproc_add_current_thread(mi_subproc_id_t subproc_id) {
289
+ mi_heap_t* heap = mi_heap_get_default();
290
+ if (heap == NULL) return;
291
+ mi_assert(heap->tld->segments.subproc == &mi_subproc_default);
292
+ if (heap->tld->segments.subproc != &mi_subproc_default) return;
293
+ heap->tld->segments.subproc = _mi_subproc_from_id(subproc_id);
294
+ }
295
+
296
+
297
+
298
+ /* -----------------------------------------------------------
299
+ Initialization and freeing of the thread local heaps
300
+ ----------------------------------------------------------- */
301
+
302
+ // note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size).
303
+ typedef struct mi_thread_data_s {
304
+ mi_heap_t heap; // must come first due to cast in `_mi_heap_done`
305
+ mi_tld_t tld;
306
+ mi_memid_t memid; // must come last due to zero'ing
307
+ } mi_thread_data_t;
308
+
309
+
310
+ // Thread meta-data is allocated directly from the OS. For
311
+ // some programs that do not use thread pools and allocate and
312
+ // destroy many OS threads, this may causes too much overhead
313
+ // per thread so we maintain a small cache of recently freed metadata.
314
+
315
+ #define TD_CACHE_SIZE (32)
316
+ static _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE];
317
+
318
+ static mi_thread_data_t* mi_thread_data_zalloc(void) {
319
+ // try to find thread metadata in the cache
320
+ mi_thread_data_t* td = NULL;
321
+ for (int i = 0; i < TD_CACHE_SIZE; i++) {
322
+ td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
323
+ if (td != NULL) {
324
+ // found cached allocation, try use it
325
+ td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
326
+ if (td != NULL) {
327
+ _mi_memzero(td, offsetof(mi_thread_data_t,memid));
328
+ return td;
329
+ }
330
+ }
331
+ }
332
+
333
+ // if that fails, allocate as meta data
334
+ mi_memid_t memid;
335
+ td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);
336
+ if (td == NULL) {
337
+ // if this fails, try once more. (issue #257)
338
+ td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);
339
+ if (td == NULL) {
340
+ // really out of memory
341
+ _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
342
+ return NULL;
343
+ }
344
+ }
345
+ td->memid = memid;
346
+ return td;
347
+ }
348
+
349
+ static void mi_thread_data_free( mi_thread_data_t* tdfree ) {
350
+ // try to add the thread metadata to the cache
351
+ for (int i = 0; i < TD_CACHE_SIZE; i++) {
352
+ mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
353
+ if (td == NULL) {
354
+ mi_thread_data_t* expected = NULL;
355
+ if (mi_atomic_cas_ptr_weak_acq_rel(mi_thread_data_t, &td_cache[i], &expected, tdfree)) {
356
+ return;
357
+ }
358
+ }
359
+ }
360
+ // if that fails, just free it directly
361
+ _mi_os_free(tdfree, sizeof(mi_thread_data_t), tdfree->memid);
362
+ }
363
+
364
+ void _mi_thread_data_collect(void) {
365
+ // free all thread metadata from the cache
366
+ for (int i = 0; i < TD_CACHE_SIZE; i++) {
367
+ mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
368
+ if (td != NULL) {
369
+ td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
370
+ if (td != NULL) {
371
+ _mi_os_free(td, sizeof(mi_thread_data_t), td->memid);
372
+ }
373
+ }
374
+ }
375
+ }
376
+
377
+ // Initialize the thread local default heap, called from `mi_thread_init`
378
+ static bool _mi_thread_heap_init(void) {
379
+ if (mi_heap_is_initialized(mi_prim_get_default_heap())) return true;
380
+ if (_mi_is_main_thread()) {
381
+ // mi_assert_internal(_mi_heap_main.thread_id != 0); // can happen on freeBSD where alloc is called before any initialization
382
+ // the main heap is statically allocated
383
+ mi_heap_main_init();
384
+ _mi_heap_set_default_direct(&_mi_heap_main);
385
+ //mi_assert_internal(_mi_heap_default->tld->heap_backing == mi_prim_get_default_heap());
386
+ }
387
+ else {
388
+ // use `_mi_os_alloc` to allocate directly from the OS
389
+ mi_thread_data_t* td = mi_thread_data_zalloc();
390
+ if (td == NULL) return false;
391
+
392
+ mi_tld_t* tld = &td->tld;
393
+ mi_heap_t* heap = &td->heap;
394
+ _mi_tld_init(tld, heap); // must be before `_mi_heap_init`
395
+ _mi_heap_init(heap, tld, _mi_arena_id_none(), false /* can reclaim */, 0 /* default tag */);
396
+ _mi_heap_set_default_direct(heap);
397
+ }
398
+ return false;
399
+ }
400
+
401
+ // initialize thread local data
402
+ void _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap) {
403
+ _mi_memcpy_aligned(tld, &tld_empty, sizeof(mi_tld_t));
404
+ tld->heap_backing = bheap;
405
+ tld->heaps = NULL;
406
+ tld->segments.subproc = &mi_subproc_default;
407
+ tld->segments.stats = &tld->stats;
408
+ }
409
+
410
+ // Free the thread local default heap (called from `mi_thread_done`)
411
+ static bool _mi_thread_heap_done(mi_heap_t* heap) {
412
+ if (!mi_heap_is_initialized(heap)) return true;
413
+
414
+ // reset default heap
415
+ _mi_heap_set_default_direct(_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty);
416
+
417
+ // switch to backing heap
418
+ heap = heap->tld->heap_backing;
419
+ if (!mi_heap_is_initialized(heap)) return false;
420
+
421
+ // delete all non-backing heaps in this thread
422
+ mi_heap_t* curr = heap->tld->heaps;
423
+ while (curr != NULL) {
424
+ mi_heap_t* next = curr->next; // save `next` as `curr` will be freed
425
+ if (curr != heap) {
426
+ mi_assert_internal(!mi_heap_is_backing(curr));
427
+ mi_heap_delete(curr);
428
+ }
429
+ curr = next;
430
+ }
431
+ mi_assert_internal(heap->tld->heaps == heap && heap->next == NULL);
432
+ mi_assert_internal(mi_heap_is_backing(heap));
433
+
434
+ // collect if not the main thread
435
+ if (heap != &_mi_heap_main) {
436
+ _mi_heap_collect_abandon(heap);
437
+ }
438
+
439
+ // merge stats
440
+ _mi_stats_done(&heap->tld->stats);
441
+
442
+ // free if not the main thread
443
+ if (heap != &_mi_heap_main) {
444
+ // the following assertion does not always hold for huge segments as those are always treated
445
+ // as abondened: one may allocate it in one thread, but deallocate in another in which case
446
+ // the count can be too large or negative. todo: perhaps not count huge segments? see issue #363
447
+ // mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id());
448
+ mi_thread_data_free((mi_thread_data_t*)heap);
449
+ }
450
+ else {
451
+ #if 0
452
+ // never free the main thread even in debug mode; if a dll is linked statically with mimalloc,
453
+ // there may still be delete/free calls after the mi_fls_done is called. Issue #207
454
+ _mi_heap_destroy_pages(heap);
455
+ mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main);
456
+ #endif
457
+ }
458
+ return false;
459
+ }
460
+
461
+
462
+
463
+ // --------------------------------------------------------
464
+ // Try to run `mi_thread_done()` automatically so any memory
465
+ // owned by the thread but not yet released can be abandoned
466
+ // and re-owned by another thread.
467
+ //
468
+ // 1. windows dynamic library:
469
+ // call from DllMain on DLL_THREAD_DETACH
470
+ // 2. windows static library:
471
+ // use `FlsAlloc` to call a destructor when the thread is done
472
+ // 3. unix, pthreads:
473
+ // use a pthread key to call a destructor when a pthread is done
474
+ //
475
+ // In the last two cases we also need to call `mi_process_init`
476
+ // to set up the thread local keys.
477
+ // --------------------------------------------------------
478
+
479
+ // Set up handlers so `mi_thread_done` is called automatically
480
+ static void mi_process_setup_auto_thread_done(void) {
481
+ static bool tls_initialized = false; // fine if it races
482
+ if (tls_initialized) return;
483
+ tls_initialized = true;
484
+ _mi_prim_thread_init_auto_done();
485
+ _mi_heap_set_default_direct(&_mi_heap_main);
486
+ }
487
+
488
+
489
+ bool _mi_is_main_thread(void) {
490
+ return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id());
491
+ }
492
+
493
+ static _Atomic(size_t) thread_count = MI_ATOMIC_VAR_INIT(1);
494
+
495
+ size_t _mi_current_thread_count(void) {
496
+ return mi_atomic_load_relaxed(&thread_count);
497
+ }
498
+
499
+ // This is called from the `mi_malloc_generic`
500
+ void mi_thread_init(void) mi_attr_noexcept
501
+ {
502
+ // ensure our process has started already
503
+ mi_process_init();
504
+
505
+ // initialize the thread local default heap
506
+ // (this will call `_mi_heap_set_default_direct` and thus set the
507
+ // fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called)
508
+ if (_mi_thread_heap_init()) return; // returns true if already initialized
509
+
510
+ _mi_stat_increase(&_mi_stats_main.threads, 1);
511
+ mi_atomic_increment_relaxed(&thread_count);
512
+ //_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id());
513
+ }
514
+
515
+ void mi_thread_done(void) mi_attr_noexcept {
516
+ _mi_thread_done(NULL);
517
+ }
518
+
519
+ void _mi_thread_done(mi_heap_t* heap)
520
+ {
521
+ // calling with NULL implies using the default heap
522
+ if (heap == NULL) {
523
+ heap = mi_prim_get_default_heap();
524
+ if (heap == NULL) return;
525
+ }
526
+
527
+ // prevent re-entrancy through heap_done/heap_set_default_direct (issue #699)
528
+ if (!mi_heap_is_initialized(heap)) {
529
+ return;
530
+ }
531
+
532
+ // adjust stats
533
+ mi_atomic_decrement_relaxed(&thread_count);
534
+ _mi_stat_decrease(&_mi_stats_main.threads, 1);
535
+
536
+ // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps...
537
+ if (heap->thread_id != _mi_thread_id()) return;
538
+
539
+ // abandon the thread local heap
540
+ if (_mi_thread_heap_done(heap)) return; // returns true if already ran
541
+ }
542
+
543
+ void _mi_heap_set_default_direct(mi_heap_t* heap) {
544
+ mi_assert_internal(heap != NULL);
545
+ #if defined(MI_TLS_SLOT)
546
+ mi_prim_tls_slot_set(MI_TLS_SLOT,heap);
547
+ #elif defined(MI_TLS_PTHREAD_SLOT_OFS)
548
+ *mi_prim_tls_pthread_heap_slot() = heap;
549
+ #elif defined(MI_TLS_PTHREAD)
550
+ // we use _mi_heap_default_key
551
+ #else
552
+ _mi_heap_default = heap;
553
+ #endif
554
+
555
+ // ensure the default heap is passed to `_mi_thread_done`
556
+ // setting to a non-NULL value also ensures `mi_thread_done` is called.
557
+ _mi_prim_thread_associate_default_heap(heap);
558
+ }
559
+
560
+ void mi_thread_set_in_threadpool(void) mi_attr_noexcept {
561
+ // nothing
562
+ }
563
+
564
+ // --------------------------------------------------------
565
+ // Run functions on process init/done, and thread init/done
566
+ // --------------------------------------------------------
567
+ static bool os_preloading = true; // true until this module is initialized
568
+
569
+ // Returns true if this module has not been initialized; Don't use C runtime routines until it returns false.
570
+ bool mi_decl_noinline _mi_preloading(void) {
571
+ return os_preloading;
572
+ }
573
+
574
+ // Returns true if mimalloc was redirected
575
+ mi_decl_nodiscard bool mi_is_redirected(void) mi_attr_noexcept {
576
+ return _mi_is_redirected();
577
+ }
578
+
579
+ // Called once by the process loader from `src/prim/prim.c`
580
+ void _mi_auto_process_init(void) {
581
+ mi_heap_main_init();
582
+ #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD)
583
+ volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true;
584
+ if (dummy == NULL) return; // use dummy or otherwise the access may get optimized away (issue #697)
585
+ #endif
586
+ os_preloading = false;
587
+ mi_assert_internal(_mi_is_main_thread());
588
+ _mi_options_init();
589
+ mi_process_setup_auto_thread_done();
590
+ mi_process_init();
591
+ if (_mi_is_redirected()) _mi_verbose_message("malloc is redirected.\n");
592
+
593
+ // show message from the redirector (if present)
594
+ const char* msg = NULL;
595
+ _mi_allocator_init(&msg);
596
+ if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) {
597
+ _mi_fputs(NULL,NULL,NULL,msg);
598
+ }
599
+
600
+ // reseed random
601
+ _mi_random_reinit_if_weak(&_mi_heap_main.random);
602
+ }
603
+
604
+ #if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
605
+ #include <intrin.h>
606
+ mi_decl_cache_align bool _mi_cpu_has_fsrm = false;
607
+ mi_decl_cache_align bool _mi_cpu_has_erms = false;
608
+
609
+ static void mi_detect_cpu_features(void) {
610
+ // FSRM for fast short rep movsb/stosb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017))
611
+ // EMRS for fast enhanced rep movsb/stosb support
612
+ int32_t cpu_info[4];
613
+ __cpuid(cpu_info, 7);
614
+ _mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>
615
+ _mi_cpu_has_erms = ((cpu_info[1] & (1 << 9)) != 0); // bit 9 of EBX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>
616
+ }
617
+ #else
618
+ static void mi_detect_cpu_features(void) {
619
+ // nothing
620
+ }
621
+ #endif
622
+
623
+ // Initialize the process; called by thread_init or the process loader
624
+ void mi_process_init(void) mi_attr_noexcept {
625
+ // ensure we are called once
626
+ static mi_atomic_once_t process_init;
627
+ #if _MSC_VER < 1920
628
+ mi_heap_main_init(); // vs2017 can dynamically re-initialize _mi_heap_main
629
+ #endif
630
+ if (!mi_atomic_once(&process_init)) return;
631
+ _mi_process_is_initialized = true;
632
+ _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id());
633
+ mi_process_setup_auto_thread_done();
634
+
635
+ mi_detect_cpu_features();
636
+ _mi_os_init();
637
+ mi_heap_main_init();
638
+ mi_thread_init();
639
+
640
+ #if defined(_WIN32)
641
+ // On windows, when building as a static lib the FLS cleanup happens to early for the main thread.
642
+ // To avoid this, set the FLS value for the main thread to NULL so the fls cleanup
643
+ // will not call _mi_thread_done on the (still executing) main thread. See issue #508.
644
+ _mi_prim_thread_associate_default_heap(NULL);
645
+ #endif
646
+
647
+ mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL)
648
+ mi_track_init();
649
+
650
+ if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
651
+ size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024);
652
+ long reserve_at = mi_option_get(mi_option_reserve_huge_os_pages_at);
653
+ if (reserve_at != -1) {
654
+ mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500);
655
+ } else {
656
+ mi_reserve_huge_os_pages_interleave(pages, 0, pages*500);
657
+ }
658
+ }
659
+ if (mi_option_is_enabled(mi_option_reserve_os_memory)) {
660
+ long ksize = mi_option_get(mi_option_reserve_os_memory);
661
+ if (ksize > 0) {
662
+ mi_reserve_os_memory((size_t)ksize*MI_KiB, true /* commit? */, true /* allow large pages? */);
663
+ }
664
+ }
665
+ }
666
+
667
+ // Called when the process is done (cdecl as it is used with `at_exit` on some platforms)
668
+ void mi_cdecl mi_process_done(void) mi_attr_noexcept {
669
+ // only shutdown if we were initialized
670
+ if (!_mi_process_is_initialized) return;
671
+ // ensure we are called once
672
+ static bool process_done = false;
673
+ if (process_done) return;
674
+ process_done = true;
675
+
676
+ // get the default heap so we don't need to acces thread locals anymore
677
+ mi_heap_t* heap = mi_prim_get_default_heap(); // use prim to not initialize any heap
678
+ mi_assert_internal(heap != NULL);
679
+
680
+ // release any thread specific resources and ensure _mi_thread_done is called on all but the main thread
681
+ _mi_prim_thread_done_auto_done();
682
+
683
+
684
+ #ifndef MI_SKIP_COLLECT_ON_EXIT
685
+ #if (MI_DEBUG || !defined(MI_SHARED_LIB))
686
+ // free all memory if possible on process exit. This is not needed for a stand-alone process
687
+ // but should be done if mimalloc is statically linked into another shared library which
688
+ // is repeatedly loaded/unloaded, see issue #281.
689
+ mi_heap_collect(heap, true /* force */ );
690
+ #endif
691
+ #endif
692
+
693
+ // Forcefully release all retained memory; this can be dangerous in general if overriding regular malloc/free
694
+ // since after process_done there might still be other code running that calls `free` (like at_exit routines,
695
+ // or C-runtime termination code.
696
+ if (mi_option_is_enabled(mi_option_destroy_on_exit)) {
697
+ mi_heap_collect(heap, true /* force */);
698
+ _mi_heap_unsafe_destroy_all(heap); // forcefully release all memory held by all heaps (of this thread only!)
699
+ _mi_arena_unsafe_destroy_all();
700
+ _mi_segment_map_unsafe_destroy();
701
+ }
702
+
703
+ if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {
704
+ mi_stats_print(NULL);
705
+ }
706
+ _mi_allocator_done();
707
+ _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id);
708
+ os_preloading = true; // don't call the C runtime anymore
709
+ }
710
+
711
+ void mi_cdecl _mi_auto_process_done(void) mi_attr_noexcept {
712
+ if (_mi_option_get_fast(mi_option_destroy_on_exit)>1) return;
713
+ mi_process_done();
714
+ }