@shd101wyy/yo 0.1.23 → 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.
Files changed (88) hide show
  1. package/.github/skills/yo-async-effects/async-effects-recipes.md +74 -1
  2. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +115 -0
  3. package/.github/skills/yo-syntax/syntax-cheatsheet.md +626 -6
  4. package/out/cjs/index.cjs +563 -564
  5. package/out/cjs/yo-cli.cjs +722 -715
  6. package/out/cjs/yo-lsp.cjs +601 -602
  7. package/out/esm/index.mjs +506 -507
  8. package/out/types/src/codegen/utils/index.d.ts +1 -0
  9. package/out/types/src/expr.d.ts +1 -0
  10. package/out/types/src/parser.d.ts +1 -0
  11. package/out/types/src/test-runner.d.ts +1 -0
  12. package/out/types/tsconfig.tsbuildinfo +1 -1
  13. package/package.json +1 -1
  14. package/std/build.yo +2 -2
  15. package/std/collections/array_list.yo +26 -0
  16. package/std/imm/map.yo +15 -15
  17. package/std/imm/sorted_map.yo +14 -14
  18. package/std/imm/string.yo +4 -4
  19. package/std/prelude.yo +18 -23
  20. package/std/process/command.yo +8 -8
  21. package/std/string/string.yo +76 -55
  22. package/std/string/unicode.yo +6 -6
  23. package/std/sys/signal.yo +6 -6
  24. package/vendor/mimalloc/.github/workflows/release.yaml +55 -0
  25. package/vendor/mimalloc/.github/workflows/stale.yaml +27 -0
  26. package/vendor/mimalloc/.github/workflows/test.yaml +163 -0
  27. package/vendor/mimalloc/CMakeLists.txt +52 -33
  28. package/vendor/mimalloc/azure-pipelines.yml +4 -3
  29. package/vendor/mimalloc/bin/bundle.bat +74 -0
  30. package/vendor/mimalloc/bin/bundle.sh +232 -0
  31. package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +2 -2
  32. package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +1 -1
  33. package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +2 -2
  34. package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +1 -1
  35. package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +1 -1
  36. package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +4 -3
  37. package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +1 -1
  38. package/vendor/mimalloc/doc/mimalloc-doc.h +42 -4
  39. package/vendor/mimalloc/doc/release-notes.md +15 -0
  40. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +3 -3
  41. package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj +511 -0
  42. package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj.filters +117 -0
  43. package/vendor/mimalloc/ide/vs2022/mimalloc-test-dep.vcxproj +360 -0
  44. package/vendor/mimalloc/ide/vs2022/mimalloc-test-override-static.vcxproj +310 -0
  45. package/vendor/mimalloc/ide/vs2022/mimalloc.sln +92 -35
  46. package/vendor/mimalloc/include/mimalloc/atomic.h +178 -182
  47. package/vendor/mimalloc/include/mimalloc/bits.h +8 -10
  48. package/vendor/mimalloc/include/mimalloc/internal.h +76 -32
  49. package/vendor/mimalloc/include/mimalloc/prim.h +25 -18
  50. package/vendor/mimalloc/include/mimalloc/track.h +7 -2
  51. package/vendor/mimalloc/include/mimalloc/types.h +57 -29
  52. package/vendor/mimalloc/include/mimalloc-override.h +10 -10
  53. package/vendor/mimalloc/include/mimalloc-stats.h +18 -6
  54. package/vendor/mimalloc/include/mimalloc.h +22 -12
  55. package/vendor/mimalloc/readme.md +42 -17
  56. package/vendor/mimalloc/src/alloc-aligned.c +13 -11
  57. package/vendor/mimalloc/src/alloc-override.c +97 -17
  58. package/vendor/mimalloc/src/alloc-posix.c +44 -27
  59. package/vendor/mimalloc/src/alloc.c +73 -23
  60. package/vendor/mimalloc/src/arena-meta.c +3 -3
  61. package/vendor/mimalloc/src/arena.c +380 -192
  62. package/vendor/mimalloc/src/bitmap.c +68 -18
  63. package/vendor/mimalloc/src/bitmap.h +8 -4
  64. package/vendor/mimalloc/src/free.c +83 -47
  65. package/vendor/mimalloc/src/heap.c +94 -40
  66. package/vendor/mimalloc/src/init.c +273 -102
  67. package/vendor/mimalloc/src/libc.c +53 -8
  68. package/vendor/mimalloc/src/options.c +43 -40
  69. package/vendor/mimalloc/src/os.c +110 -45
  70. package/vendor/mimalloc/src/page-map.c +14 -8
  71. package/vendor/mimalloc/src/page-queue.c +9 -6
  72. package/vendor/mimalloc/src/page.c +26 -16
  73. package/vendor/mimalloc/src/prim/emscripten/prim.c +10 -1
  74. package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +35 -16
  75. package/vendor/mimalloc/src/prim/unix/prim.c +26 -22
  76. package/vendor/mimalloc/src/prim/wasi/prim.c +7 -4
  77. package/vendor/mimalloc/src/prim/windows/prim.c +247 -44
  78. package/vendor/mimalloc/src/random.c +8 -3
  79. package/vendor/mimalloc/src/stats.c +59 -48
  80. package/vendor/mimalloc/src/theap.c +85 -44
  81. package/vendor/mimalloc/src/threadlocal.c +102 -41
  82. package/vendor/mimalloc/test/main-override-static.c +31 -2
  83. package/vendor/mimalloc/test/main-override.c +27 -14
  84. package/vendor/mimalloc/test/main-static-dep.cpp +46 -0
  85. package/vendor/mimalloc/test/main-static-dep.h +11 -0
  86. package/vendor/mimalloc/test/test-api-fill.c +2 -2
  87. package/vendor/mimalloc/test/test-stress.c +3 -3
  88. package/vendor/mimalloc/test/test-wrong.c +11 -7
