@shd101wyy/yo 0.1.24 → 0.1.25
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/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +30 -0
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +436 -2
- package/out/cjs/index.cjs +551 -553
- package/out/cjs/yo-cli.cjs +638 -632
- package/out/cjs/yo-lsp.cjs +595 -597
- package/out/esm/index.mjs +487 -489
- package/out/types/src/codegen/utils/index.d.ts +1 -0
- package/out/types/src/expr.d.ts +1 -0
- package/out/types/src/test-runner.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/vendor/mimalloc/.github/workflows/release.yaml +55 -0
- package/vendor/mimalloc/.github/workflows/stale.yaml +27 -0
- package/vendor/mimalloc/.github/workflows/test.yaml +163 -0
- package/vendor/mimalloc/CMakeLists.txt +52 -33
- package/vendor/mimalloc/azure-pipelines.yml +4 -3
- package/vendor/mimalloc/bin/bundle.bat +74 -0
- package/vendor/mimalloc/bin/bundle.sh +232 -0
- package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +2 -2
- package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +1 -1
- package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +2 -2
- package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +1 -1
- package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +1 -1
- package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +4 -3
- package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +1 -1
- package/vendor/mimalloc/doc/mimalloc-doc.h +42 -4
- package/vendor/mimalloc/doc/release-notes.md +15 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +3 -3
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj +511 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj.filters +117 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-dep.vcxproj +360 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-override-static.vcxproj +310 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc.sln +92 -35
- package/vendor/mimalloc/include/mimalloc/atomic.h +178 -182
- package/vendor/mimalloc/include/mimalloc/bits.h +8 -10
- package/vendor/mimalloc/include/mimalloc/internal.h +76 -32
- package/vendor/mimalloc/include/mimalloc/prim.h +25 -18
- package/vendor/mimalloc/include/mimalloc/track.h +7 -2
- package/vendor/mimalloc/include/mimalloc/types.h +57 -29
- package/vendor/mimalloc/include/mimalloc-override.h +10 -10
- package/vendor/mimalloc/include/mimalloc-stats.h +18 -6
- package/vendor/mimalloc/include/mimalloc.h +22 -12
- package/vendor/mimalloc/readme.md +42 -17
- package/vendor/mimalloc/src/alloc-aligned.c +13 -11
- package/vendor/mimalloc/src/alloc-override.c +97 -17
- package/vendor/mimalloc/src/alloc-posix.c +44 -27
- package/vendor/mimalloc/src/alloc.c +73 -23
- package/vendor/mimalloc/src/arena-meta.c +3 -3
- package/vendor/mimalloc/src/arena.c +380 -192
- package/vendor/mimalloc/src/bitmap.c +68 -18
- package/vendor/mimalloc/src/bitmap.h +8 -4
- package/vendor/mimalloc/src/free.c +83 -47
- package/vendor/mimalloc/src/heap.c +94 -40
- package/vendor/mimalloc/src/init.c +273 -102
- package/vendor/mimalloc/src/libc.c +53 -8
- package/vendor/mimalloc/src/options.c +43 -40
- package/vendor/mimalloc/src/os.c +110 -45
- package/vendor/mimalloc/src/page-map.c +14 -8
- package/vendor/mimalloc/src/page-queue.c +9 -6
- package/vendor/mimalloc/src/page.c +26 -16
- package/vendor/mimalloc/src/prim/emscripten/prim.c +10 -1
- package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +35 -16
- package/vendor/mimalloc/src/prim/unix/prim.c +26 -22
- package/vendor/mimalloc/src/prim/wasi/prim.c +7 -4
- package/vendor/mimalloc/src/prim/windows/prim.c +247 -44
- package/vendor/mimalloc/src/random.c +8 -3
- package/vendor/mimalloc/src/stats.c +59 -48
- package/vendor/mimalloc/src/theap.c +85 -44
- package/vendor/mimalloc/src/threadlocal.c +102 -41
- package/vendor/mimalloc/test/main-override-static.c +31 -2
- package/vendor/mimalloc/test/main-override.c +27 -14
- package/vendor/mimalloc/test/main-static-dep.cpp +46 -0
- package/vendor/mimalloc/test/main-static-dep.h +11 -0
- package/vendor/mimalloc/test/test-api-fill.c +2 -2
- package/vendor/mimalloc/test/test-stress.c +3 -3
- package/vendor/mimalloc/test/test-wrong.c +11 -7
|
@@ -11,6 +11,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
|
|
11
11
|
#include "mimalloc/internal.h"
|
|
12
12
|
#include "mimalloc/prim.h"
|
|
13
13
|
#include <stdio.h> // fputs, stderr
|
|
14
|
+
#include <stdlib.h> // atexit
|
|
14
15
|
|
|
15
16
|
// xbox has no console IO
|
|
16
17
|
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
|
|
@@ -86,15 +87,13 @@ typedef BOOL (__stdcall *PGetPhysicallyInstalledSystemMemory)( PULONGLONG TotalM
|
|
|
86
87
|
typedef BOOL (__stdcall* PGetVersionExW)(LPOSVERSIONINFOW lpVersionInformation);
|
|
87
88
|
|
|
88
89
|
|
|
90
|
+
|
|
89
91
|
//---------------------------------------------
|
|
90
92
|
// Enable large page support dynamically (if possible)
|
|
91
93
|
//---------------------------------------------
|
|
92
94
|
|
|
93
|
-
static bool
|
|
95
|
+
static bool win_enable_large_os_pages_once(size_t* large_page_size)
|
|
94
96
|
{
|
|
95
|
-
static bool large_initialized = false;
|
|
96
|
-
if (large_initialized) return (_mi_os_large_page_size() > 0);
|
|
97
|
-
large_initialized = true;
|
|
98
97
|
if (pGetLargePageMinimum==NULL) return false; // no large page support (xbox etc.)
|
|
99
98
|
|
|
100
99
|
// Try to see if large OS pages are supported
|
|
@@ -128,6 +127,13 @@ static bool win_enable_large_os_pages(size_t* large_page_size)
|
|
|
128
127
|
return (ok!=0);
|
|
129
128
|
}
|
|
130
129
|
|
|
130
|
+
static bool win_enable_large_os_pages(size_t* large_page_size) {
|
|
131
|
+
mi_atomic_do_once {
|
|
132
|
+
win_enable_large_os_pages_once(large_page_size);
|
|
133
|
+
}
|
|
134
|
+
return (_mi_os_large_page_size() > 0);
|
|
135
|
+
}
|
|
136
|
+
|
|
131
137
|
|
|
132
138
|
//---------------------------------------------
|
|
133
139
|
// Initialize
|
|
@@ -417,8 +423,8 @@ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int num
|
|
|
417
423
|
|
|
418
424
|
MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };
|
|
419
425
|
// on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages
|
|
420
|
-
static
|
|
421
|
-
if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) {
|
|
426
|
+
static _Atomic(size_t) mi_huge_pages_available = MI_ATOMIC_VAR_INIT(1);
|
|
427
|
+
if (pNtAllocateVirtualMemoryEx != NULL && mi_atomic_load_acquire(&mi_huge_pages_available) != 0) {
|
|
422
428
|
params[0].Type.Type = MiMemExtendedParameterAttributeFlags;
|
|
423
429
|
params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;
|
|
424
430
|
ULONG param_count = 1;
|
|
@@ -435,7 +441,7 @@ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int num
|
|
|
435
441
|
}
|
|
436
442
|
else {
|
|
437
443
|
// fall back to regular large pages
|
|
438
|
-
mi_huge_pages_available
|
|
444
|
+
mi_atomic_store_release(&mi_huge_pages_available,0); // don't try further huge pages
|
|
439
445
|
_mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err);
|
|
440
446
|
}
|
|
441
447
|
}
|
|
@@ -561,10 +567,11 @@ void _mi_prim_process_info(mi_process_info_t* pinfo)
|
|
|
561
567
|
pinfo->stime = filetime_msecs(&st);
|
|
562
568
|
|
|
563
569
|
// load psapi on demand
|
|
564
|
-
|
|
570
|
+
mi_atomic_do_once {
|
|
565
571
|
HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll"));
|
|
566
572
|
if (hDll != NULL) {
|
|
567
573
|
pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo");
|
|
574
|
+
// FreeLibrary(hDll); // don't free
|
|
568
575
|
}
|
|
569
576
|
}
|
|
570
577
|
|
|
@@ -630,7 +637,7 @@ void _mi_prim_out_stderr( const char* msg )
|
|
|
630
637
|
// Note: on windows, environment names are not case sensitive.
|
|
631
638
|
bool _mi_prim_getenv(const char* name, char* result, size_t result_size) {
|
|
632
639
|
result[0] = 0;
|
|
633
|
-
size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);
|
|
640
|
+
const size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);
|
|
634
641
|
return (len > 0 && len < result_size);
|
|
635
642
|
}
|
|
636
643
|
|
|
@@ -663,13 +670,16 @@ typedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG);
|
|
|
663
670
|
static PBCryptGenRandom pBCryptGenRandom = NULL;
|
|
664
671
|
|
|
665
672
|
bool _mi_prim_random_buf(void* buf, size_t buf_len) {
|
|
666
|
-
|
|
673
|
+
mi_assert(buf_len <= ULONG_MAX);
|
|
674
|
+
if (buf_len > ULONG_MAX) return false;
|
|
675
|
+
mi_atomic_do_once {
|
|
667
676
|
HINSTANCE hDll = LoadLibrary(TEXT("bcrypt.dll"));
|
|
668
677
|
if (hDll != NULL) {
|
|
669
678
|
pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, "BCryptGenRandom");
|
|
679
|
+
// FreeLibrary(hDll); // don't free
|
|
670
680
|
}
|
|
671
|
-
if (pBCryptGenRandom == NULL) return false;
|
|
672
681
|
}
|
|
682
|
+
if (pBCryptGenRandom == NULL) return false;
|
|
673
683
|
return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
|
|
674
684
|
}
|
|
675
685
|
|
|
@@ -693,47 +703,22 @@ bool _mi_prim_thread_is_in_threadpool(void) {
|
|
|
693
703
|
return false;
|
|
694
704
|
}
|
|
695
705
|
|
|
706
|
+
void _mi_prim_thread_yield(void) {
|
|
707
|
+
SwitchToThread();
|
|
708
|
+
}
|
|
696
709
|
|
|
697
710
|
//----------------------------------------------------------------
|
|
698
711
|
// Process & Thread Init/Done
|
|
699
712
|
//----------------------------------------------------------------
|
|
700
713
|
|
|
701
|
-
#if MI_WIN_USE_FIXED_TLS==1
|
|
702
|
-
mi_decl_cache_align size_t _mi_win_tls_offset = 0;
|
|
703
|
-
#endif
|
|
704
|
-
|
|
705
714
|
//static void mi_debug_out(const char* s) {
|
|
706
715
|
// HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
|
|
707
716
|
// WriteConsole(h, s, (DWORD)_mi_strlen(s), NULL, NULL);
|
|
708
717
|
//}
|
|
709
718
|
|
|
710
|
-
static void mi_win_tls_init(DWORD reason) {
|
|
711
|
-
if (reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) {
|
|
712
|
-
#if MI_WIN_USE_FIXED_TLS==1 // we must allocate a TLS slot dynamically
|
|
713
|
-
if (_mi_win_tls_offset == 0 && reason == DLL_PROCESS_ATTACH) {
|
|
714
|
-
const DWORD tls_slot = TlsAlloc(); // usually returns slot 1
|
|
715
|
-
if (tls_slot == TLS_OUT_OF_INDEXES) {
|
|
716
|
-
_mi_error_message(EFAULT, "unable to allocate the a TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\n");
|
|
717
|
-
}
|
|
718
|
-
_mi_win_tls_offset = (size_t)tls_slot * sizeof(void*);
|
|
719
|
-
}
|
|
720
|
-
#endif
|
|
721
|
-
#if MI_HAS_TLS_SLOT >= 2 // we must initialize the TLS slot before any allocation
|
|
722
|
-
if (_mi_theap_default() == NULL) {
|
|
723
|
-
_mi_theap_default_set((mi_theap_t*)&_mi_theap_empty);
|
|
724
|
-
#if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1
|
|
725
|
-
void* const p = TlsGetValue((DWORD)(_mi_win_tls_offset / sizeof(void*)));
|
|
726
|
-
mi_assert_internal(p == (void*)&_mi_theap_empty);
|
|
727
|
-
#endif
|
|
728
|
-
}
|
|
729
|
-
#endif
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
|
|
733
719
|
static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
734
720
|
MI_UNUSED(reserved);
|
|
735
721
|
MI_UNUSED(module);
|
|
736
|
-
mi_win_tls_init(reason);
|
|
737
722
|
if (reason==DLL_PROCESS_ATTACH) {
|
|
738
723
|
_mi_auto_process_init();
|
|
739
724
|
}
|
|
@@ -746,7 +731,223 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
746
731
|
}
|
|
747
732
|
|
|
748
733
|
|
|
749
|
-
|
|
734
|
+
/* -----------------------------------------------------------------------
|
|
735
|
+
Auto initialize and finalize mimalloc on process and thread start/end.
|
|
736
|
+
By default we use a combination of CRT init and TLS sections for
|
|
737
|
+
both static and dynamic linkage (`MI_WIN_INIT_USE_CRT_TLS`).
|
|
738
|
+
------------------------------------------------------------------------- */
|
|
739
|
+
#if !defined(MI_WIN_INIT_USE_CRT_TLS) && !defined(MI_WIN_INIT_USE_RAW_DLLMAIN) && !defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && !defined(MI_WIN_INIT_USE_FLS)
|
|
740
|
+
#if !defined(__INTEL_LLVM_COMPILER) && !defined(__INTEL_COMPILER)
|
|
741
|
+
#define MI_WIN_INIT_USE_CRT_TLS 1
|
|
742
|
+
#else
|
|
743
|
+
#define MI_WIN_INIT_USE_TLS_DLLMAIN 1 /* default for Intel ICX, see issue #1268 */
|
|
744
|
+
#endif
|
|
745
|
+
#endif
|
|
746
|
+
|
|
747
|
+
#if defined(MI_WIN_INIT_USE_CRT_TLS)
|
|
748
|
+
#define MI_PRIM_HAS_PROCESS_ATTACH 1
|
|
749
|
+
// nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.
|
|
750
|
+
void _mi_prim_thread_init_auto_done(void) {}
|
|
751
|
+
void _mi_prim_thread_done_auto_done(void) {}
|
|
752
|
+
void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {
|
|
753
|
+
MI_UNUSED(theap);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
static bool mi_module_is_dll(PVOID mod) {
|
|
757
|
+
if (mod==NULL) return false;
|
|
758
|
+
PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;
|
|
759
|
+
PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);
|
|
760
|
+
return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
static bool mi_current_module_is_dll(void) {
|
|
764
|
+
HMODULE mod = NULL;
|
|
765
|
+
const BOOL ok = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)mi_current_module_is_dll, &mod);
|
|
766
|
+
return (ok && mi_module_is_dll(mod));
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// Hook into CRT initialization and finalization.
|
|
770
|
+
static void mi_cdecl mi_crt_done(void) {
|
|
771
|
+
// mi_debug_out(mi_current_module_is_dll() ? "crt dll done\n" : "crt exe done\n");
|
|
772
|
+
mi_win_main(NULL, DLL_PROCESS_DETACH, 0);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
static int mi_cdecl mi_crt_init(void) {
|
|
776
|
+
// mi_debug_out(mi_current_module_is_dll() ? "crt dll init\n" : "crt exe init\n");
|
|
777
|
+
if (mi_current_module_is_dll()) {
|
|
778
|
+
// in a dll, atexit (crt_done) is called after tls process detach
|
|
779
|
+
atexit(&mi_crt_done);
|
|
780
|
+
}
|
|
781
|
+
return 0;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// We also hook into the Windows loader TLS initialization and finalization.
|
|
785
|
+
static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {
|
|
786
|
+
if (reason == DLL_THREAD_ATTACH) {
|
|
787
|
+
//mi_debug_out("tls thread attach\n");
|
|
788
|
+
mi_win_main(module, reason, reserved);
|
|
789
|
+
}
|
|
790
|
+
else if (reason == DLL_PROCESS_ATTACH) {
|
|
791
|
+
// mi_debug_out(mi_module_is_dll(module) ? "tls dll process attach\n" : "tls exe process attach\n");
|
|
792
|
+
// tls process attach is always called before crt init
|
|
793
|
+
mi_win_main(module, reason, reserved);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {
|
|
798
|
+
if (reason == DLL_THREAD_DETACH) {
|
|
799
|
+
//mi_debug_out("tls thread detach\n");
|
|
800
|
+
mi_win_main(module, reason, reserved);
|
|
801
|
+
}
|
|
802
|
+
else if (reason == DLL_PROCESS_DETACH) {
|
|
803
|
+
// mi_debug_out(mi_module_is_dll(module) ? "tls dll process detach\n" : "tls exe process detach\n");
|
|
804
|
+
if (!mi_module_is_dll(module)) {
|
|
805
|
+
// in an exe, tls process detach is called after atexit (mi_crt_done)
|
|
806
|
+
mi_win_main(module, reason, reserved);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// Set up TLS callbacks in a statically linked library by using special data sections.
|
|
812
|
+
// See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>
|
|
813
|
+
// We use 2 entries to ensure we call attach events before constructors
|
|
814
|
+
// are called, and detach events after destructors are called.
|
|
815
|
+
// We also set up a CRT initialization callback.
|
|
816
|
+
#if defined(__cplusplus)
|
|
817
|
+
extern "C" {
|
|
818
|
+
#endif
|
|
819
|
+
|
|
820
|
+
typedef int (mi_cdecl* mi_crt_callback_t)(void);
|
|
821
|
+
#if defined(_WIN64)
|
|
822
|
+
#pragma comment(linker, "/INCLUDE:_tls_used")
|
|
823
|
+
#pragma comment(linker, "/INCLUDE:_mi_tls_callback_pre")
|
|
824
|
+
#pragma comment(linker, "/INCLUDE:_mi_tls_callback_post")
|
|
825
|
+
#pragma const_seg(".CRT$XLB")
|
|
826
|
+
extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];
|
|
827
|
+
const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
|
|
828
|
+
#pragma const_seg()
|
|
829
|
+
#pragma const_seg(".CRT$XLY")
|
|
830
|
+
extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];
|
|
831
|
+
const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
|
|
832
|
+
#pragma const_seg()
|
|
833
|
+
#pragma const_seg(".CRT$XIB")
|
|
834
|
+
extern const mi_crt_callback_t _mi_crt_callback_init[];
|
|
835
|
+
const mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };
|
|
836
|
+
#pragma const_seg()
|
|
837
|
+
#else
|
|
838
|
+
#pragma comment(linker, "/INCLUDE:__tls_used")
|
|
839
|
+
#pragma comment(linker, "/INCLUDE:__mi_tls_callback_pre")
|
|
840
|
+
#pragma comment(linker, "/INCLUDE:__mi_tls_callback_post")
|
|
841
|
+
#pragma data_seg(".CRT$XLB")
|
|
842
|
+
PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
|
|
843
|
+
#pragma data_seg()
|
|
844
|
+
#pragma data_seg(".CRT$XLY")
|
|
845
|
+
PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
|
|
846
|
+
#pragma data_seg()
|
|
847
|
+
#pragma data_seg(".CRT$XIB")
|
|
848
|
+
mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };
|
|
849
|
+
#pragma data_seg()
|
|
850
|
+
#endif
|
|
851
|
+
|
|
852
|
+
#if defined(__cplusplus)
|
|
853
|
+
}
|
|
854
|
+
#endif
|
|
855
|
+
|
|
856
|
+
/* ----------------------------------------------------------------
|
|
857
|
+
Here we use a combination of the raw DLL main and TLS sections for
|
|
858
|
+
both static and dynamic linkage. This is perhaps the most robust as
|
|
859
|
+
the raw DLL main ensure we can close mimalloc latest possible.
|
|
860
|
+
However, it can lead to link errors with on `_pRawDllMain` if other
|
|
861
|
+
libraries also try to hook into this (like Boost).
|
|
862
|
+
*/
|
|
863
|
+
#elif defined(MI_WIN_INIT_USE_RAW_DLLMAIN)
|
|
864
|
+
#define MI_PRIM_HAS_PROCESS_ATTACH 1
|
|
865
|
+
// nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.
|
|
866
|
+
void _mi_prim_thread_init_auto_done(void) {}
|
|
867
|
+
void _mi_prim_thread_done_auto_done(void) {}
|
|
868
|
+
void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {
|
|
869
|
+
MI_UNUSED(theap);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// If linked into a DLL module, this raw entry is called before the CRT attach and
|
|
873
|
+
// after the CRT detach through the CRT _pRawDllMain pointer.
|
|
874
|
+
static BOOL NTAPI mi_dll_main_raw(PVOID module, DWORD reason, LPVOID reserved) {
|
|
875
|
+
mi_win_main(module, reason, reserved);
|
|
876
|
+
return TRUE;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// Set the value of the CRT _pRawDllMain pointer
|
|
880
|
+
#if defined(__cplusplus)
|
|
881
|
+
extern "C"
|
|
882
|
+
#endif
|
|
883
|
+
PVOID _pRawDllMain = (PVOID)&mi_dll_main_raw;
|
|
884
|
+
|
|
885
|
+
// We also hook into the Windows loader TLS initialization and finalization.
|
|
886
|
+
// If we are linked into an EXE module we rely on these as `mi_dll_main_raw`
|
|
887
|
+
// is not called (and otherwise we ignore the TLS callbacks by checking if we are in a DLL).
|
|
888
|
+
static bool mi_module_is_dll(PVOID mod) {
|
|
889
|
+
if (mod==NULL) return false;
|
|
890
|
+
PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;
|
|
891
|
+
PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);
|
|
892
|
+
return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {
|
|
896
|
+
if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {
|
|
897
|
+
if (!mi_module_is_dll(module)) {
|
|
898
|
+
mi_win_main(module, reason, reserved);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {
|
|
904
|
+
if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {
|
|
905
|
+
if (!mi_module_is_dll(module)) {
|
|
906
|
+
mi_win_main(module, reason, reserved);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// Set up TLS callbacks in a statically linked library by using special data sections.
|
|
912
|
+
// See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>
|
|
913
|
+
// We use 2 entries to ensure we call attach events before constructors
|
|
914
|
+
// are called, and detach events after destructors are called.
|
|
915
|
+
#if defined(__cplusplus)
|
|
916
|
+
extern "C" {
|
|
917
|
+
#endif
|
|
918
|
+
|
|
919
|
+
#if defined(_WIN64)
|
|
920
|
+
#pragma comment(linker, "/INCLUDE:_tls_used")
|
|
921
|
+
#pragma comment(linker, "/INCLUDE:_mi_tls_callback_pre")
|
|
922
|
+
#pragma comment(linker, "/INCLUDE:_mi_tls_callback_post")
|
|
923
|
+
#pragma const_seg(".CRT$XLB")
|
|
924
|
+
extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];
|
|
925
|
+
const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
|
|
926
|
+
#pragma const_seg()
|
|
927
|
+
#pragma const_seg(".CRT$XLY")
|
|
928
|
+
extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];
|
|
929
|
+
const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
|
|
930
|
+
#pragma const_seg()
|
|
931
|
+
#else
|
|
932
|
+
#pragma comment(linker, "/INCLUDE:__tls_used")
|
|
933
|
+
#pragma comment(linker, "/INCLUDE:__mi_tls_callback_pre")
|
|
934
|
+
#pragma comment(linker, "/INCLUDE:__mi_tls_callback_post")
|
|
935
|
+
#pragma data_seg(".CRT$XLB")
|
|
936
|
+
PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
|
|
937
|
+
#pragma data_seg()
|
|
938
|
+
#pragma data_seg(".CRT$XLY")
|
|
939
|
+
PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
|
|
940
|
+
#pragma data_seg()
|
|
941
|
+
#endif
|
|
942
|
+
|
|
943
|
+
#if defined(__cplusplus)
|
|
944
|
+
}
|
|
945
|
+
#endif
|
|
946
|
+
|
|
947
|
+
/* --------------------------------------------------------------------
|
|
948
|
+
Legacy options: DllMain, TLS, and FLS
|
|
949
|
+
--------------------------------------------------------------------*/
|
|
950
|
+
#elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && defined(MI_SHARED_LIB)
|
|
750
951
|
#define MI_PRIM_HAS_PROCESS_ATTACH 1
|
|
751
952
|
|
|
752
953
|
// Windows DLL: easy to hook into process_init and thread_done
|
|
@@ -762,7 +963,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
762
963
|
MI_UNUSED(theap);
|
|
763
964
|
}
|
|
764
965
|
|
|
765
|
-
#elif
|
|
966
|
+
#elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN)
|
|
766
967
|
#define MI_PRIM_HAS_PROCESS_ATTACH 1
|
|
767
968
|
|
|
768
969
|
static void NTAPI mi_win_main_attach(PVOID module, DWORD reason, LPVOID reserved) {
|
|
@@ -803,7 +1004,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
803
1004
|
#pragma data_seg(".CRT$XLB")
|
|
804
1005
|
PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };
|
|
805
1006
|
#pragma data_seg()
|
|
806
|
-
#pragma data_seg(".CRT$
|
|
1007
|
+
#pragma data_seg(".CRT$XIY")
|
|
807
1008
|
PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };
|
|
808
1009
|
#pragma data_seg()
|
|
809
1010
|
#endif
|
|
@@ -819,7 +1020,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
819
1020
|
MI_UNUSED(theap);
|
|
820
1021
|
}
|
|
821
1022
|
|
|
822
|
-
#
|
|
1023
|
+
#elif defined(MI_WIN_INIT_USE_FLS) // deprecated: statically linked, use fiber api
|
|
823
1024
|
|
|
824
1025
|
#if defined(_MSC_VER) // on clang/gcc use the constructor attribute (in `src/prim/prim.c`)
|
|
825
1026
|
// MSVC: use data section magic for static libraries
|
|
@@ -876,6 +1077,8 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
876
1077
|
mi_assert_internal(mi_fls_key != (DWORD)(-1));
|
|
877
1078
|
FlsSetValue(mi_fls_key, theap);
|
|
878
1079
|
}
|
|
1080
|
+
#else
|
|
1081
|
+
#error "define windows process and thread auto initialization"
|
|
879
1082
|
#endif
|
|
880
1083
|
|
|
881
1084
|
// ----------------------------------------------------
|
|
@@ -895,7 +1098,6 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
895
1098
|
#endif
|
|
896
1099
|
mi_decl_export void _mi_redirect_entry(DWORD reason) {
|
|
897
1100
|
// called on redirection; careful as this may be called before DllMain
|
|
898
|
-
mi_win_tls_init(reason);
|
|
899
1101
|
if (reason == DLL_PROCESS_ATTACH) {
|
|
900
1102
|
mi_redirected = true;
|
|
901
1103
|
}
|
|
@@ -903,6 +1105,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
|
|
|
903
1105
|
mi_redirected = false;
|
|
904
1106
|
}
|
|
905
1107
|
else if (reason == DLL_THREAD_DETACH) {
|
|
1108
|
+
// mi_debug_out("redirect thread detach\n");
|
|
906
1109
|
_mi_thread_done(NULL);
|
|
907
1110
|
}
|
|
908
1111
|
}
|
|
@@ -94,7 +94,8 @@ static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t no
|
|
|
94
94
|
// since we only use chacha for randomness (and not encryption) we
|
|
95
95
|
// do not _need_ to read 32-bit values as little endian but we do anyways
|
|
96
96
|
// just for being compatible :-)
|
|
97
|
-
|
|
97
|
+
ctx->output_available = 0;
|
|
98
|
+
_mi_memzero(ctx->output,sizeof(ctx->output));
|
|
98
99
|
for (size_t i = 0; i < 4; i++) {
|
|
99
100
|
const uint8_t* sigma = (uint8_t*)"expand 32-byte k";
|
|
100
101
|
ctx->input[i] = read32(sigma,i);
|
|
@@ -110,6 +111,7 @@ static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t no
|
|
|
110
111
|
|
|
111
112
|
static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) {
|
|
112
113
|
_mi_memzero(ctx_new, sizeof(*ctx_new));
|
|
114
|
+
ctx_new->weak = ctx->weak;
|
|
113
115
|
_mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input));
|
|
114
116
|
ctx_new->input[12] = 0;
|
|
115
117
|
ctx_new->input[13] = 0;
|
|
@@ -178,9 +180,12 @@ static void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) {
|
|
|
178
180
|
if (!use_weak) { _mi_warning_message("unable to use secure randomness\n"); }
|
|
179
181
|
#endif
|
|
180
182
|
uintptr_t x = _mi_os_random_weak(0);
|
|
181
|
-
for (size_t i = 0; i <
|
|
183
|
+
for (size_t i = 0; i < 32; i+=4, x++) {
|
|
182
184
|
x = _mi_random_shuffle(x);
|
|
183
|
-
|
|
185
|
+
key[i] = (uint8_t)(x);
|
|
186
|
+
key[i+1] = (uint8_t)(x>>8);
|
|
187
|
+
key[i+2] = (uint8_t)(x>>16);
|
|
188
|
+
key[i+3] = (uint8_t)(x>>24);
|
|
184
189
|
}
|
|
185
190
|
ctx->weak = true;
|
|
186
191
|
}
|