@@ -19,6 +19,7 @@ struct MemInfo {
19
19
void * dtor_info ;
20
20
void * data ;
21
21
size_t size ; /* only used for NRT allocated memory */
22
+ NRT_ExternalAllocator * external_allocator ;
22
23
};
23
24
24
25
@@ -170,13 +171,16 @@ void NRT_MemSys_set_atomic_cas_stub(void) {
170
171
*/
171
172
172
173
void NRT_MemInfo_init (NRT_MemInfo * mi ,void * data , size_t size ,
173
- NRT_dtor_function dtor , void * dtor_info )
174
+ NRT_dtor_function dtor , void * dtor_info ,
175
+ NRT_ExternalAllocator * external_allocator )
174
176
{
175
177
mi -> refct = 1 ; /* starts with 1 refct */
176
178
mi -> dtor = dtor ;
177
179
mi -> dtor_info = dtor_info ;
178
180
mi -> data = data ;
179
181
mi -> size = size ;
182
+ mi -> external_allocator = external_allocator ;
183
+ NRT_Debug (nrt_debug_print ("NRT_MemInfo_init mi=%p external_allocator=%p\n" , mi , external_allocator ));
180
184
/* Update stats */
181
185
TheMSys .atomic_inc (& TheMSys .stats_mi_alloc );
182
186
}
@@ -185,7 +189,8 @@ NRT_MemInfo *NRT_MemInfo_new(void *data, size_t size,
185
189
NRT_dtor_function dtor , void * dtor_info )
186
190
{
187
191
NRT_MemInfo * mi = NRT_Allocate (sizeof (NRT_MemInfo ));
188
- NRT_MemInfo_init (mi , data , size , dtor , dtor_info );
192
+ NRT_Debug (nrt_debug_print ("NRT_MemInfo_new mi=%p\n" , mi ));
193
+ NRT_MemInfo_init (mi , data , size , dtor , dtor_info , NULL );
189
194
return mi ;
190
195
}
191
196
@@ -206,9 +211,10 @@ void nrt_internal_dtor_safe(void *ptr, size_t size, void *info) {
206
211
}
207
212
208
213
static
209
- void * nrt_allocate_meminfo_and_data (size_t size , NRT_MemInfo * * mi_out ) {
214
+ void * nrt_allocate_meminfo_and_data (size_t size , NRT_MemInfo * * mi_out , NRT_ExternalAllocator * allocator ) {
210
215
NRT_MemInfo * mi ;
211
- char * base = NRT_Allocate (sizeof (NRT_MemInfo ) + size );
216
+ NRT_Debug (nrt_debug_print ("nrt_allocate_meminfo_and_data %p\n" , allocator ));
217
+ char * base = NRT_Allocate_External (sizeof (NRT_MemInfo ) + size , allocator );
212
218
mi = (NRT_MemInfo * ) base ;
213
219
* mi_out = mi ;
214
220
return base + sizeof (NRT_MemInfo );
@@ -230,9 +236,17 @@ void nrt_internal_custom_dtor_safe(void *ptr, size_t size, void *info) {
230
236
231
237
NRT_MemInfo * NRT_MemInfo_alloc (size_t size ) {
232
238
NRT_MemInfo * mi ;
233
- void * data = nrt_allocate_meminfo_and_data (size , & mi );
239
+ void * data = nrt_allocate_meminfo_and_data (size , & mi , NULL );
234
240
NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc %p\n" , data ));
235
- NRT_MemInfo_init (mi , data , size , NULL , NULL );
241
+ NRT_MemInfo_init (mi , data , size , NULL , NULL , NULL );
242
+ return mi ;
243
+ }
244
+
245
+ NRT_MemInfo * NRT_MemInfo_alloc_external (size_t size , NRT_ExternalAllocator * allocator ) {
246
+ NRT_MemInfo * mi ;
247
+ void * data = nrt_allocate_meminfo_and_data (size , & mi , allocator );
248
+ NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc %p\n" , data ));
249
+ NRT_MemInfo_init (mi , data , size , NULL , NULL , allocator );
236
250
return mi ;
237
251
}
238
252
@@ -242,22 +256,23 @@ NRT_MemInfo *NRT_MemInfo_alloc_safe(size_t size) {
242
256
243
257
NRT_MemInfo * NRT_MemInfo_alloc_dtor_safe (size_t size , NRT_dtor_function dtor ) {
244
258
NRT_MemInfo * mi ;
245
- void * data = nrt_allocate_meminfo_and_data (size , & mi );
259
+ void * data = nrt_allocate_meminfo_and_data (size , & mi , NULL );
246
260
/* Only fill up a couple cachelines with debug markers, to minimize
247
261
overhead. */
248
262
memset (data , 0xCB , MIN (size , 256 ));
249
263
NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc_dtor_safe %p %zu\n" , data , size ));
250
- NRT_MemInfo_init (mi , data , size , nrt_internal_custom_dtor_safe , dtor );
264
+ NRT_MemInfo_init (mi , data , size , nrt_internal_custom_dtor_safe , dtor , NULL );
251
265
return mi ;
252
266
}
253
267
254
268
255
269
static
256
270
void * nrt_allocate_meminfo_and_data_align (size_t size , unsigned align ,
257
- NRT_MemInfo * * mi )
271
+ NRT_MemInfo * * mi , NRT_ExternalAllocator * allocator )
258
272
{
259
273
size_t offset , intptr , remainder ;
260
- char * base = nrt_allocate_meminfo_and_data (size + 2 * align , mi );
274
+ NRT_Debug (nrt_debug_print ("nrt_allocate_meminfo_and_data_align %p\n" , allocator ));
275
+ char * base = nrt_allocate_meminfo_and_data (size + 2 * align , mi , allocator );
261
276
intptr = (size_t ) base ;
262
277
/* See if we are aligned */
263
278
remainder = intptr % align ;
@@ -271,26 +286,48 @@ void *nrt_allocate_meminfo_and_data_align(size_t size, unsigned align,
271
286
272
287
NRT_MemInfo * NRT_MemInfo_alloc_aligned (size_t size , unsigned align ) {
273
288
NRT_MemInfo * mi ;
274
- void * data = nrt_allocate_meminfo_and_data_align (size , align , & mi );
289
+ void * data = nrt_allocate_meminfo_and_data_align (size , align , & mi , NULL );
275
290
NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc_aligned %p\n" , data ));
276
- NRT_MemInfo_init (mi , data , size , NULL , NULL );
291
+ NRT_MemInfo_init (mi , data , size , NULL , NULL , NULL );
277
292
return mi ;
278
293
}
279
294
280
295
NRT_MemInfo * NRT_MemInfo_alloc_safe_aligned (size_t size , unsigned align ) {
281
296
NRT_MemInfo * mi ;
282
- void * data = nrt_allocate_meminfo_and_data_align (size , align , & mi );
297
+ void * data = nrt_allocate_meminfo_and_data_align (size , align , & mi , NULL );
283
298
/* Only fill up a couple cachelines with debug markers, to minimize
284
299
overhead. */
285
300
memset (data , 0xCB , MIN (size , 256 ));
286
301
NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc_safe_aligned %p %zu\n" ,
287
302
data , size ));
288
- NRT_MemInfo_init (mi , data , size , nrt_internal_dtor_safe , (void * )size );
303
+ NRT_MemInfo_init (mi , data , size , nrt_internal_dtor_safe , (void * )size , NULL );
289
304
return mi ;
290
305
}
291
306
307
+ NRT_MemInfo * NRT_MemInfo_alloc_safe_aligned_external (size_t size , unsigned align , NRT_ExternalAllocator * allocator ) {
308
+ NRT_MemInfo * mi ;
309
+ NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc_safe_aligned_external %p\n" , allocator ));
310
+ void * data = nrt_allocate_meminfo_and_data_align (size , align , & mi , allocator );
311
+ /* Only fill up a couple cachelines with debug markers, to minimize
312
+ overhead. */
313
+ memset (data , 0xCB , MIN (size , 256 ));
314
+ NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc_safe_aligned %p %zu\n" ,
315
+ data , size ));
316
+ NRT_MemInfo_init (mi , data , size , nrt_internal_dtor_safe , (void * )size , allocator );
317
+ return mi ;
318
+ }
319
+
320
+ void NRT_dealloc (NRT_MemInfo * mi ) {
321
+ NRT_Debug (nrt_debug_print ("NRT_dealloc meminfo: %p external_allocator: %p\n" , mi , mi -> external_allocator ));
322
+ if (mi -> external_allocator ) {
323
+ mi -> external_allocator -> free (mi , mi -> external_allocator -> opaque_data );
324
+ } else {
325
+ NRT_Free (mi );
326
+ }
327
+ }
328
+
292
329
void NRT_MemInfo_destroy (NRT_MemInfo * mi ) {
293
- NRT_Free (mi );
330
+ NRT_dealloc (mi );
294
331
TheMSys .atomic_inc (& TheMSys .stats_mi_free );
295
332
}
296
333
@@ -328,6 +365,14 @@ size_t NRT_MemInfo_size(NRT_MemInfo* mi) {
328
365
return mi -> size ;
329
366
}
330
367
368
+ void * NRT_MemInfo_external_allocator (NRT_MemInfo * mi ) {
369
+ NRT_Debug (nrt_debug_print ("NRT_MemInfo_external_allocator meminfo: %p external_allocator: %p\n" , mi , mi -> external_allocator ));
370
+ return mi -> external_allocator ;
371
+ }
372
+
373
+ void * NRT_MemInfo_parent (NRT_MemInfo * mi ) {
374
+ return mi -> dtor_info ;
375
+ }
331
376
332
377
void NRT_MemInfo_dump (NRT_MemInfo * mi , FILE * out ) {
333
378
fprintf (out , "MemInfo %p refcount %zu\n" , mi , mi -> refct );
@@ -414,8 +459,18 @@ void NRT_MemInfo_varsize_free(NRT_MemInfo *mi, void *ptr)
414
459
*/
415
460
416
461
void * NRT_Allocate (size_t size ) {
417
- void * ptr = TheMSys .allocator .malloc (size );
418
- NRT_Debug (nrt_debug_print ("NRT_Allocate bytes=%zu ptr=%p\n" , size , ptr ));
462
+ return NRT_Allocate_External (size , NULL );
463
+ }
464
+
465
+ void * NRT_Allocate_External (size_t size , NRT_ExternalAllocator * allocator ) {
466
+ void * ptr ;
467
+ if (allocator ) {
468
+ ptr = allocator -> malloc (size , allocator -> opaque_data );
469
+ NRT_Debug (nrt_debug_print ("NRT_Allocate custom bytes=%zu ptr=%p\n" , size , ptr ));
470
+ } else {
471
+ ptr = TheMSys .allocator .malloc (size );
472
+ NRT_Debug (nrt_debug_print ("NRT_Allocate bytes=%zu ptr=%p\n" , size , ptr ));
473
+ }
419
474
TheMSys .atomic_inc (& TheMSys .stats_alloc );
420
475
return ptr ;
421
476
}
@@ -460,6 +515,7 @@ NRT_MemInfo* nrt_manage_memory(void *data, NRT_managed_dtor dtor) {
460
515
static const
461
516
NRT_api_functions nrt_functions_table = {
462
517
NRT_MemInfo_alloc ,
518
+ NRT_MemInfo_alloc_external ,
463
519
nrt_manage_memory ,
464
520
NRT_MemInfo_acquire ,
465
521
NRT_MemInfo_release ,
0 commit comments