00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef CU_MEMORY_H
00020 #define CU_MEMORY_H
00021
00022 #include <stdlib.h>
00023 #include <cu/fwd.h>
00024 #include <cu/tstate.h>
00025 #include <cu/conf.h>
00026 #include <cu/debug.h>
00027 #if CUCONF_HAVE_GC_GC_H
00028 # include <gc/gc.h>
00029 #else
00030 # include <gc.h>
00031 #endif
00032 #ifdef CUCONF_HAVE_GC_LOCAL_MALLOC
00033 # ifdef CUCONF_HAVE_GC_GC_LOCAL_ALLOC_H
00034 # include <gc/gc_local_alloc.h>
00035 # elif defined(CUCONF_HAVE_GC_LOCAL_ALLOC_H)
00036 # include <gc_local_alloc.h>
00037 # endif
00038 #endif
00039 #ifdef CUCONF_HAVE_STDINT_H
00040 #include <stdint.h>
00041 #endif
00042
00043
00044
00045
00046 #if !defined(CU_NDEBUG) && !defined(CU_NDEBUG_MEMORY)
00047 # define CU_DEBUG_MEMORY
00048 #endif
00049
00050
00051 CU_BEGIN_DECLARATIONS
00052
00053 #ifdef CUCONF_HAVE_STDINT_H
00054 typedef uintptr_t cu_uintptr_t;
00055 #else
00056 typedef unsigned long cu_uintptr_t;
00057 #endif
00058 void cu_raise_out_of_memory(size_t size) CU_ATTR_NORETURN;
00059 void cu_regh_out_of_memory(void (*f)(size_t));
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #define cu_salloc(size) (alloca(size))
00070
00071
00072 #define cu_sfree(p) ((void)(p))
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #if defined(CU_DEBUG_MEMORY) && !defined(CU_IN_DOXYGEN)
00084
00085 void *cuD_galloc(size_t size, char const *file, int line);
00086 void *cuD_galloc_atomic(size_t size, char const *file, int line);
00087 void *cuD_gallocz_atomic(size_t size, char const *file, int line);
00088
00089 void *cuD_ualloc(size_t size, char const *file, int line);
00090 void *cuD_ualloc_atomic(size_t size, char const *file, int line);
00091 void *cuD_uallocz_atomic(size_t size, char const *file, int line);
00092
00093 #define cu_galloc(size) cuD_galloc(size, __FILE__, __LINE__)
00094 #define cu_galloc_atomic(size) cuD_galloc_atomic(size, __FILE__, __LINE__)
00095 #define cu_gallocz(size) cuD_galloc(size, __FILE__, __LINE__)
00096 #define cu_gallocz_atomic(size) cuD_gallocz_atomic(size, __FILE__, __LINE__)
00097
00098 #define cu_ualloc(size) cuD_ualloc(size, __FILE__, __LINE__)
00099 #define cu_ualloc_atomic(size) cuD_ualloc_atomic(size, __FILE__, __LINE__)
00100 #define cu_uallocz(size) cuD_ualloc(size, __FILE__, __LINE__)
00101 #define cu_uallocz_atomic(size) cuD_uallocz_atomic(size, __FILE__, __LINE__)
00102
00103 #else
00104
00105
00106
00107 CU_SINLINE void *
00108 cu_galloc(size_t size)
00109 {
00110 void *p;
00111 #ifdef CUCONF_HAVE_GC_LOCAL_MALLOC
00112 p = GC_local_malloc(size);
00113 #else
00114 p = GC_malloc(size);
00115 #endif
00116 if (p == NULL)
00117 cu_raise_out_of_memory(size);
00118 return p;
00119 }
00120
00121
00122
00123 CU_SINLINE void *
00124 cu_galloc_atomic(size_t size)
00125 {
00126 void *p;
00127 #ifdef CUCONF_HAVE_GC_LOCAL_MALLOC_ATOMIC
00128 p = GC_local_malloc_atomic(size);
00129 #else
00130 p = GC_malloc_atomic(size);
00131 #endif
00132 if (p == NULL)
00133 cu_raise_out_of_memory(size);
00134 return p;
00135 }
00136
00137
00138 CU_SINLINE void *cu_gallocz(size_t size) { return cu_galloc(size); }
00139
00140
00141 void *cu_gallocz_atomic(size_t size);
00142
00143
00144
00145 CU_SINLINE void *
00146 cu_ualloc(size_t size)
00147 {
00148 void *p;
00149 p = GC_malloc_uncollectable(size);
00150 if (p == NULL)
00151 cu_raise_out_of_memory(size);
00152 return p;
00153 }
00154
00155
00156
00157
00158 CU_SINLINE void *
00159 cu_ualloc_atomic(size_t size)
00160 {
00161 void *p;
00162 #ifdef CUCONF_HAVE_GC_MALLOC_ATOMIC_UNCOLLECTABLE
00163 p = GC_malloc_atomic_uncollectable(size);
00164 #else
00165 p = malloc(size);
00166 #endif
00167 if (p == NULL)
00168 cu_raise_out_of_memory(size);
00169 return p;
00170 }
00171
00172
00173 CU_SINLINE void *cu_uallocz(size_t size) { return cu_ualloc(size); }
00174
00175
00176 void *cu_uallocz_atomic(size_t size);
00177
00178 #endif
00179
00180
00181 #if defined(CU_DEBUG_MEMORY) && !defined(CU_IN_DOXYGEN)
00182
00183 void cuD_gfree(void *ptr, char const *file, int line);
00184 void cuD_ufree_atomic(void *ptr, char const *file, int line);
00185 # define cu_gfree(ptr) cuD_gfree(ptr, __FILE__, __LINE__)
00186 # define cu_gfree_atomic cu_gfree
00187 # define cu_ufree cu_gfree
00188 # define cu_ufree_atomic(ptr) cuD_ufree_atomic(ptr, __FILE__, __LINE__)
00189
00190 #else
00191
00192
00193 # define cu_gfree GC_free
00194
00195
00196 # define cu_gfree_atomic cu_gfree
00197
00198
00199 # define cu_ufree cu_gfree
00200
00201
00202 # ifdef CUCONF_HAVE_GC_MALLOC_ATOMIC_UNCOLLECTABLE
00203 # define cu_ufree_atomic cu_gfree
00204 # else
00205 # define cu_ufree_atomic free
00206 # endif
00207
00208 #endif
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 #define cu_snew(type, n) ((type *)cu_salloc(sizeof(type)))
00220
00221
00222 #define cu_gnew(type) ((type*)cu_galloc(sizeof(type)))
00223
00224
00225 #define cu_gnew_atomic(type) ((type *)cu_galloc_atomic(sizeof(type)))
00226
00227
00228 #define cu_unew(type) ((type *)cu_ualloc(sizeof(type)))
00229
00230
00231 #define cu_unew_atomic(type) ((type *)cu_ualloc_atomic(sizeof(type)))
00232
00233 #define cu_gnewz(type) ((type *)cu_gallocz(sizeof(type)))
00234 #define cu_gnewz_atomic(type) ((type *)cu_gallocz_atomic(sizeof(type)))
00235 #define cu_unewz(type) ((type *)cu_uallocz(sizeof(type)))
00236 #define cu_unewz_atomic(type) ((type *)cu_uallocz_atomic(sizeof(type)))
00237
00238 #define cu_snewarr(type, n) ((type *)cu_salloc(sizeof(type)*(n)))
00239 #define cu_gnewarr(type, n) ((type *)cu_galloc(sizeof(type)*(n)))
00240 #define cu_gnewarr_atomic(type, n) ((type *)cu_galloc_atomic(sizeof(type)*(n)))
00241 #define cu_unewarr(type, n) ((type *)cu_ualloc(sizeof(type)*(n)))
00242 #define cu_unewarr_atomic(type, n) ((type *)cu_ualloc_atomic(sizeof(type)*(n)))
00243
00244 #define cu_gnewarrz(type, n) ((type *)cu_gallocz(sizeof(type)*(n)))
00245 #define cu_gnewarrz_atomic(type, n) ((type *)cu_gallocz_atomic(sizeof(type)*(n)))
00246 #define cu_unewarrz(type, n) ((type *)cu_uallocz(sizeof(type)*(n)))
00247 #define cu_unewarrz_atomic(type, n) ((type *)cu_uallocz_atomic(sizeof(type)*(n)))
00248
00249
00250
00251
00252
00253
00254
00255
00256 #define CU_GWIPE(ptr_lvalue) ((ptr_lvalue) = NULL)
00257
00258 #define CU_GCLEAR_INT(lvalue) (0? (void)((lvalue) = 0) : (void)0)
00259 #define CU_GCLEAR_PTR(lvalue) (0? (void)((lvalue) = NULL) : (void)0)
00260
00261
00262
00263 typedef struct cu_hidden_ptr *cu_hidden_ptr_t;
00264
00265
00266 #define cu_hide_ptr(ptr) ((cu_hidden_ptr_t)~(cu_uintptr_t)(ptr))
00267
00268
00269
00270 #define cu_reveal_ptr(hptr) \
00271 ((void*)~(cu_uintptr_t)CU_MARG(cu_hidden_ptr_t, hptr))
00272
00273 #ifdef CU_DEBUG_MEMORY
00274 void *cuD_gc_base(void *);
00275 # define cu_gc_base cuD_gc_base
00276 # define cu_gc_register_finaliser GC_debug_register_finalizer
00277 # define cu_gc_register_finaliser_no_order GC_debug_register_finalizer_no_order
00278 #else
00279 # define cu_gc_base GC_base
00280 # define cu_gc_register_finaliser GC_register_finalizer
00281 # define cu_gc_register_finaliser_no_order GC_register_finalizer_no_order
00282 #endif
00283
00284 #ifndef CU_DEBUG_MEMORY
00285 # define cu_gc_ptr_assign(p, q) (*(p) = (q))
00286 #else
00287 # define cu_gc_ptr_assign(p, q) \
00288 (1 ? *((void**)GC_is_visible(p)) = GC_is_valid_displacement(q) \
00289 : *(p) = (q))
00290 #endif
00291
00292
00293
00294
00295 #if defined(CU_COMPAT) && CU_COMPAT < 20091115
00296 # define cu_malloc malloc
00297 # define cu_mfree free
00298 # define cu_galloc_a cu_galloc_atomic
00299 # define cu_galloc_u cu_ualloc
00300 # define cu_galloc_au cu_ualloc_atomic
00301 # define cu_cgalloc cu_gallocz
00302 # define cu_cgalloc_a cu_gallocz_atomic
00303 # define cu_cgalloc_u cu_uallocz
00304 # define cu_gfree_a cu_gfree_atomic
00305 # define cu_gfree_u cu_ufree
00306 # define cu_gfree_au cu_ufree_atomic
00307 # define cu_gnew_a cu_gnew_atomic
00308 # define cu_gnew_u cu_unew
00309 # define cu_gnew_au cu_unew_atomic
00310 # define cu_cgnew cu_gnewz
00311 # define cu_gnewarr_a cu_gnewarr_atomic
00312 # define cu_gnewarr_u cu_unewarr
00313 # define cu_gnewarr_au cu_unewarr_atomic
00314 #endif
00315
00316 CU_END_DECLARATIONS
00317
00318 #endif