@@ -33,46 +33,42 @@ void mi_heap_stats_merge_to_main(mi_heap_t* heap) {
33
33
  _mi_stats_merge_into(&mi_heap_main()->stats, &heap->stats);
34
34
  }
35
35
 
36
- static mi_theap_t* mi_heap_init_theap(const mi_heap_t* const_heap)
36
+ static mi_decl_noinline mi_theap_t* mi_heap_init_theap(const mi_heap_t* const_heap)
37
37
  {
38
38
  mi_heap_t* heap = (mi_heap_t*)const_heap;
39
39
  mi_assert_internal(heap!=NULL);
40
40
 
41
41
  if (_mi_is_heap_main(heap)) {
42
42
  // this can be called if the (main) thread is not yet initialized (as no allocation happened)
43
- mi_thread_init();
44
- mi_theap_t* theap = _mi_heap_theap(heap);
45
- mi_assert_internal(theap!=NULL);
43
+ // but `theap_main_init_get()` will call `mi_thread_init()`
44
+ mi_theap_t* const theap = _mi_theap_main_safe();
45
+ mi_assert_internal(theap!=NULL && _mi_is_heap_main(_mi_theap_heap(theap)));
46
46
  return theap;
47
47
  }
48
48
 
49
49
  // otherwise initialize the theap for this heap
50
50
  // get the thread local
51
- mi_theap_t* theap = NULL;
52
- if (heap->theap==0) {
53
- // initialize thread locals
54
- heap->theap = _mi_thread_local_create();
55
- if (heap->theap==0) {
56
- _mi_error_message(EFAULT, "unable to dynamically create a thread local for a heap\n");
57
- return NULL;
58
- }
59
- }
60
- else {
61
- // get current thread local
62
- theap = (mi_theap_t*)_mi_thread_local_get(heap->theap);
51
+ mi_assert_internal(heap->theap != 0);
52
+ if (heap->theap==0) { // paranoia
53
+ _mi_error_message(EFAULT, "no thread-local reserved for heap (%p)\n", heap);
54
+ return NULL;
63
55
  }
56
+ mi_theap_t* theap = (mi_theap_t*)_mi_thread_local_get(heap->theap);
64
57
 
65
58
  // create a fresh theap?
66
59
  if (theap==NULL) {
60
+ // set first an invalid value to ensure the thread local storage is allocated
61
+ if (!_mi_thread_local_set(heap->theap, (mi_theap_t*)1)) {
62
+ _mi_error_message(EFAULT, "unable to allocate memory for thread local storage\n");
63
+ return NULL;
64
+ }
65
+ // then allocate the theap
67
66
  theap = _mi_theap_create(heap, _mi_theap_default_safe()->tld);
67
+ _mi_thread_local_set(heap->theap, theap); // Cannot fail now as it was set before. Always set so the local is valid or NULL (and not 1)
68
68
  if (theap==NULL) {
69
69
  _mi_error_message(EFAULT, "unable to allocate memory for a thread local heap\n");
70
70
  return NULL;
71
- }
72
- if (!_mi_thread_local_set(heap->theap, theap)) {
73
- _mi_error_message(EFAULT, "unable to allocate memory for a thread local storage\n");
74
- return NULL;
75
- }
71
+ }
76
72
  }
77
73
  return theap;
78
74
  }
