1 /* Copyright (C) 2001-2012 Artifex Software, Inc. 2 All Rights Reserved. 3 4 This software is provided AS-IS with no warranty, either express or 5 implied. 6 7 This software is distributed under license and may not be copied, 8 modified or distributed except as expressly authorized under the terms 9 of the license contained in the file LICENSE in this distribution. 10 11 Refer to licensing information at http://www.artifex.com or contact 12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, 13 CA 94903, U.S.A., +1(415)492-9861, for further information. 14 */ 15 16 17 /* Client interface for memory allocation */ 18 19 /* 20 * The allocator knows about two basic kinds of memory: objects, which are 21 * aligned and cannot have pointers to their interior, and strings, which 22 * are not aligned and which can have interior references. 23 * 24 * Note: OBJECTS ARE NOT GUARANTEED to be aligned any more strictly than 25 * required by the hardware, regardless of the value of obj_align_mod. In 26 * other words, whether ALIGNMENT_MOD(ptr, obj_align_mod) will be zero 27 * depends on the alignment provided by the underlying allocator. 28 * Most systems ensure this, but Microsoft VC 6 in particular does not. 29 * See gsmemraw.h for more information about this. 30 * 31 * The standard allocator is designed to interface to a garbage collector, 32 * although it does not include or call one. The allocator API recognizes 33 * that the garbage collector may move objects, relocating pointers to them; 34 * the API provides for allocating both movable (the default) and immovable 35 * objects. Clients must not attempt to resize immovable objects, and must 36 * not create references to substrings of immovable strings. 37 */ 38 39 #ifndef gsmemory_INCLUDED 40 # define gsmemory_INCLUDED 41 42 #include "gstypes.h" /* for gs_bytestring */ 43 #include "gslibctx.h" 44 45 /* Define the opaque type for a structure descriptor. */ 46 typedef struct gs_memory_struct_type_s gs_memory_struct_type_t; 47 typedef const gs_memory_struct_type_t *gs_memory_type_ptr_t; 48 49 /* Define the opaque type for an allocator. */ 50 /* (The actual structure is defined later in this file.) */ 51 #ifndef gs_memory_DEFINED 52 # define gs_memory_DEFINED 53 typedef struct gs_memory_s gs_memory_t; 54 #endif 55 56 /* Define the opaque type for a pointer type. */ 57 typedef struct gs_ptr_procs_s gs_ptr_procs_t; 58 typedef const gs_ptr_procs_t *gs_ptr_type_t; 59 60 /* Define the opaque type for a GC root. */ 61 typedef struct gs_gc_root_s gs_gc_root_t; 62 63 /* Accessors for structure types. */ 64 65 typedef client_name_t struct_name_t; 66 67 /* Get the size of a structure from the descriptor. */ 68 uint gs_struct_type_size(gs_memory_type_ptr_t); 69 70 /* Get the name of a structure from the descriptor. */ 71 struct_name_t gs_struct_type_name(gs_memory_type_ptr_t); 72 73 #define gs_struct_type_name_string(styp)\ 74 ((const char *)gs_struct_type_name(styp)) 75 76 /* 77 * Define the structure for reporting memory manager statistics. 78 */ 79 typedef struct gs_memory_status_s { 80 /* 81 * "Allocated" space is the total amount of space acquired from 82 * the parent of the memory manager. It includes space used for 83 * allocated data, space available for allocation, and overhead. 84 */ 85 ulong allocated; 86 /* 87 * "Used" space is the amount of space used by allocated data 88 * plus overhead. 89 */ 90 ulong used; 91 /* used when wrapping if underlying allocator must be thread safe */ 92 bool is_thread_safe; 93 } gs_memory_status_t; 94 95 /* 96 * Allocate bytes. The bytes are always aligned maximally 97 * if the processor requires alignment. 98 * 99 * Note that the object memory level can allocate bytes as 100 * either movable or immovable: raw memory blocks are 101 * always immovable. 102 */ 103 104 #define gs_memory_t_proc_alloc_bytes(proc, mem_t)\ 105 byte *proc(mem_t *mem, uint nbytes, client_name_t cname) 106 107 #define gs_alloc_bytes_immovable(mem, nbytes, cname)\ 108 ((mem)->procs.alloc_bytes_immovable(mem, nbytes, cname)) 109 110 /* 111 * Resize an object to a new number of elements. At the raw 112 * memory level, the "element" is a byte; for object memory 113 * (gsmemory.h), the object may be an an array of either 114 * bytes or structures. The new size may be larger than, 115 * the same as, or smaller than the old. If the new size is 116 * the same as the old, resize_object returns the same 117 * object; otherwise, it preserves the first min(old_size, 118 * new_size) bytes of the object's contents. 119 */ 120 121 #define gs_memory_t_proc_resize_object(proc, mem_t)\ 122 void *proc(mem_t *mem, void *obj, uint new_num_elements,\ 123 client_name_t cname) 124 125 #define gs_resize_object(mem, obj, newn, cname)\ 126 ((mem)->procs.resize_object(mem, obj, newn, cname)) 127 128 /* 129 * Free an object (at the object memory level, this includes 130 * everything except strings). Note: data == 0 must be 131 * allowed, and must be a no-op. 132 */ 133 134 #define gs_memory_t_proc_free_object(proc, mem_t)\ 135 void proc(mem_t *mem, void *data, client_name_t cname) 136 137 #define gs_free_object(mem, data, cname)\ 138 ((mem)->procs.free_object(mem, data, cname)) 139 140 /* 141 * Report status (assigned, used). 142 */ 143 144 #define gs_memory_t_proc_status(proc, mem_t)\ 145 void proc(mem_t *mem, gs_memory_status_t *status) 146 147 #define gs_memory_status(mem, pst)\ 148 ((mem)->procs.status(mem, pst)) 149 150 /* 151 * Return the stable allocator for this allocator. The 152 * stable allocator allocates from the same heap and in 153 * the same VM space, but is not subject to save and restore. 154 * (It is the client's responsibility to avoid creating 155 * dangling pointers.) 156 * 157 * Note that the stable allocator may be the same allocator 158 * as this one. 159 */ 160 161 #define gs_memory_t_proc_stable(proc, mem_t)\ 162 mem_t *proc(mem_t *mem) 163 164 #define gs_memory_stable(mem)\ 165 ((mem)->procs.stable(mem)) 166 167 /* 168 * Free one or more of: data memory acquired by the allocator 169 * (FREE_ALL_DATA), overhead structures other than the 170 * allocator itself (FREE_ALL_STRUCTURES), and the allocator 171 * itself (FREE_ALL_ALLOCATOR). Note that this requires 172 * allocators to keep track of all the memory they have ever 173 * acquired, and where they acquired it. Note that this 174 * operation propagates to the stable allocator (if 175 * different). 176 */ 177 178 #define FREE_ALL_DATA 1 179 #define FREE_ALL_STRUCTURES 2 180 #define FREE_ALL_ALLOCATOR 4 181 #define FREE_ALL_EVERYTHING\ 182 (FREE_ALL_DATA | FREE_ALL_STRUCTURES | FREE_ALL_ALLOCATOR) 183 184 #define gs_memory_t_proc_free_all(proc, mem_t)\ 185 void proc(mem_t *mem, uint free_mask, client_name_t cname) 186 187 #define gs_memory_free_all(mem, free_mask, cname)\ 188 ((mem)->procs.free_all(mem, free_mask, cname)) 189 /* Backward compatibility */ 190 #define gs_free_all(mem)\ 191 gs_memory_free_all(mem, FREE_ALL_DATA, "(free_all)") 192 193 /* 194 * Consolidate free space. This may be used as part of (or 195 * as an alternative to) garbage collection, or before 196 * giving up on an attempt to allocate. 197 */ 198 199 #define gs_memory_t_proc_consolidate_free(proc, mem_t)\ 200 void proc(mem_t *mem) 201 202 #define gs_consolidate_free(mem)\ 203 ((mem)->procs.consolidate_free(mem)) 204 205 /* Define the members of the procedure structure. */ 206 #define gs_raw_memory_procs(mem_t)\ 207 gs_memory_t_proc_alloc_bytes((*alloc_bytes_immovable), mem_t);\ 208 gs_memory_t_proc_resize_object((*resize_object), mem_t);\ 209 gs_memory_t_proc_free_object((*free_object), mem_t);\ 210 gs_memory_t_proc_stable((*stable), mem_t);\ 211 gs_memory_t_proc_status((*status), mem_t);\ 212 gs_memory_t_proc_free_all((*free_all), mem_t);\ 213 gs_memory_t_proc_consolidate_free((*consolidate_free), mem_t) 214 215 /* 216 * Define the memory manager procedural interface. 217 */ 218 typedef struct gs_memory_procs_s { 219 220 gs_raw_memory_procs(gs_memory_t); 221 222 /* Redefine inherited procedures with the new allocator type. */ 223 224 #define gs_memory_proc_alloc_bytes(proc)\ 225 gs_memory_t_proc_alloc_bytes(proc, gs_memory_t) 226 #define gs_memory_proc_resize_object(proc)\ 227 gs_memory_t_proc_resize_object(proc, gs_memory_t) 228 #define gs_memory_proc_free_object(proc)\ 229 gs_memory_t_proc_free_object(proc, gs_memory_t) 230 #define gs_memory_proc_stable(proc)\ 231 gs_memory_t_proc_stable(proc, gs_memory_t) 232 #define gs_memory_proc_status(proc)\ 233 gs_memory_t_proc_status(proc, gs_memory_t) 234 #define gs_memory_proc_free_all(proc)\ 235 gs_memory_t_proc_free_all(proc, gs_memory_t) 236 #define gs_memory_proc_consolidate_free(proc)\ 237 gs_memory_t_proc_consolidate_free(proc, gs_memory_t) 238 239 /* 240 * Allocate possibly movable bytes. (We inherit allocating immovable 241 * bytes from the raw memory allocator.) 242 */ 243 244 #define gs_alloc_bytes(mem, nbytes, cname)\ 245 (*(mem)->procs.alloc_bytes)(mem, nbytes, cname) 246 gs_memory_proc_alloc_bytes((*alloc_bytes)); 247 248 /* 249 * Allocate a structure. 250 */ 251 252 #define gs_memory_proc_alloc_struct(proc)\ 253 void *proc(gs_memory_t *mem, gs_memory_type_ptr_t pstype,\ 254 client_name_t cname) 255 #define gs_alloc_struct(mem, typ, pstype, cname)\ 256 (typ *)(*(mem)->procs.alloc_struct)(mem, pstype, cname) 257 gs_memory_proc_alloc_struct((*alloc_struct)); 258 #define gs_alloc_struct_immovable(mem, typ, pstype, cname)\ 259 (typ *)(*(mem)->procs.alloc_struct_immovable)(mem, pstype, cname) 260 gs_memory_proc_alloc_struct((*alloc_struct_immovable)); 261 262 /* 263 * Allocate an array of bytes. 264 */ 265 266 #define gs_memory_proc_alloc_byte_array(proc)\ 267 byte *proc(gs_memory_t *mem, uint num_elements, uint elt_size,\ 268 client_name_t cname) 269 #define gs_alloc_byte_array(mem, nelts, esize, cname)\ 270 (*(mem)->procs.alloc_byte_array)(mem, nelts, esize, cname) 271 gs_memory_proc_alloc_byte_array((*alloc_byte_array)); 272 #define gs_alloc_byte_array_immovable(mem, nelts, esize, cname)\ 273 (*(mem)->procs.alloc_byte_array_immovable)(mem, nelts, esize, cname) 274 gs_memory_proc_alloc_byte_array((*alloc_byte_array_immovable)); 275 276 /* 277 * Allocate an array of structures. 278 */ 279 280 #define gs_memory_proc_alloc_struct_array(proc)\ 281 void *proc(gs_memory_t *mem, uint num_elements,\ 282 gs_memory_type_ptr_t pstype, client_name_t cname) 283 #define gs_alloc_struct_array(mem, nelts, typ, pstype, cname)\ 284 (typ *)(*(mem)->procs.alloc_struct_array)(mem, nelts, pstype, cname) 285 gs_memory_proc_alloc_struct_array((*alloc_struct_array)); 286 #define gs_alloc_struct_array_immovable(mem, nelts, typ, pstype, cname)\ 287 (typ *)(*(mem)->procs.alloc_struct_array_immovable)(mem, nelts, pstype, cname) 288 gs_memory_proc_alloc_struct_array((*alloc_struct_array_immovable)); 289 290 /* 291 * Get the size of an object (anything except a string). 292 */ 293 294 #define gs_memory_proc_object_size(proc)\ 295 uint proc(gs_memory_t *mem, const void *obj) 296 #define gs_object_size(mem, obj)\ 297 (*(mem)->procs.object_size)(mem, obj) 298 gs_memory_proc_object_size((*object_size)); 299 300 /* 301 * Get the type of an object (anything except a string). 302 * The value returned for byte objects is useful only for 303 * printing. 304 */ 305 306 #define gs_memory_proc_object_type(proc)\ 307 gs_memory_type_ptr_t proc(const gs_memory_t *mem, const void *obj) 308 #define gs_object_type(mem, obj)\ 309 (*(mem)->procs.object_type)(mem, obj) 310 gs_memory_proc_object_type((*object_type)); 311 312 /* 313 * Allocate a string (unaligned bytes). 314 */ 315 316 #define gs_memory_proc_alloc_string(proc)\ 317 byte *proc(gs_memory_t *mem, uint nbytes, client_name_t cname) 318 #define gs_alloc_string(mem, nbytes, cname)\ 319 (*(mem)->procs.alloc_string)(mem, nbytes, cname) 320 gs_memory_proc_alloc_string((*alloc_string)); 321 #define gs_alloc_string_immovable(mem, nbytes, cname)\ 322 (*(mem)->procs.alloc_string_immovable)(mem, nbytes, cname) 323 gs_memory_proc_alloc_string((*alloc_string_immovable)); 324 325 /* 326 * Resize a string. The specification is the same as resize_object 327 * except that the element size is always a byte. 328 */ 329 330 #define gs_memory_proc_resize_string(proc)\ 331 byte *proc(gs_memory_t *mem, byte *data, uint old_num, uint new_num,\ 332 client_name_t cname) 333 #define gs_resize_string(mem, data, oldn, newn, cname)\ 334 (*(mem)->procs.resize_string)(mem, data, oldn, newn, cname) 335 gs_memory_proc_resize_string((*resize_string)); 336 337 /* 338 * Free a string. 339 */ 340 341 #define gs_memory_proc_free_string(proc)\ 342 void proc(gs_memory_t *mem, byte *data, uint nbytes,\ 343 client_name_t cname) 344 #define gs_free_string(mem, data, nbytes, cname)\ 345 (*(mem)->procs.free_string)(mem, data, nbytes, cname) 346 gs_memory_proc_free_string((*free_string)); 347 348 /* 349 * Register a root for the garbage collector. root = NULL 350 * asks the memory manager to allocate the root object 351 * itself (immovable, in the manager's parent): this is the usual 352 * way to call this procedure. 353 */ 354 355 #define gs_memory_proc_register_root(proc)\ 356 int proc(gs_memory_t *mem, gs_gc_root_t *root, gs_ptr_type_t ptype,\ 357 void **pp, client_name_t cname) 358 #define gs_register_root(mem, root, ptype, pp, cname)\ 359 (*(mem)->procs.register_root)(mem, root, ptype, pp, cname) 360 gs_memory_proc_register_root((*register_root)); 361 362 /* 363 * Unregister a root. The root object itself will be freed iff 364 * it was allocated by gs_register_root. 365 */ 366 367 #define gs_memory_proc_unregister_root(proc)\ 368 void proc(gs_memory_t *mem, gs_gc_root_t *root, client_name_t cname) 369 #define gs_unregister_root(mem, root, cname)\ 370 (*(mem)->procs.unregister_root)(mem, root, cname) 371 gs_memory_proc_unregister_root((*unregister_root)); 372 373 /* 374 * Enable or disable the freeing operations: when disabled, 375 * these operations return normally but do nothing. The 376 * garbage collector and the PostScript interpreter 377 * 'restore' operator need to temporarily disable the 378 * freeing functions of (an) allocator(s) while running 379 * finalization procedures. 380 */ 381 382 #define gs_memory_proc_enable_free(proc)\ 383 void proc(gs_memory_t *mem, bool enable) 384 #define gs_enable_free(mem, enable)\ 385 (*(mem)->procs.enable_free)(mem, enable) 386 gs_memory_proc_enable_free((*enable_free)); 387 388 } gs_memory_procs_t; 389 390 /* 391 * Define versions of the freeing procedures that are applicable even if the 392 * pointer is declared as const T *. These are intended for use where a 393 * structure contains a pointer member whose referent is declared as const 394 * because it is const for all ordinary clients. 395 */ 396 void gs_free_const_object(gs_memory_t *mem, const void *data, 397 client_name_t cname); 398 void gs_free_const_string(gs_memory_t *mem, const byte *data, uint nbytes, 399 client_name_t cname); 400 401 /* 402 * Free a [const] bytestring. Note that this is *not* a member procedure of 403 * the allocator: it calls the free_object or free_string procedure. 404 */ 405 void gs_free_bytestring(gs_memory_t *mem, gs_bytestring *pbs, 406 client_name_t cname); 407 void gs_free_const_bytestring(gs_memory_t *mem, gs_const_bytestring *pbs, 408 client_name_t cname); 409 410 /* 411 * Either allocate (if obj == 0) or resize (if obj != 0) a structure array. 412 * If obj != 0, pstype is used only for checking (in DEBUG configurations). 413 */ 414 void *gs_resize_struct_array(gs_memory_t *mem, void *obj, uint num_elements, 415 gs_memory_type_ptr_t pstype, 416 client_name_t cname); 417 418 /* Register a structure root. This just calls gs_register_root. */ 419 int gs_register_struct_root(gs_memory_t *mem, gs_gc_root_t *root, 420 void **pp, client_name_t cname); 421 422 /* Define no-op freeing procedures for use by enable_free. */ 423 gs_memory_proc_free_object(gs_ignore_free_object); 424 gs_memory_proc_free_string(gs_ignore_free_string); 425 426 /* Define a no-op consolidation procedure. */ 427 gs_memory_proc_consolidate_free(gs_ignore_consolidate_free); 428 429 /* 430 * Allocate a structure using a "raw memory" allocator. Note that this does 431 * not retain the identity of the structure. Note also that it returns a 432 * void *, and does not take the type of the returned pointer as a 433 * parameter. 434 */ 435 void *gs_raw_alloc_struct_immovable(gs_memory_t * rmem, 436 gs_memory_type_ptr_t pstype, 437 client_name_t cname); 438 439 typedef struct pl_mem_node_s pl_mem_node_t; 440 441 /* 442 * Define an abstract allocator instance. 443 * Subclasses may have state as well 444 * 445 * stable_memory: no save or restore, maybe gc-ed 446 * non-gc allocators stable_memory == this 447 * 448 * gs_lib_ctx: pointer to a library context 449 * 450 * non_gc_memory: a garabge collecting allocator requires a "parent" who doesn't gc 451 * non-gc allocators non_gc_memory == this 452 * 453 * thread_safe_memory: use with multiple threads must provide for a thread safe allocator 454 * that will most likely use a monitor (mutex) to serialize actions. 455 */ 456 #define gs_memory_common\ 457 gs_memory_t *stable_memory;\ 458 gs_memory_procs_t procs;\ 459 gs_lib_ctx_t *gs_lib_ctx;\ 460 gs_memory_t *non_gc_memory;\ 461 gs_memory_t *thread_safe_memory 462 463 struct gs_memory_s { 464 gs_memory_common; 465 }; 466 467 #endif /* gsmemory_INCLUDED */ 468