@@ -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