@@ -81,7 +77,7 @@ static mi_theap_t* mi_heap_init_theap(const mi_heap_t* const_heap)
81
77
  // get the theap for a heap without initializing (and return NULL in that case)
82
78
  mi_theap_t* _mi_heap_theap_get_peek(const mi_heap_t* heap) {
83
79
  if (heap==NULL || _mi_is_heap_main(heap)) {
84
- return __mi_theap_main; // don't call _mi_theap_main as it may still be NULL
80
+ return _mi_theap_main_safe();
85
81
  }
86
82
  else {
87
83
  return (mi_theap_t*)_mi_thread_local_get(heap->theap);
@@ -103,17 +99,26 @@ mi_theap_t* _mi_heap_theap_get_or_init(const mi_heap_t* heap)
103
99
 
104
100
  mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t exclusive_arena_id) {
105
101
  // always allocate heap data in the (subprocess) main heap
106
- mi_heap_t* heap_main = mi_heap_main();
102
+ mi_heap_t* const heap_main = mi_heap_main();
107
103
  // todo: allocate heap data in the exclusive arena ?
108
- mi_heap_t* heap = (mi_heap_t*)mi_heap_zalloc( heap_main, sizeof(mi_heap_t) );
104
+ mi_heap_t* const heap = (mi_heap_t*)mi_heap_zalloc( heap_main, sizeof(mi_heap_t) );
109
105
  if (heap==NULL) return NULL;
110
106
 
107
+ // reserve a thread local slot for this heap (see also issue #1230)
108
+ const mi_thread_local_t theap_slot = _mi_thread_local_create();
109
+ if (theap_slot == 0) {
110
+ _mi_error_message(EFAULT, "unable to dynamically create a thread local for a heap\n");
111
+ mi_free(heap);
112
+ return NULL;
113
+ }
114
+
111
115
  // init fields
116
+ heap->theap = theap_slot;
112
117
  heap->subproc = heap_main->subproc;
113
118
  heap->heap_seq = mi_atomic_increment_relaxed(&heap_main->subproc->heap_total_count);
114
119
  heap->exclusive_arena = _mi_arena_from_id(exclusive_arena_id);
115
120
  heap->numa_node = -1; // no initial affinity
116
-
121
+ mi_stats_header_init(&heap->stats);
117
122
  mi_lock_init(&heap->theaps_lock);
118
123
  mi_lock_init(&heap->os_abandoned_pages_lock);
119
124
  mi_lock_init(&heap->arena_pages_lock);
@@ -135,22 +140,41 @@ mi_heap_t* mi_heap_new(void) {
135
140
  return mi_heap_new_in_arena(0);
136
141
  }
137
142
 
138
- // free the heap resources (assuming the pages are already moved/destroyed)
143
+ // free all theaps belonging to this heap (without deleting their pages as we do this arena wise for efficiency)
144
+ static void mi_heap_free_theaps(mi_heap_t* heap) {
145
+ // This can run concurrently with a thread that terminates (see `init.c:mi_thread_theaps_done`),
146
+ // and we need to ensure we free theaps atomically.
147
+ // We do this in a loop where we release the theaps_lock at every potential re-iteration to unblock
148
+ // potential concurrent thread termination which tries to remove the theap from our theaps list.
149
+ bool all_freed;
150
+ do {
151
+ all_freed = true;
152
+ mi_theap_t* theap = NULL;
153
+ mi_lock(&heap->theaps_lock) {
154
+ theap = heap->theaps;
155
+ while(theap != NULL) {
156
+ mi_theap_t* next = theap->hnext;
157
+ if (!_mi_theap_free(theap, false /* dont re-acquire the heap->theaps_lock */, true /* acquire the tld->theaps_lock though */ )) {
158
+ all_freed = false;
159
+ }
160
+ theap = next;
161
+ }
162
+ }
163
+ if (!all_freed) {
164
+ mi_heap_stat_counter_increase(heap,heaps_delete_wait,1);
165
+ _mi_prim_thread_yield();
166
+ }
167
+ else {
168
+ mi_assert_internal(heap->theaps==NULL);
169
+ }
170
+ }
171
+ while(!all_freed);
172
+ }
173
+
174
+ // free the heap resources (assuming the pages are already moved/destroyed, and all theaps have been freed)
139
175
  static void mi_heap_free(mi_heap_t* heap) {
140
176
  mi_assert_internal(heap!=NULL && !_mi_is_heap_main(heap));
141
177
 
142
- // free all theaps belonging to this heap
143
- mi_theap_t* theap = NULL;
144
- mi_lock(&heap->theaps_lock) { theap = heap->theaps; }
145
- while(theap != NULL) {
146
- mi_theap_t* next = NULL;
147
- mi_lock(&heap->theaps_lock) { next = theap->hnext; }
148
- _mi_theap_free(theap);
149
- theap = next;
150
- }
151
- mi_lock(&heap->theaps_lock) { theap = heap->theaps; }
152
- mi_assert_internal(theap==NULL);
153
-
154
178
  // free all arena pages infos
155
179
  mi_lock(&heap->arena_pages_lock) {
156
180
  for (size_t i = 0; i < MI_MAX_ARENAS; i++) {
@@ -175,6 +199,7 @@ static void mi_heap_free(mi_heap_t* heap) {
175
199
  _mi_thread_local_free(heap->theap);
176
200
  mi_lock_done(&heap->theaps_lock);
177
201
  mi_lock_done(&heap->os_abandoned_pages_lock);
202
+ mi_lock_done(&heap->arena_pages_lock);
178
203
  mi_free(heap);
179
204
  }
180
205
 
@@ -184,18 +209,25 @@ void mi_heap_delete(mi_heap_t* heap) {
184
209
  _mi_warning_message("cannot delete the main heap\n");
185
210
  return;
186
211
  }
212
+ mi_heap_free_theaps(heap);
187
213
  _mi_heap_move_pages(heap, mi_heap_main());
188
214
  mi_heap_free(heap);
189
215
  }
190
216
 
217
+ void _mi_heap_force_destroy(mi_heap_t* heap) {
218
+ if (heap==NULL) return;
219
+ mi_heap_free_theaps(heap);
220
+ _mi_heap_destroy_pages(heap);
221
+ if (!_mi_is_heap_main(heap)) { mi_heap_free(heap); } // todo: release locks of the main heap?
222
+ }
223
+
191
224
  void mi_heap_destroy(mi_heap_t* heap) {
192
225
  if (heap==NULL) return;
193
226
  if (_mi_is_heap_main(heap)) {
194
227
  _mi_warning_message("cannot destroy the main heap\n");
195
228
  return;
196
229
  }
197
- _mi_heap_destroy_pages(heap);
198
- mi_heap_free(heap);
230
+ _mi_heap_force_destroy(heap);
199
231
  }
200
232
 
201
233
  mi_heap_t* mi_heap_of(const void* p) {
@@ -217,3 +249,25 @@ bool mi_heap_contains(const mi_heap_t* heap, const void* p) {
217
249
  bool mi_check_owned(const void* p) {
218
250
  return mi_any_heap_contains(p);
219
251
  }
252
+
253
+ // unsafe heap utilization function for DragonFly (see issue #1258)
254
+ // If the page of pointer `p` belongs to `heap` (or `heap==NULL`) and has less than `perc_threshold` used blocks in its used area return `true`.
255
+ // This function is unsafe in general as it assumes we are the only thread accessing the page of `p`.
256
+ bool mi_unsafe_heap_page_is_under_utilized(mi_heap_t* heap, void* p, size_t perc_threshold) mi_attr_noexcept {
257
+ if (p==NULL) return false;
258
+ const mi_page_t* const page = _mi_safe_ptr_page(p); // Get the page containing this pointer
259
+ if (page==NULL || page->used==page->capacity || page->capacity < page->reserved) return false;
260
+ // If the page is the head of the queue, it is currently being used for
261
+ // allocations; we skip it to avoid immediate thrashing.
262
+ if (page->prev == NULL) return false;
263
+
264
+ // match heap?
265
+ const mi_heap_t* const page_heap = mi_page_heap(page);
266
+ if (page_heap==NULL) return false;
267
+ if (heap!=NULL && page_heap!=heap) return false;
268
+
269
+ // check utilization
270
+ if (page->capacity==0) return false;
271
+ if (perc_threshold>=100) return true;
272
+ return (perc_threshold >= ((100UL*page->used) / page->capacity));
273
+ }