@@ -19,6 +19,7 @@ struct MemInfo {
1919    void               * dtor_info ;
2020    void               * data ;
2121    size_t             size ;    /* only used for NRT allocated memory */ 
22+     NRT_ExternalAllocator  * external_allocator ;
2223};
2324
2425
@@ -170,13 +171,16 @@ void NRT_MemSys_set_atomic_cas_stub(void) {
170171 */ 
171172
172173void  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 )
174176{
175177    mi -> refct  =  1 ;  /* starts with 1 refct */ 
176178    mi -> dtor  =  dtor ;
177179    mi -> dtor_info  =  dtor_info ;
178180    mi -> data  =  data ;
179181    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 ));
180184    /* Update stats */ 
181185    TheMSys .atomic_inc (& TheMSys .stats_mi_alloc );
182186}
@@ -185,7 +189,8 @@ NRT_MemInfo *NRT_MemInfo_new(void *data, size_t size,
185189                             NRT_dtor_function  dtor , void  * dtor_info )
186190{
187191    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 );
189194    return  mi ;
190195}
191196
@@ -206,9 +211,10 @@ void nrt_internal_dtor_safe(void *ptr, size_t size, void *info) {
206211}
207212
208213static 
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 ) {
210215    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 );
212218    mi  =  (NRT_MemInfo  * ) base ;
213219    * mi_out  =  mi ;
214220    return  base  +  sizeof (NRT_MemInfo );
@@ -230,9 +236,17 @@ void nrt_internal_custom_dtor_safe(void *ptr, size_t size, void *info) {
230236
231237NRT_MemInfo  * NRT_MemInfo_alloc (size_t  size ) {
232238    NRT_MemInfo  * mi ;
233-     void  * data  =  nrt_allocate_meminfo_and_data (size , & mi );
239+     void  * data  =  nrt_allocate_meminfo_and_data (size , & mi ,  NULL );
234240    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 );
236250    return  mi ;
237251}
238252
@@ -242,22 +256,23 @@ NRT_MemInfo *NRT_MemInfo_alloc_safe(size_t size) {
242256
243257NRT_MemInfo *  NRT_MemInfo_alloc_dtor_safe (size_t  size , NRT_dtor_function  dtor ) {
244258    NRT_MemInfo  * mi ;
245-     void  * data  =  nrt_allocate_meminfo_and_data (size , & mi );
259+     void  * data  =  nrt_allocate_meminfo_and_data (size , & mi ,  NULL );
246260    /* Only fill up a couple cachelines with debug markers, to minimize 
247261       overhead. */ 
248262    memset (data , 0xCB , MIN (size , 256 ));
249263    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 );
251265    return  mi ;
252266}
253267
254268
255269static 
256270void  * nrt_allocate_meminfo_and_data_align (size_t  size , unsigned  align ,
257-                                           NRT_MemInfo  * * mi )
271+                                           NRT_MemInfo  * * mi ,  NRT_ExternalAllocator   * allocator )
258272{
259273    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 );
261276    intptr  =  (size_t ) base ;
262277    /* See if we are aligned */ 
263278    remainder  =  intptr  % align ;
@@ -271,26 +286,48 @@ void *nrt_allocate_meminfo_and_data_align(size_t size, unsigned align,
271286
272287NRT_MemInfo  * NRT_MemInfo_alloc_aligned (size_t  size , unsigned  align ) {
273288    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 );
275290    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 );
277292    return  mi ;
278293}
279294
280295NRT_MemInfo  * NRT_MemInfo_alloc_safe_aligned (size_t  size , unsigned  align ) {
281296    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 );
283298    /* Only fill up a couple cachelines with debug markers, to minimize 
284299       overhead. */ 
285300    memset (data , 0xCB , MIN (size , 256 ));
286301    NRT_Debug (nrt_debug_print ("NRT_MemInfo_alloc_safe_aligned %p %zu\n" ,
287302                              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 );
289304    return  mi ;
290305}
291306
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+ 
292329void  NRT_MemInfo_destroy (NRT_MemInfo  * mi ) {
293-     NRT_Free (mi );
330+     NRT_dealloc (mi );
294331    TheMSys .atomic_inc (& TheMSys .stats_mi_free );
295332}
296333
@@ -328,6 +365,14 @@ size_t NRT_MemInfo_size(NRT_MemInfo* mi) {
328365    return  mi -> size ;
329366}
330367
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+ }
331376
332377void  NRT_MemInfo_dump (NRT_MemInfo  * mi , FILE  * out ) {
333378    fprintf (out , "MemInfo %p refcount %zu\n" , mi , mi -> refct );
@@ -414,8 +459,18 @@ void NRT_MemInfo_varsize_free(NRT_MemInfo *mi, void *ptr)
414459 */ 
415460
416461void *  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+     }
419474    TheMSys .atomic_inc (& TheMSys .stats_alloc );
420475    return  ptr ;
421476}
@@ -460,6 +515,7 @@ NRT_MemInfo* nrt_manage_memory(void *data, NRT_managed_dtor dtor) {
460515static  const 
461516NRT_api_functions  nrt_functions_table  =  {
462517    NRT_MemInfo_alloc ,
518+     NRT_MemInfo_alloc_external ,
463519    nrt_manage_memory ,
464520    NRT_MemInfo_acquire ,
465521    NRT_MemInfo_release ,
0 commit comments