@@ -13,6 +13,7 @@ terms of the MIT license. A copy of the license can be found in the file
1313// Empty page used to initialize the small free pages array
1414const mi_page_t _mi_page_empty = {
1515 0 , false, false, false, false,
16+ 0 , // tag
1617 0 , // capacity
1718 0 , // reserved capacity
1819 { 0 }, // flags
@@ -98,6 +99,8 @@ const mi_heap_t _mi_heap_empty = {
9899 { {0 }, {0 }, 0 },
99100 0 , // page count
100101 NULL , // next
102+ false,
103+ 0 ,
101104 false
102105};
103106
@@ -110,9 +113,15 @@ mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;
110113
111114extern mi_heap_t _mi_heap_main ;
112115
116+ // Initialized in mi_heap_init
117+ static mi_heap_t _mi_heap_main_obj ;
118+ static mi_heap_t _mi_heap_main_gc ;
119+
113120static mi_tld_t tld_main = {
114121 0 , false,
115122 & _mi_heap_main , & _mi_heap_main ,
123+ & _mi_heap_main_obj ,
124+ & _mi_heap_main_gc ,
116125 { { NULL , NULL }, {NULL ,NULL }, {NULL ,NULL , 0 },
117126 0 , 0 , 0 , 0 , 0 , 0 , NULL ,
118127 tld_main_stats , tld_main_os
@@ -163,9 +172,22 @@ mi_heap_t* _mi_heap_main_get(void) {
163172// note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size).
164173typedef struct mi_thread_data_s {
165174 mi_heap_t heap ; // must come first due to cast in `_mi_heap_done`
175+ mi_heap_t heap_obj ;
176+ mi_heap_t heap_gc ;
166177 mi_tld_t tld ;
167178} mi_thread_data_t ;
168179
180+ static void _mi_heap_init_ex (mi_heap_t * heap , mi_tld_t * tld , int tag ) {
181+ memcpy (heap , & _mi_heap_empty , sizeof (* heap ));
182+ heap -> thread_id = _mi_thread_id ();
183+ _mi_random_init (& heap -> random );
184+ heap -> cookie = _mi_heap_random_next (heap ) | 1 ;
185+ heap -> keys [0 ] = _mi_heap_random_next (heap );
186+ heap -> keys [1 ] = _mi_heap_random_next (heap );
187+ heap -> tld = tld ;
188+ heap -> tag = tag ;
189+ }
190+
169191// Initialize the thread local default heap, called from `mi_thread_init`
170192static bool _mi_heap_init (void ) {
171193 if (mi_heap_is_initialized (mi_get_default_heap ())) return true;
@@ -185,24 +207,23 @@ static bool _mi_heap_init(void) {
185207 }
186208 // OS allocated so already zero initialized
187209 mi_tld_t * tld = & td -> tld ;
188- mi_heap_t * heap = & td -> heap ;
189- memcpy (heap , & _mi_heap_empty , sizeof (* heap ));
190- heap -> thread_id = _mi_thread_id ();
191- _mi_random_init (& heap -> random );
192- heap -> cookie = _mi_heap_random_next (heap ) | 1 ;
193- heap -> keys [0 ] = _mi_heap_random_next (heap );
194- heap -> keys [1 ] = _mi_heap_random_next (heap );
195- heap -> tld = tld ;
196- tld -> heap_backing = heap ;
197- tld -> heaps = heap ;
210+ _mi_heap_init_ex (& td -> heap , & td -> tld , mi_heap_tag_default );
211+ _mi_heap_init_ex (& td -> heap_obj , & td -> tld , mi_heap_tag_obj );
212+ _mi_heap_init_ex (& td -> heap_gc , & td -> tld , mi_heap_tag_gc );
213+ tld -> heap_backing = & td -> heap ;
214+ tld -> heaps = & td -> heap ;
215+ tld -> heap_obj = & td -> heap_obj ;
216+ tld -> heap_gc = & td -> heap_gc ;
198217 tld -> segments .stats = & tld -> stats ;
199218 tld -> segments .os = & tld -> os ;
200219 tld -> os .stats = & tld -> stats ;
201- _mi_heap_set_default_direct (heap );
220+ _mi_heap_set_default_direct (& td -> heap );
202221 }
203222 return false;
204223}
205224
225+ void mi_heap_absorb (mi_heap_t * heap , mi_heap_t * from );
226+
206227// Free the thread local default heap (called from `mi_thread_done`)
207228static bool _mi_heap_done (mi_heap_t * heap ) {
208229 if (!mi_heap_is_initialized (heap )) return true;
@@ -230,6 +251,8 @@ static bool _mi_heap_done(mi_heap_t* heap) {
230251
231252 // collect if not the main thread
232253 if (heap != & _mi_heap_main ) {
254+ mi_heap_absorb (heap , heap -> tld -> heap_obj );
255+ mi_heap_absorb (heap , heap -> tld -> heap_gc );
233256 _mi_heap_collect_abandon (heap );
234257 }
235258
@@ -461,6 +484,8 @@ void mi_process_init(void) mi_attr_noexcept {
461484 _mi_verbose_message ("process init: 0x%zx\n" , _mi_thread_id ());
462485 _mi_os_init ();
463486 mi_heap_main_init ();
487+ _mi_heap_init_ex (& _mi_heap_main_obj , & tld_main , mi_heap_tag_obj );
488+ _mi_heap_init_ex (& _mi_heap_main_gc , & tld_main , mi_heap_tag_gc );
464489 #if (MI_DEBUG )
465490 _mi_verbose_message ("debug level : %d\n" , MI_DEBUG );
466491 #endif
0 commit comments