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