1 /** 2 * \file 3 * GC aware equivalente of g_ptr_array 4 * 5 * Author: 6 * Rodrigo Kumpera <rkumpera@novell.com> 7 * 8 * (C) 2010 Novell, Inc 9 */ 10 11 #ifndef __MONO_PTR_ARRAY_H__ 12 #define __MONO_PTR_ARRAY_H__ 13 14 15 #include <glib.h> 16 17 #include "mono/metadata/gc-internals.h" 18 19 /* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes. 20 * It works by allocating an initial small array on stack and only going to gc tracked memory if needed. 21 * The array elements are assumed to be object references. 22 */ 23 typedef struct { 24 void **data; 25 int size; 26 int capacity; 27 MonoGCRootSource source; 28 const char *msg; 29 } MonoPtrArray; 30 31 #define MONO_PTR_ARRAY_MAX_ON_STACK (16) 32 33 #define mono_ptr_array_init(ARRAY, INITIAL_SIZE, SOURCE, MSG) do {\ 34 (ARRAY).size = 0; \ 35 (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \ 36 (ARRAY).source = SOURCE; \ 37 (ARRAY).msg = MSG; \ 38 (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK \ 39 ? (void **)mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, mono_gc_make_root_descr_all_refs (INITIAL_SIZE), SOURCE, MSG) \ 40 : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \ 41 } while (0) 42 43 #define mono_ptr_array_destroy(ARRAY) do {\ 44 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \ 45 mono_gc_free_fixed ((ARRAY).data); \ 46 } while (0) 47 48 #define mono_ptr_array_append(ARRAY, VALUE) do { \ 49 if ((ARRAY).size >= (ARRAY).capacity) {\ 50 void **__tmp = (void **)mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, mono_gc_make_root_descr_all_refs ((ARRAY).capacity * 2), (ARRAY).source, (ARRAY).msg); \ 51 mono_gc_memmove_aligned ((void *)__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \ 52 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \ 53 mono_gc_free_fixed ((ARRAY).data); \ 54 (ARRAY).data = __tmp; \ 55 (ARRAY).capacity *= 2;\ 56 }\ 57 ((ARRAY).data [(ARRAY).size++] = VALUE); \ 58 } while (0) 59 60 #define mono_ptr_array_sort(ARRAY, COMPARE_FUNC) do { \ 61 qsort ((ARRAY).data, (ARRAY).size, sizeof (gpointer), (COMPARE_FUNC)); \ 62 } while (0) 63 64 #define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \ 65 ((ARRAY).data [(IDX)] = VALUE); \ 66 } while (0) 67 68 #define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)]) 69 70 #define mono_ptr_array_size(ARRAY) ((ARRAY).size) 71 72 #define mono_ptr_array_reset(ARRAY) do { \ 73 (ARRAY).size = 0; \ 74 } while (0) 75 76 #define mono_ptr_array_clear(ARRAY) do { \ 77 (ARRAY).size = 0; \ 78 mono_gc_bzero_aligned ((ARRAY).data, (ARRAY).capacity * sizeof (void*)); \ 79 } while (0) 80 81 #endif 82