@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.
- package/LICENSE.md +17 -0
- package/README.md +80 -0
- package/out/cjs/index.cjs +51 -0
- package/out/cjs/yo-cli.cjs +2158 -0
- package/out/esm/index.mjs +51 -0
- package/out/types/src/codegen/async/runtime.d.ts +2 -0
- package/out/types/src/codegen/async/state-code-gen.d.ts +10 -0
- package/out/types/src/codegen/async/state-machine.d.ts +13 -0
- package/out/types/src/codegen/c/collection.d.ts +3 -0
- package/out/types/src/codegen/codegen-c.d.ts +12 -0
- package/out/types/src/codegen/constants.d.ts +3 -0
- package/out/types/src/codegen/expressions/array.d.ts +4 -0
- package/out/types/src/codegen/expressions/generation.d.ts +11 -0
- package/out/types/src/codegen/expressions/index.d.ts +2 -0
- package/out/types/src/codegen/functions/collection.d.ts +5 -0
- package/out/types/src/codegen/functions/context.d.ts +57 -0
- package/out/types/src/codegen/functions/generation.d.ts +25 -0
- package/out/types/src/codegen/functions/index.d.ts +2 -0
- package/out/types/src/codegen/index.d.ts +20 -0
- package/out/types/src/codegen/parallelism/runtime.d.ts +2 -0
- package/out/types/src/codegen/types/collection.d.ts +8 -0
- package/out/types/src/codegen/types/generation.d.ts +13 -0
- package/out/types/src/codegen/types/index.d.ts +2 -0
- package/out/types/src/codegen/utils/fixup.d.ts +2 -0
- package/out/types/src/codegen/utils/index.d.ts +77 -0
- package/out/types/src/codegen/values/index.d.ts +1 -0
- package/out/types/src/emitter.d.ts +11 -0
- package/out/types/src/env.d.ts +85 -0
- package/out/types/src/error.d.ts +45 -0
- package/out/types/src/evaluator/async/await-analysis-types.d.ts +23 -0
- package/out/types/src/evaluator/async/await-analysis.d.ts +5 -0
- package/out/types/src/evaluator/builtins/alignof.d.ts +8 -0
- package/out/types/src/evaluator/builtins/and_or.d.ts +8 -0
- package/out/types/src/evaluator/builtins/arc_fns.d.ts +58 -0
- package/out/types/src/evaluator/builtins/array_fns.d.ts +0 -0
- package/out/types/src/evaluator/builtins/as.d.ts +8 -0
- package/out/types/src/evaluator/builtins/async_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_assert.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_boolean_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_expect_error.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_list_fns.d.ts +33 -0
- package/out/types/src/evaluator/builtins/compt_print.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_string_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/consume.d.ts +8 -0
- package/out/types/src/evaluator/builtins/drop.d.ts +8 -0
- package/out/types/src/evaluator/builtins/dup.d.ts +8 -0
- package/out/types/src/evaluator/builtins/expr_fns.d.ts +33 -0
- package/out/types/src/evaluator/builtins/future_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/gc.d.ts +8 -0
- package/out/types/src/evaluator/builtins/gensym.d.ts +8 -0
- package/out/types/src/evaluator/builtins/impl_constraint.d.ts +8 -0
- package/out/types/src/evaluator/builtins/macro_expand.d.ts +8 -0
- package/out/types/src/evaluator/builtins/numeric_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/panic.d.ts +8 -0
- package/out/types/src/evaluator/builtins/ptr_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/quote.d.ts +13 -0
- package/out/types/src/evaluator/builtins/rc.d.ts +8 -0
- package/out/types/src/evaluator/builtins/sizeof.d.ts +8 -0
- package/out/types/src/evaluator/builtins/the.d.ts +8 -0
- package/out/types/src/evaluator/builtins/type_fns.d.ts +28 -0
- package/out/types/src/evaluator/builtins/va_start.d.ts +8 -0
- package/out/types/src/evaluator/builtins/var_fns.d.ts +18 -0
- package/out/types/src/evaluator/calls/array.d.ts +13 -0
- package/out/types/src/evaluator/calls/array_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/closure_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/compt_function.d.ts +19 -0
- package/out/types/src/evaluator/calls/compt_list_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/function.d.ts +16 -0
- package/out/types/src/evaluator/calls/function_type.d.ts +15 -0
- package/out/types/src/evaluator/calls/helper.d.ts +42 -0
- package/out/types/src/evaluator/calls/iso.d.ts +15 -0
- package/out/types/src/evaluator/calls/module_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/numeric_type.d.ts +15 -0
- package/out/types/src/evaluator/calls/pointer.d.ts +8 -0
- package/out/types/src/evaluator/calls/pointer_type.d.ts +14 -0
- package/out/types/src/evaluator/calls/type.d.ts +12 -0
- package/out/types/src/evaluator/context.d.ts +169 -0
- package/out/types/src/evaluator/exprs/_expr.d.ts +8 -0
- package/out/types/src/evaluator/exprs/assignment.d.ts +9 -0
- package/out/types/src/evaluator/exprs/begin.d.ts +10 -0
- package/out/types/src/evaluator/exprs/binding.d.ts +12 -0
- package/out/types/src/evaluator/exprs/c_include.d.ts +8 -0
- package/out/types/src/evaluator/exprs/cond.d.ts +8 -0
- package/out/types/src/evaluator/exprs/destructuring_assignment.d.ts +33 -0
- package/out/types/src/evaluator/exprs/exists.d.ts +0 -0
- package/out/types/src/evaluator/exprs/expr.d.ts +9 -0
- package/out/types/src/evaluator/exprs/extern.d.ts +8 -0
- package/out/types/src/evaluator/exprs/identifer_and_operator.d.ts +9 -0
- package/out/types/src/evaluator/exprs/import.d.ts +9 -0
- package/out/types/src/evaluator/exprs/initialization_assignment.d.ts +8 -0
- package/out/types/src/evaluator/exprs/match.d.ts +8 -0
- package/out/types/src/evaluator/exprs/open.d.ts +8 -0
- package/out/types/src/evaluator/exprs/property_access.d.ts +8 -0
- package/out/types/src/evaluator/exprs/recur.d.ts +8 -0
- package/out/types/src/evaluator/exprs/subtype_of.d.ts +21 -0
- package/out/types/src/evaluator/exprs/test.d.ts +8 -0
- package/out/types/src/evaluator/exprs/typeof.d.ts +8 -0
- package/out/types/src/evaluator/exprs/while.d.ts +8 -0
- package/out/types/src/evaluator/index.d.ts +26 -0
- package/out/types/src/evaluator/types/array.d.ts +8 -0
- package/out/types/src/evaluator/types/closure.d.ts +8 -0
- package/out/types/src/evaluator/types/compt_list.d.ts +8 -0
- package/out/types/src/evaluator/types/concrete_module.d.ts +8 -0
- package/out/types/src/evaluator/types/dyn.d.ts +8 -0
- package/out/types/src/evaluator/types/enum.d.ts +8 -0
- package/out/types/src/evaluator/types/expr_synthesizer.d.ts +14 -0
- package/out/types/src/evaluator/types/field.d.ts +14 -0
- package/out/types/src/evaluator/types/fn_module.d.ts +8 -0
- package/out/types/src/evaluator/types/function.d.ts +58 -0
- package/out/types/src/evaluator/types/future_module.d.ts +8 -0
- package/out/types/src/evaluator/types/module.d.ts +19 -0
- package/out/types/src/evaluator/types/newtype.d.ts +8 -0
- package/out/types/src/evaluator/types/object.d.ts +8 -0
- package/out/types/src/evaluator/types/proofs.d.ts +0 -0
- package/out/types/src/evaluator/types/slice.d.ts +8 -0
- package/out/types/src/evaluator/types/struct.d.ts +8 -0
- package/out/types/src/evaluator/types/synthesizer.d.ts +16 -0
- package/out/types/src/evaluator/types/tuple.d.ts +18 -0
- package/out/types/src/evaluator/types/union.d.ts +8 -0
- package/out/types/src/evaluator/types/utils.d.ts +71 -0
- package/out/types/src/evaluator/types/validation.d.ts +3 -0
- package/out/types/src/evaluator/utils/array-utils.d.ts +15 -0
- package/out/types/src/evaluator/utils/closure.d.ts +35 -0
- package/out/types/src/evaluator/utils.d.ts +4 -0
- package/out/types/src/evaluator/values/anonymous_function.d.ts +8 -0
- package/out/types/src/evaluator/values/anonymous_module.d.ts +17 -0
- package/out/types/src/evaluator/values/anonymous_struct.d.ts +8 -0
- package/out/types/src/evaluator/values/array.d.ts +8 -0
- package/out/types/src/evaluator/values/boolean.d.ts +3 -0
- package/out/types/src/evaluator/values/char.d.ts +3 -0
- package/out/types/src/evaluator/values/compt_list.d.ts +8 -0
- package/out/types/src/evaluator/values/dyn.d.ts +8 -0
- package/out/types/src/evaluator/values/float.d.ts +4 -0
- package/out/types/src/evaluator/values/integer.d.ts +4 -0
- package/out/types/src/evaluator/values/module.d.ts +58 -0
- package/out/types/src/evaluator/values/string.d.ts +3 -0
- package/out/types/src/evaluator/values/tuple.d.ts +32 -0
- package/out/types/src/expr.d.ts +456 -0
- package/out/types/src/function-value.d.ts +42 -0
- package/out/types/src/index.d.ts +4 -0
- package/out/types/src/lexer.d.ts +2 -0
- package/out/types/src/logger.d.ts +1 -0
- package/out/types/src/module-manager.d.ts +30 -0
- package/out/types/src/naming-checker.d.ts +4 -0
- package/out/types/src/parser.d.ts +33 -0
- package/out/types/src/test-runner.d.ts +30 -0
- package/out/types/src/tests/codegen.test.d.ts +1 -0
- package/out/types/src/tests/fixme.test.d.ts +1 -0
- package/out/types/src/tests/module-manager.test.d.ts +1 -0
- package/out/types/src/tests/parser.test.d.ts +1 -0
- package/out/types/src/tests/sample.test.d.ts +0 -0
- package/out/types/src/tests/std.test.d.ts +1 -0
- package/out/types/src/token.d.ts +40 -0
- package/out/types/src/type-value.d.ts +7 -0
- package/out/types/src/types/compatibility.d.ts +16 -0
- package/out/types/src/types/creators.d.ts +73 -0
- package/out/types/src/types/definitions.d.ts +218 -0
- package/out/types/src/types/guards.d.ts +70 -0
- package/out/types/src/types/hierarchy.d.ts +4 -0
- package/out/types/src/types/index.d.ts +7 -0
- package/out/types/src/types/module_field.d.ts +2 -0
- package/out/types/src/types/tags.d.ts +45 -0
- package/out/types/src/types/utils.d.ts +50 -0
- package/out/types/src/unit-value.d.ts +7 -0
- package/out/types/src/utils.d.ts +6 -0
- package/out/types/src/value-tag.d.ts +29 -0
- package/out/types/src/value.d.ts +110 -0
- package/out/types/src/yo-cli.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +57 -0
- package/scripts/check-liburing.js +76 -0
- package/std/alg/hash.yo +50 -0
- package/std/allocator.yo +113 -0
- package/std/allocators/c_allocator.yo +118 -0
- package/std/async.yo +13 -0
- package/std/collections/array_list.yo +415 -0
- package/std/collections/hash_map.yo +482 -0
- package/std/collections/hash_set.yo +706 -0
- package/std/collections/index.yo +11 -0
- package/std/collections/linked_list.yo +439 -0
- package/std/error.yo +0 -0
- package/std/gc.yo +10 -0
- package/std/index.yo +12 -0
- package/std/io/file.yo +191 -0
- package/std/io/index.yo +5 -0
- package/std/libc/assert.yo +39 -0
- package/std/libc/ctype.yo +57 -0
- package/std/libc/errno.yo +182 -0
- package/std/libc/float.yo +87 -0
- package/std/libc/index.yo +29 -0
- package/std/libc/limits.yo +65 -0
- package/std/libc/math.yo +679 -0
- package/std/libc/signal.yo +101 -0
- package/std/libc/stdatomic.yo +213 -0
- package/std/libc/stdint.yo +214 -0
- package/std/libc/stdio.yo +225 -0
- package/std/libc/stdlib.yo +204 -0
- package/std/libc/string.yo +151 -0
- package/std/libc/time.yo +92 -0
- package/std/libc/unistd.yo +130 -0
- package/std/monad.yo +152 -0
- package/std/prelude.yo +3094 -0
- package/std/string/index.yo +8 -0
- package/std/string/rune.yo +82 -0
- package/std/string/string.yo +288 -0
- package/std/sync.yo +95 -0
- package/std/thread.yo +36 -0
- package/std/time.yo +13 -0
- package/std/worker.yo +36 -0
- package/vendor/mimalloc/.gitattributes +12 -0
- package/vendor/mimalloc/CMakeLists.txt +763 -0
- package/vendor/mimalloc/LICENSE +21 -0
- package/vendor/mimalloc/SECURITY.md +41 -0
- package/vendor/mimalloc/azure-pipelines.yml +251 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64.lib +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.lib +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect.lib +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect32.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect32.lib +0 -0
- package/vendor/mimalloc/bin/minject-arm64.exe +0 -0
- package/vendor/mimalloc/bin/minject.exe +0 -0
- package/vendor/mimalloc/bin/minject32.exe +0 -0
- package/vendor/mimalloc/bin/readme.md +118 -0
- package/vendor/mimalloc/cmake/JoinPaths.cmake +23 -0
- package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +19 -0
- package/vendor/mimalloc/cmake/mimalloc-config.cmake +14 -0
- package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +23 -0
- package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +28 -0
- package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +28 -0
- package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +23 -0
- package/vendor/mimalloc/contrib/docker/readme.md +10 -0
- package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +64 -0
- package/vendor/mimalloc/contrib/vcpkg/readme.md +40 -0
- package/vendor/mimalloc/contrib/vcpkg/usage +20 -0
- package/vendor/mimalloc/contrib/vcpkg/vcpkg-cmake-wrapper.cmake +20 -0
- package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +48 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg +887 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg +1185 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg +757 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg +1028 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-1.svg +769 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg +868 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg +1157 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-2.svg +983 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg +683 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg +854 -0
- package/vendor/mimalloc/doc/bench-2020/bench-spec-rss.svg +713 -0
- package/vendor/mimalloc/doc/bench-2020/bench-spec.svg +713 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-1.svg +890 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-2.svg +1146 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-1.svg +796 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-2.svg +974 -0
- package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg +952 -0
- package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg +1255 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg +955 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg +1269 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg +836 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg +1131 -0
- package/vendor/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg +766 -0
- package/vendor/mimalloc/doc/doxyfile +2895 -0
- package/vendor/mimalloc/doc/ds-logo.jpg +0 -0
- package/vendor/mimalloc/doc/ds-logo.png +0 -0
- package/vendor/mimalloc/doc/mimalloc-doc.h +1452 -0
- package/vendor/mimalloc/doc/mimalloc-doxygen.css +60 -0
- package/vendor/mimalloc/doc/mimalloc-logo-100.png +0 -0
- package/vendor/mimalloc/doc/mimalloc-logo.png +0 -0
- package/vendor/mimalloc/doc/mimalloc-logo.svg +161 -0
- package/vendor/mimalloc/doc/spades-logo.png +0 -0
- package/vendor/mimalloc/doc/unreal-logo.svg +43 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +500 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj.filters +108 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj +508 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj.filters +111 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-test-dep.vcxproj +355 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj +360 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj +295 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj +292 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test.vcxproj +289 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc.sln +151 -0
- package/vendor/mimalloc/include/mimalloc/atomic.h +557 -0
- package/vendor/mimalloc/include/mimalloc/internal.h +1153 -0
- package/vendor/mimalloc/include/mimalloc/prim.h +421 -0
- package/vendor/mimalloc/include/mimalloc/track.h +145 -0
- package/vendor/mimalloc/include/mimalloc/types.h +685 -0
- package/vendor/mimalloc/include/mimalloc-new-delete.h +66 -0
- package/vendor/mimalloc/include/mimalloc-override.h +68 -0
- package/vendor/mimalloc/include/mimalloc-stats.h +103 -0
- package/vendor/mimalloc/include/mimalloc.h +612 -0
- package/vendor/mimalloc/mimalloc.pc.in +11 -0
- package/vendor/mimalloc/readme.md +946 -0
- package/vendor/mimalloc/src/alloc-aligned.c +360 -0
- package/vendor/mimalloc/src/alloc-override.c +316 -0
- package/vendor/mimalloc/src/alloc-posix.c +185 -0
- package/vendor/mimalloc/src/alloc.c +692 -0
- package/vendor/mimalloc/src/arena-abandon.c +346 -0
- package/vendor/mimalloc/src/arena.c +1043 -0
- package/vendor/mimalloc/src/bitmap.c +441 -0
- package/vendor/mimalloc/src/bitmap.h +119 -0
- package/vendor/mimalloc/src/free.c +572 -0
- package/vendor/mimalloc/src/heap.c +733 -0
- package/vendor/mimalloc/src/init.c +714 -0
- package/vendor/mimalloc/src/libc.c +334 -0
- package/vendor/mimalloc/src/options.c +663 -0
- package/vendor/mimalloc/src/os.c +770 -0
- package/vendor/mimalloc/src/page-queue.c +390 -0
- package/vendor/mimalloc/src/page.c +1049 -0
- package/vendor/mimalloc/src/prim/emscripten/prim.c +249 -0
- package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +461 -0
- package/vendor/mimalloc/src/prim/osx/prim.c +9 -0
- package/vendor/mimalloc/src/prim/prim.c +76 -0
- package/vendor/mimalloc/src/prim/readme.md +9 -0
- package/vendor/mimalloc/src/prim/unix/prim.c +934 -0
- package/vendor/mimalloc/src/prim/wasi/prim.c +284 -0
- package/vendor/mimalloc/src/prim/windows/etw-mimalloc.wprp +61 -0
- package/vendor/mimalloc/src/prim/windows/etw.h +905 -0
- package/vendor/mimalloc/src/prim/windows/etw.man +0 -0
- package/vendor/mimalloc/src/prim/windows/prim.c +878 -0
- package/vendor/mimalloc/src/prim/windows/readme.md +17 -0
- package/vendor/mimalloc/src/random.c +258 -0
- package/vendor/mimalloc/src/segment-map.c +142 -0
- package/vendor/mimalloc/src/segment.c +1702 -0
- package/vendor/mimalloc/src/static.c +41 -0
- package/vendor/mimalloc/src/stats.c +635 -0
- package/vendor/mimalloc/test/CMakeLists.txt +56 -0
- package/vendor/mimalloc/test/main-override-dep.cpp +51 -0
- package/vendor/mimalloc/test/main-override-dep.h +11 -0
- package/vendor/mimalloc/test/main-override-static.c +539 -0
- package/vendor/mimalloc/test/main-override.c +36 -0
- package/vendor/mimalloc/test/main-override.cpp +497 -0
- package/vendor/mimalloc/test/main.c +46 -0
- package/vendor/mimalloc/test/readme.md +16 -0
- package/vendor/mimalloc/test/test-api-fill.c +343 -0
- package/vendor/mimalloc/test/test-api.c +466 -0
- package/vendor/mimalloc/test/test-stress.c +428 -0
- package/vendor/mimalloc/test/test-wrong.c +92 -0
- package/vendor/mimalloc/test/testhelper.h +49 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.18)
|
|
2
|
+
project(mimalloc-test C CXX)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_C_STANDARD 11)
|
|
5
|
+
set(CMAKE_CXX_STANDARD 17)
|
|
6
|
+
|
|
7
|
+
# Set default build type
|
|
8
|
+
if (NOT CMAKE_BUILD_TYPE)
|
|
9
|
+
if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$")
|
|
10
|
+
message(STATUS "No build type selected, default to *** Debug ***")
|
|
11
|
+
set(CMAKE_BUILD_TYPE "Debug")
|
|
12
|
+
else()
|
|
13
|
+
message(STATUS "No build type selected, default to *** Release ***")
|
|
14
|
+
set(CMAKE_BUILD_TYPE "Release")
|
|
15
|
+
endif()
|
|
16
|
+
endif()
|
|
17
|
+
|
|
18
|
+
# Import mimalloc (if installed)
|
|
19
|
+
find_package(mimalloc 2.2 CONFIG REQUIRED)
|
|
20
|
+
message(STATUS "Found mimalloc installed at: ${MIMALLOC_LIBRARY_DIR} (${MIMALLOC_VERSION_DIR})")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# link with a dynamic shared library
|
|
24
|
+
# use `LD_PRELOAD` to actually override malloc/free at runtime with mimalloc
|
|
25
|
+
add_executable(dynamic-override main-override.c)
|
|
26
|
+
target_link_libraries(dynamic-override PUBLIC mimalloc)
|
|
27
|
+
|
|
28
|
+
add_executable(dynamic-override-cxx main-override.cpp)
|
|
29
|
+
target_link_libraries(dynamic-override-cxx PUBLIC mimalloc)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# overriding with a static object file works reliable as the symbols in the
|
|
33
|
+
# object file have priority over those in library files
|
|
34
|
+
add_executable(static-override-obj main-override.c ${MIMALLOC_OBJECT_DIR}/mimalloc${CMAKE_C_OUTPUT_EXTENSION})
|
|
35
|
+
target_include_directories(static-override-obj PUBLIC ${MIMALLOC_INCLUDE_DIR})
|
|
36
|
+
target_link_libraries(static-override-obj PUBLIC mimalloc-static)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# overriding with a static library works too if using the `mimalloc-override.h`
|
|
40
|
+
# header to redefine malloc/free. (the library already overrides new/delete)
|
|
41
|
+
add_executable(static-override-static main-override-static.c)
|
|
42
|
+
target_link_libraries(static-override-static PUBLIC mimalloc-static)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# overriding with a static library: this may not work if the library is linked too late
|
|
46
|
+
# on the command line after the C runtime library; but we cannot control that well in CMake
|
|
47
|
+
add_executable(static-override main-override.c)
|
|
48
|
+
target_link_libraries(static-override PUBLIC mimalloc-static)
|
|
49
|
+
|
|
50
|
+
add_executable(static-override-cxx main-override.cpp)
|
|
51
|
+
target_link_libraries(static-override-cxx PUBLIC mimalloc-static)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## test memory errors
|
|
55
|
+
add_executable(test-wrong test-wrong.c)
|
|
56
|
+
target_link_libraries(test-wrong PUBLIC mimalloc)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Issue #981: test overriding allocation in a DLL that is compiled independent of mimalloc.
|
|
2
|
+
// This is imported by the `mimalloc-test-override` project.
|
|
3
|
+
#include <string>
|
|
4
|
+
#include <iostream>
|
|
5
|
+
#include "main-override-dep.h"
|
|
6
|
+
|
|
7
|
+
std::string TestAllocInDll::GetString()
|
|
8
|
+
{
|
|
9
|
+
char* test = new char[128];
|
|
10
|
+
memset(test, 0, 128);
|
|
11
|
+
const char* t = "test";
|
|
12
|
+
memcpy(test, t, 4);
|
|
13
|
+
std::string r = test;
|
|
14
|
+
std::cout << "override-dep: GetString: " << r << "\n";
|
|
15
|
+
delete[] test;
|
|
16
|
+
return r;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Static {
|
|
21
|
+
private:
|
|
22
|
+
void* p;
|
|
23
|
+
public:
|
|
24
|
+
Static() {
|
|
25
|
+
printf("override-dep: static constructor\n");
|
|
26
|
+
p = malloc(64);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
~Static() {
|
|
30
|
+
free(p);
|
|
31
|
+
printf("override-dep: static destructor\n");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
static Static s = Static();
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#include <windows.h>
|
|
40
|
+
|
|
41
|
+
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID reserved) {
|
|
42
|
+
(void)(reserved);
|
|
43
|
+
(void)(module);
|
|
44
|
+
if (reason==DLL_PROCESS_ATTACH) {
|
|
45
|
+
printf("override-dep: dll attach\n");
|
|
46
|
+
}
|
|
47
|
+
else if (reason==DLL_PROCESS_DETACH) {
|
|
48
|
+
printf("override-dep: dll detach\n");
|
|
49
|
+
}
|
|
50
|
+
return TRUE;
|
|
51
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
// Issue #981: test overriding allocation in a DLL that is compiled independent of mimalloc.
|
|
3
|
+
// This is imported by the `mimalloc-test-override` project.
|
|
4
|
+
|
|
5
|
+
#include <string>
|
|
6
|
+
|
|
7
|
+
class TestAllocInDll
|
|
8
|
+
{
|
|
9
|
+
public:
|
|
10
|
+
__declspec(dllexport) std::string GetString();
|
|
11
|
+
};
|
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
#if _WIN32
|
|
2
|
+
#include <windows.h>
|
|
3
|
+
#endif
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
#include <stdio.h>
|
|
6
|
+
#include <assert.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
|
|
10
|
+
#include <mimalloc.h>
|
|
11
|
+
#include <mimalloc-override.h> // redefines malloc etc.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
static void double_free1();
|
|
15
|
+
static void double_free2();
|
|
16
|
+
static void corrupt_free();
|
|
17
|
+
static void block_overflow1();
|
|
18
|
+
static void block_overflow2();
|
|
19
|
+
static void invalid_free();
|
|
20
|
+
static void test_aslr(void);
|
|
21
|
+
static void test_process_info(void);
|
|
22
|
+
static void test_reserved(void);
|
|
23
|
+
static void negative_stat(void);
|
|
24
|
+
static void alloc_huge(void);
|
|
25
|
+
static void test_heap_walk(void);
|
|
26
|
+
static void test_heap_arena(void);
|
|
27
|
+
static void test_align(void);
|
|
28
|
+
static void test_canary_leak(void);
|
|
29
|
+
static void test_manage_os_memory(void);
|
|
30
|
+
// static void test_large_pages(void);
|
|
31
|
+
|
|
32
|
+
int main() {
|
|
33
|
+
mi_version();
|
|
34
|
+
mi_stats_reset();
|
|
35
|
+
|
|
36
|
+
// mi_bins();
|
|
37
|
+
|
|
38
|
+
// test_manage_os_memory();
|
|
39
|
+
// test_large_pages();
|
|
40
|
+
// detect double frees and heap corruption
|
|
41
|
+
// double_free1();
|
|
42
|
+
// double_free2();
|
|
43
|
+
// corrupt_free();
|
|
44
|
+
// block_overflow1();
|
|
45
|
+
// block_overflow2();
|
|
46
|
+
test_canary_leak();
|
|
47
|
+
// test_aslr();
|
|
48
|
+
// invalid_free();
|
|
49
|
+
// test_reserved();
|
|
50
|
+
// negative_stat();
|
|
51
|
+
// test_heap_walk();
|
|
52
|
+
// alloc_huge();
|
|
53
|
+
// test_heap_walk();
|
|
54
|
+
// test_heap_arena();
|
|
55
|
+
// test_align();
|
|
56
|
+
|
|
57
|
+
void* p1 = malloc(78);
|
|
58
|
+
void* p2 = malloc(24);
|
|
59
|
+
free(p1);
|
|
60
|
+
p1 = mi_malloc(8);
|
|
61
|
+
char* s = strdup("hello\n");
|
|
62
|
+
free(p2);
|
|
63
|
+
|
|
64
|
+
mi_heap_t* h = mi_heap_new();
|
|
65
|
+
mi_heap_set_default(h);
|
|
66
|
+
|
|
67
|
+
p2 = malloc(16);
|
|
68
|
+
p1 = realloc(p1, 32);
|
|
69
|
+
free(p1);
|
|
70
|
+
free(p2);
|
|
71
|
+
free(s);
|
|
72
|
+
|
|
73
|
+
/* now test if override worked by allocating/freeing across the api's*/
|
|
74
|
+
//p1 = mi_malloc(32);
|
|
75
|
+
//free(p1);
|
|
76
|
+
//p2 = malloc(32);
|
|
77
|
+
//mi_free(p2);
|
|
78
|
+
|
|
79
|
+
//mi_collect(true);
|
|
80
|
+
//mi_stats_print(NULL);
|
|
81
|
+
|
|
82
|
+
// test_process_info();
|
|
83
|
+
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static void test_align() {
|
|
88
|
+
void* p = mi_malloc_aligned(256, 256);
|
|
89
|
+
if (((uintptr_t)p % 256) != 0) {
|
|
90
|
+
fprintf(stderr, "%p is not 256 alignend!\n", p);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static void invalid_free() {
|
|
95
|
+
free((void*)0xBADBEEF);
|
|
96
|
+
realloc((void*)0xBADBEEF,10);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static void block_overflow1() {
|
|
100
|
+
uint8_t* p = (uint8_t*)mi_malloc(17);
|
|
101
|
+
p[18] = 0;
|
|
102
|
+
free(p);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static void block_overflow2() {
|
|
106
|
+
uint8_t* p = (uint8_t*)mi_malloc(16);
|
|
107
|
+
p[17] = 0;
|
|
108
|
+
free(p);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// The double free samples come ArcHeap [1] by Insu Yun (issue #161)
|
|
112
|
+
// [1]: https://arxiv.org/pdf/1903.00503.pdf
|
|
113
|
+
|
|
114
|
+
static void double_free1() {
|
|
115
|
+
void* p[256];
|
|
116
|
+
//uintptr_t buf[256];
|
|
117
|
+
|
|
118
|
+
p[0] = mi_malloc(622616);
|
|
119
|
+
p[1] = mi_malloc(655362);
|
|
120
|
+
p[2] = mi_malloc(786432);
|
|
121
|
+
mi_free(p[2]);
|
|
122
|
+
// [VULN] Double free
|
|
123
|
+
mi_free(p[2]);
|
|
124
|
+
p[3] = mi_malloc(786456);
|
|
125
|
+
// [BUG] Found overlap
|
|
126
|
+
// p[3]=0x429b2ea2000 (size=917504), p[1]=0x429b2e42000 (size=786432)
|
|
127
|
+
fprintf(stderr, "p3: %p-%p, p1: %p-%p, p2: %p\n", p[3], (uint8_t*)(p[3]) + 786456, p[1], (uint8_t*)(p[1]) + 655362, p[2]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static void double_free2() {
|
|
131
|
+
void* p[256];
|
|
132
|
+
//uintptr_t buf[256];
|
|
133
|
+
// [INFO] Command buffer: 0x327b2000
|
|
134
|
+
// [INFO] Input size: 182
|
|
135
|
+
p[0] = malloc(712352);
|
|
136
|
+
p[1] = malloc(786432);
|
|
137
|
+
free(p[0]);
|
|
138
|
+
// [VULN] Double free
|
|
139
|
+
free(p[0]);
|
|
140
|
+
p[2] = malloc(786440);
|
|
141
|
+
p[3] = malloc(917504);
|
|
142
|
+
p[4] = malloc(786440);
|
|
143
|
+
// [BUG] Found overlap
|
|
144
|
+
// p[4]=0x433f1402000 (size=917504), p[1]=0x433f14c2000 (size=786432)
|
|
145
|
+
fprintf(stderr, "p1: %p-%p, p2: %p-%p\n", p[4], (uint8_t*)(p[4]) + 917504, p[1], (uint8_t*)(p[1]) + 786432);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
// Try to corrupt the heap through buffer overflow
|
|
150
|
+
#define N 256
|
|
151
|
+
#define SZ 64
|
|
152
|
+
|
|
153
|
+
static void corrupt_free() {
|
|
154
|
+
void* p[N];
|
|
155
|
+
// allocate
|
|
156
|
+
for (int i = 0; i < N; i++) {
|
|
157
|
+
p[i] = malloc(SZ);
|
|
158
|
+
}
|
|
159
|
+
// free some
|
|
160
|
+
for (int i = 0; i < N; i += (N/10)) {
|
|
161
|
+
free(p[i]);
|
|
162
|
+
p[i] = NULL;
|
|
163
|
+
}
|
|
164
|
+
// try to corrupt the free list
|
|
165
|
+
for (int i = 0; i < N; i++) {
|
|
166
|
+
if (p[i] != NULL) {
|
|
167
|
+
memset(p[i], 0, SZ+8);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// allocate more.. trying to trigger an allocation from a corrupted entry
|
|
171
|
+
// this may need many allocations to get there (if at all)
|
|
172
|
+
for (int i = 0; i < 4096; i++) {
|
|
173
|
+
malloc(SZ);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static void test_aslr(void) {
|
|
178
|
+
void* p[256];
|
|
179
|
+
p[0] = malloc(378200);
|
|
180
|
+
p[1] = malloc(1134626);
|
|
181
|
+
printf("p1: %p, p2: %p\n", p[0], p[1]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static void test_process_info(void) {
|
|
185
|
+
size_t elapsed = 0;
|
|
186
|
+
size_t user_msecs = 0;
|
|
187
|
+
size_t system_msecs = 0;
|
|
188
|
+
size_t current_rss = 0;
|
|
189
|
+
size_t peak_rss = 0;
|
|
190
|
+
size_t current_commit = 0;
|
|
191
|
+
size_t peak_commit = 0;
|
|
192
|
+
size_t page_faults = 0;
|
|
193
|
+
for (int i = 0; i < 100000; i++) {
|
|
194
|
+
void* p = calloc(100,10);
|
|
195
|
+
free(p);
|
|
196
|
+
}
|
|
197
|
+
mi_process_info(&elapsed, &user_msecs, &system_msecs, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults);
|
|
198
|
+
printf("\n\n*** process info: elapsed %3zd.%03zd s, user: %3zd.%03zd s, rss: %zd b, commit: %zd b\n\n", elapsed/1000, elapsed%1000, user_msecs/1000, user_msecs%1000, peak_rss, peak_commit);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static void test_reserved(void) {
|
|
202
|
+
#define KiB 1024ULL
|
|
203
|
+
#define MiB (KiB*KiB)
|
|
204
|
+
#define GiB (MiB*KiB)
|
|
205
|
+
mi_reserve_os_memory(4*GiB, false, true);
|
|
206
|
+
void* p1 = malloc(100);
|
|
207
|
+
void* p2 = malloc(100000);
|
|
208
|
+
void* p3 = malloc(2*GiB);
|
|
209
|
+
void* p4 = malloc(1*GiB + 100000);
|
|
210
|
+
free(p1);
|
|
211
|
+
free(p2);
|
|
212
|
+
free(p3);
|
|
213
|
+
p3 = malloc(1*GiB);
|
|
214
|
+
free(p4);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
static void negative_stat(void) {
|
|
220
|
+
int* p = mi_malloc(60000);
|
|
221
|
+
mi_stats_print_out(NULL, NULL);
|
|
222
|
+
*p = 100;
|
|
223
|
+
mi_free(p);
|
|
224
|
+
mi_stats_print_out(NULL, NULL);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
static void alloc_huge(void) {
|
|
228
|
+
void* p = mi_malloc(67108872);
|
|
229
|
+
mi_free(p);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
static bool test_visit(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) {
|
|
233
|
+
if (block == NULL) {
|
|
234
|
+
printf("visiting an area with blocks of size %zu (including padding)\n", area->full_block_size);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
printf(" block of size %zu (allocated size is %zu)\n", block_size, mi_usable_size(block));
|
|
238
|
+
}
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
static void test_heap_walk(void) {
|
|
243
|
+
mi_heap_t* heap = mi_heap_new();
|
|
244
|
+
mi_heap_malloc(heap, 16*2097152);
|
|
245
|
+
mi_heap_malloc(heap, 2067152);
|
|
246
|
+
mi_heap_malloc(heap, 2097160);
|
|
247
|
+
mi_heap_malloc(heap, 24576);
|
|
248
|
+
mi_heap_visit_blocks(heap, true, &test_visit, NULL);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
static void test_heap_arena(void) {
|
|
252
|
+
mi_arena_id_t arena_id;
|
|
253
|
+
int err = mi_reserve_os_memory_ex(100 * 1024 * 1024, false /* commit */, false /* allow large */, true /* exclusive */, &arena_id);
|
|
254
|
+
if (err) abort();
|
|
255
|
+
mi_heap_t* heap = mi_heap_new_in_arena(arena_id);
|
|
256
|
+
for (int i = 0; i < 500000; i++) {
|
|
257
|
+
void* p = mi_heap_malloc(heap, 1024);
|
|
258
|
+
if (p == NULL) {
|
|
259
|
+
printf("out of memory after %d kb (expecting about 100_000kb)\n", i);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static void test_canary_leak(void) {
|
|
266
|
+
char* p = mi_mallocn_tp(char,23);
|
|
267
|
+
for(int i = 0; i < 23; i++) {
|
|
268
|
+
p[i] = '0'+i;
|
|
269
|
+
}
|
|
270
|
+
puts(p);
|
|
271
|
+
free(p);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#if _WIN32
|
|
275
|
+
static void test_manage_os_memory(void) {
|
|
276
|
+
size_t size = 256 * 1024 * 1024;
|
|
277
|
+
void* ptr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
278
|
+
mi_arena_id_t arena_id;
|
|
279
|
+
mi_manage_os_memory_ex(ptr, size, true /* committed */, true /* pinned */, false /* is zero */, -1 /* numa node */, true /* exclusive */, &arena_id);
|
|
280
|
+
mi_heap_t* cuda_heap = mi_heap_new_in_arena(arena_id); // you can do this in any thread
|
|
281
|
+
|
|
282
|
+
// now allocate only in the cuda arena
|
|
283
|
+
void* p1 = mi_heap_malloc(cuda_heap, 8);
|
|
284
|
+
int* p2 = mi_heap_malloc_tp(cuda_heap, int);
|
|
285
|
+
*p2 = 42;
|
|
286
|
+
|
|
287
|
+
// and maybe set the cuda heap as the default heap? (but careful as now `malloc` will allocate in the cuda heap as well)
|
|
288
|
+
{
|
|
289
|
+
mi_heap_t* prev_default_heap = mi_heap_set_default(cuda_heap);
|
|
290
|
+
void* p3 = mi_malloc(8); // allocate in the cuda heap
|
|
291
|
+
mi_free(p3);
|
|
292
|
+
}
|
|
293
|
+
mi_free(p1);
|
|
294
|
+
mi_free(p2);
|
|
295
|
+
}
|
|
296
|
+
#else
|
|
297
|
+
static void test_manage_os_memory(void) {
|
|
298
|
+
// empty
|
|
299
|
+
}
|
|
300
|
+
#endif
|
|
301
|
+
|
|
302
|
+
// Experiment with huge OS pages
|
|
303
|
+
#if 0
|
|
304
|
+
|
|
305
|
+
#include <mimalloc/types.h>
|
|
306
|
+
#include <mimalloc/internal.h>
|
|
307
|
+
#include <unistd.h>
|
|
308
|
+
#include <sys/mman.h>
|
|
309
|
+
|
|
310
|
+
static void test_large_pages(void) {
|
|
311
|
+
mi_memid_t memid;
|
|
312
|
+
|
|
313
|
+
#if 0
|
|
314
|
+
size_t pages_reserved;
|
|
315
|
+
size_t page_size;
|
|
316
|
+
uint8_t* p = (uint8_t*)_mi_os_alloc_huge_os_pages(1, -1, 30000, &pages_reserved, &page_size, &memid);
|
|
317
|
+
const size_t req_size = pages_reserved * page_size;
|
|
318
|
+
#else
|
|
319
|
+
const size_t req_size = 64*MI_MiB;
|
|
320
|
+
uint8_t* p = (uint8_t*)_mi_os_alloc(req_size,&memid,NULL);
|
|
321
|
+
#endif
|
|
322
|
+
|
|
323
|
+
p[0] = 1;
|
|
324
|
+
|
|
325
|
+
//_mi_os_protect(p, _mi_os_page_size());
|
|
326
|
+
//_mi_os_unprotect(p, _mi_os_page_size());
|
|
327
|
+
//_mi_os_decommit(p, _mi_os_page_size(), NULL);
|
|
328
|
+
if (madvise(p, req_size, MADV_HUGEPAGE) == 0) {
|
|
329
|
+
printf("advised huge pages\n");
|
|
330
|
+
_mi_os_decommit(p, _mi_os_page_size(), NULL);
|
|
331
|
+
};
|
|
332
|
+
_mi_os_free(p, req_size, memid, NULL);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
#endif
|
|
336
|
+
|
|
337
|
+
// ----------------------------
|
|
338
|
+
// bin size experiments
|
|
339
|
+
// ------------------------------
|
|
340
|
+
|
|
341
|
+
#if 0
|
|
342
|
+
#include <stdint.h>
|
|
343
|
+
#include <stdbool.h>
|
|
344
|
+
|
|
345
|
+
#define MI_INTPTR_SIZE 8
|
|
346
|
+
#define MI_LARGE_WSIZE_MAX (4*1024*1024 / MI_INTPTR_SIZE)
|
|
347
|
+
|
|
348
|
+
#define MI_BIN_HUGE 100
|
|
349
|
+
//#define MI_ALIGN2W
|
|
350
|
+
|
|
351
|
+
// Bit scan reverse: return the index of the highest bit.
|
|
352
|
+
static inline uint8_t mi_bsr32(uint32_t x);
|
|
353
|
+
|
|
354
|
+
#if defined(_MSC_VER)
|
|
355
|
+
//#include <Windows.h>
|
|
356
|
+
#include <intrin.h>
|
|
357
|
+
static inline uint8_t mi_bsr32(uint32_t x) {
|
|
358
|
+
uint32_t idx;
|
|
359
|
+
_BitScanReverse(&idx, x);
|
|
360
|
+
return idx;
|
|
361
|
+
}
|
|
362
|
+
#elif defined(__GNUC__) || defined(__clang__)
|
|
363
|
+
static inline uint8_t mi_bsr32(uint32_t x) {
|
|
364
|
+
return (31 - __builtin_clz(x));
|
|
365
|
+
}
|
|
366
|
+
#else
|
|
367
|
+
static inline uint8_t mi_bsr32(uint32_t x) {
|
|
368
|
+
// de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
|
|
369
|
+
static const uint8_t debruijn[32] = {
|
|
370
|
+
31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12,
|
|
371
|
+
30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13,
|
|
372
|
+
};
|
|
373
|
+
x |= x >> 1;
|
|
374
|
+
x |= x >> 2;
|
|
375
|
+
x |= x >> 4;
|
|
376
|
+
x |= x >> 8;
|
|
377
|
+
x |= x >> 16;
|
|
378
|
+
x++;
|
|
379
|
+
return debruijn[(x*0x076be629) >> 27];
|
|
380
|
+
}
|
|
381
|
+
#endif
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
// Bit scan reverse: return the index of the highest bit.
|
|
385
|
+
uint8_t _mi_bsr(uintptr_t x) {
|
|
386
|
+
if (x == 0) return 0;
|
|
387
|
+
#if MI_INTPTR_SIZE==8
|
|
388
|
+
uint32_t hi = (x >> 32);
|
|
389
|
+
return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi));
|
|
390
|
+
#elif MI_INTPTR_SIZE==4
|
|
391
|
+
return mi_bsr32(x);
|
|
392
|
+
#else
|
|
393
|
+
# error "define bsr for non-32 or 64-bit platforms"
|
|
394
|
+
#endif
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
static inline size_t _mi_wsize_from_size(size_t size) {
|
|
400
|
+
return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// #define MI_ALIGN2W
|
|
404
|
+
|
|
405
|
+
// Return the bin for a given field size.
|
|
406
|
+
// Returns MI_BIN_HUGE if the size is too large.
|
|
407
|
+
// We use `wsize` for the size in "machine word sizes",
|
|
408
|
+
// i.e. byte size == `wsize*sizeof(void*)`.
|
|
409
|
+
static inline size_t mi_bin(size_t wsize) {
|
|
410
|
+
// size_t wsize = _mi_wsize_from_size(size);
|
|
411
|
+
// size_t bin;
|
|
412
|
+
/*if (wsize <= 1) {
|
|
413
|
+
bin = 1;
|
|
414
|
+
}
|
|
415
|
+
*/
|
|
416
|
+
#if defined(MI_ALIGN4W)
|
|
417
|
+
if (wsize <= 4) {
|
|
418
|
+
return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes
|
|
419
|
+
}
|
|
420
|
+
#elif defined(MI_ALIGN2W)
|
|
421
|
+
if (wsize <= 8) {
|
|
422
|
+
return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes
|
|
423
|
+
}
|
|
424
|
+
#else
|
|
425
|
+
if (wsize <= 8) {
|
|
426
|
+
return (wsize == 0 ? 1 : wsize);
|
|
427
|
+
}
|
|
428
|
+
#endif
|
|
429
|
+
else if (wsize > MI_LARGE_WSIZE_MAX) {
|
|
430
|
+
return MI_BIN_HUGE;
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
#if defined(MI_ALIGN4W)
|
|
434
|
+
if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes
|
|
435
|
+
#endif
|
|
436
|
+
wsize--;
|
|
437
|
+
// find the highest bit
|
|
438
|
+
const size_t b = _mi_bsr(wsize); // note: wsize != 0
|
|
439
|
+
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
|
440
|
+
// - adjust with 3 because we use do not round the first 8 sizes
|
|
441
|
+
// which each get an exact bin
|
|
442
|
+
const size_t bin = ((b << 2) + ((wsize >> (b - 2)) & 0x03)) - 3;
|
|
443
|
+
assert(bin > 0 && bin < MI_BIN_HUGE);
|
|
444
|
+
return bin;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
static inline uint8_t _mi_bin4(size_t size) {
|
|
450
|
+
size_t wsize = _mi_wsize_from_size(size);
|
|
451
|
+
uint8_t bin;
|
|
452
|
+
if (wsize <= 1) {
|
|
453
|
+
bin = 1;
|
|
454
|
+
}
|
|
455
|
+
#if defined(MI_ALIGN4W)
|
|
456
|
+
else if (wsize <= 4) {
|
|
457
|
+
bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
|
|
458
|
+
}
|
|
459
|
+
#elif defined(MI_ALIGN2W)
|
|
460
|
+
else if (wsize <= 8) {
|
|
461
|
+
bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
|
|
462
|
+
}
|
|
463
|
+
#else
|
|
464
|
+
else if (wsize <= 8) {
|
|
465
|
+
bin = (uint8_t)wsize;
|
|
466
|
+
}
|
|
467
|
+
#endif
|
|
468
|
+
else if (wsize > MI_LARGE_WSIZE_MAX) {
|
|
469
|
+
bin = MI_BIN_HUGE;
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
uint8_t b = mi_bsr32((uint32_t)wsize);
|
|
473
|
+
bin = ((b << 1) + (uint8_t)((wsize >> (b - 1)) & 0x01)) + 3;
|
|
474
|
+
}
|
|
475
|
+
return bin;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
static size_t _mi_binx4(size_t wsize) {
|
|
479
|
+
size_t bin;
|
|
480
|
+
if (wsize <= 1) {
|
|
481
|
+
bin = 1;
|
|
482
|
+
}
|
|
483
|
+
else if (wsize <= 8) {
|
|
484
|
+
// bin = (wsize+1)&~1; // round to double word sizes
|
|
485
|
+
bin = (uint8_t)wsize;
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
uint8_t b = mi_bsr32((uint32_t)wsize);
|
|
489
|
+
if (b <= 1) return wsize;
|
|
490
|
+
bin = ((b << 1) | (wsize >> (b - 1))&0x01) + 3;
|
|
491
|
+
}
|
|
492
|
+
return bin;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
static size_t _mi_binx8(size_t bsize) {
|
|
496
|
+
if (bsize<=1) return bsize;
|
|
497
|
+
uint8_t b = mi_bsr32((uint32_t)bsize);
|
|
498
|
+
if (b <= 2) return bsize;
|
|
499
|
+
size_t bin = ((b << 2) | (bsize >> (b - 2))&0x03) - 5;
|
|
500
|
+
return bin;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
static inline size_t mi_binx(size_t wsize) {
|
|
505
|
+
uint8_t bin;
|
|
506
|
+
if (wsize <= 1) {
|
|
507
|
+
bin = 1;
|
|
508
|
+
}
|
|
509
|
+
else if (wsize <= 8) {
|
|
510
|
+
// bin = (wsize+1)&~1; // round to double word sizes
|
|
511
|
+
bin = (uint8_t)wsize;
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
wsize--;
|
|
515
|
+
// find the highest bit
|
|
516
|
+
uint8_t b = (uint8_t)mi_bsr32((uint32_t)wsize); // note: wsize != 0
|
|
517
|
+
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
|
518
|
+
// - adjust with 3 because we use do not round the first 8 sizes
|
|
519
|
+
// which each get an exact bin
|
|
520
|
+
bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3;
|
|
521
|
+
}
|
|
522
|
+
return bin;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
static void mi_bins(void) {
|
|
527
|
+
//printf(" QNULL(1), /* 0 */ \\\n ");
|
|
528
|
+
size_t last_bin = 0;
|
|
529
|
+
for (size_t wsize = 1; wsize <= (4*1024*1024) / 8 + 1024; wsize++) {
|
|
530
|
+
size_t bin = mi_bin(wsize);
|
|
531
|
+
if (bin != last_bin) {
|
|
532
|
+
//printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_wsize, last_wsize, last_bin);
|
|
533
|
+
printf("QNULL(%6zd), ", wsize-1);
|
|
534
|
+
if (last_bin%8 == 0) printf("/* %zu */ \\\n ", last_bin);
|
|
535
|
+
last_bin = bin;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
#endif
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#include <stdlib.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <assert.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
#include <mimalloc-override.h>
|
|
7
|
+
|
|
8
|
+
int main() {
|
|
9
|
+
mi_version(); // ensure mimalloc library is linked
|
|
10
|
+
void* p1 = malloc(78);
|
|
11
|
+
void* p2 = malloc(24);
|
|
12
|
+
free(p1);
|
|
13
|
+
p1 = malloc(8);
|
|
14
|
+
//char* s = strdup("hello\n");
|
|
15
|
+
free(p2);
|
|
16
|
+
p2 = malloc(16);
|
|
17
|
+
p1 = realloc(p1, 32);
|
|
18
|
+
free(p1);
|
|
19
|
+
free(p2);
|
|
20
|
+
//free(s);
|
|
21
|
+
//mi_collect(true);
|
|
22
|
+
|
|
23
|
+
/* now test if override worked by allocating/freeing across the api's*/
|
|
24
|
+
//p1 = mi_malloc(32);
|
|
25
|
+
//free(p1);
|
|
26
|
+
//p2 = malloc(32);
|
|
27
|
+
//mi_free(p2);
|
|
28
|
+
p1 = malloc(24);
|
|
29
|
+
p2 = reallocarray(p1, 16, 16);
|
|
30
|
+
free(p2);
|
|
31
|
+
p1 = malloc(24);
|
|
32
|
+
assert(reallocarr(&p1, 16, 16) == 0);
|
|
33
|
+
free(p1);
|
|
34
|
+
mi_stats_print(NULL);
|
|
35
|
+
return 0;
|
|
36
|
+
}
|