1 /* Copyright (C) 2001-2006 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, modified 8 or distributed except as expressly authorized under the terms of that 9 license. Refer to licensing information at http://www.artifex.com/ 10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, 11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. 12 */ 13 14 /* $Id: gsmemraw.h 8022 2007-06-05 22:23:38Z giles $ */ 15 /* Client interface for "raw memory" allocator */ 16 17 /* Initial version 02/03/1998 by John Desrosiers (soho@crl.com) */ 18 /* Completely rewritten 6/26/1998 by L. Peter Deutsch <ghost@aladdin.com> */ 19 20 #ifndef gsmemraw_INCLUDED 21 # define gsmemraw_INCLUDED 22 23 #if 0 24 25 /* gsmemraw was an abstract base class. 26 * it is no longer in use, instead use the concrete base class is gs_memory_t 27 * since gs_memory_t contains interfaces that must be availiable throughout the system 28 * is is unadvisable to have a class below it without these. 29 */ 30 31 32 /* 33 * This interface provides minimal memory allocation and freeing capability. 34 * It is meant to be used for "wholesale" allocation of blocks -- typically, 35 * but not only, via malloc -- which are then divided up into "retail" 36 * objects. However, since it is a subset (superclass) of the "retail" 37 * interface defined in gsmemory.h, retail allocators implement it as 38 * well, and in fact the malloc interface defined in gsmalloc.h is used for 39 * both wholesale and retail allocation. 40 */ 41 42 /* 43 * Define the structure for reporting memory manager statistics. 44 */ 45 typedef struct gs_memory_status_s { 46 /* 47 * "Allocated" space is the total amount of space acquired from 48 * the parent of the memory manager. It includes space used for 49 * allocated data, space available for allocation, and overhead. 50 */ 51 ulong allocated; 52 /* 53 * "Used" space is the amount of space used by allocated data 54 * plus overhead. 55 */ 56 ulong used; 57 } gs_memory_status_t; 58 59 /* Define the abstract type for the memory manager. */ 60 #ifndef gs_raw_memory_t_DEFINED 61 #define gs_raw_memory_t_DEFINED 62 typedef struct gs_raw_memory_s gs_raw_memory_t; 63 #endif 64 65 /* Define the procedures for raw memory management. Memory managers have no 66 * standard constructor: each implementation defines its own, and is 67 * responsible for calling its superclass' initialization code first. 68 * Similarly, each implementation's destructor (release) must first take 69 * care of its own cleanup and then call the superclass' release. 70 * 71 * The allocation procedures must align objects as strictly as malloc. 72 * Formerly, the procedures were required to align objects as strictly 73 * as the compiler aligned structure members. However, the ANSI C standard 74 * does not require this -- it only requires malloc to align blocks 75 * strictly enough to prevent hardware access faults. Thus, for example, 76 * on the x86, malloc need not align blocks at all. And in fact, we have 77 * found one compiler (Microsoft VC 6) that 8-byte aligns 'double' members 78 * of structures, but whose malloc only 4-byte aligns its blocks. 79 * Ghostscript allocators could enforce the stricter alignment, but the 80 * few dozen lines of code required to implement this were rejected during 81 * code review as introducing too much risk for too little payoff. As a 82 * consequence of this, 83 * 84 * CLIENTS CANNOT ASSUME THAT BLOCKS RETURNED BY ANY OF THE ALLOCATION 85 * PROCEDURES ARE ALIGNED ANY MORE STRICTLY THAN IS REQUIRED BY THE 86 * HARDWARE. 87 * 88 * In particular, clients cannot assume that blocks returned by an allocator 89 * can be processed efficiently in any unit larger than a single byte: there 90 * is no guarantee that accessing any larger quantity will not require two 91 * memory accesses at the hardware level. Clients that want to process data 92 * efficiently in larger units must use ALIGNMENT_MOD to determine the 93 * actual alignment of the data in memory. 94 */ 95 96 /* 97 * Allocate bytes. The bytes are always aligned maximally 98 * if the processor requires alignment. 99 * 100 * Note that the object memory level can allocate bytes as 101 * either movable or immovable: raw memory blocks are 102 * always immovable. 103 */ 104 105 #define gs_memory_t_proc_alloc_bytes(proc, mem_t)\ 106 byte *proc(mem_t *mem, uint nbytes, client_name_t cname) 107 108 #define gs_alloc_bytes_immovable(mem, nbytes, cname)\ 109 ((mem)->procs.alloc_bytes_immovable(mem, nbytes, cname)) 110 111 /* 112 * Resize an object to a new number of elements. At the raw 113 * memory level, the "element" is a byte; for object memory 114 * (gsmemory.h), the object may be an an array of either 115 * bytes or structures. The new size may be larger than, 116 * the same as, or smaller than the old. If the new size is 117 * the same as the old, resize_object returns the same 118 * object; otherwise, it preserves the first min(old_size, 119 * new_size) bytes of the object's contents. 120 */ 121 122 #define gs_memory_t_proc_resize_object(proc, mem_t)\ 123 void *proc(mem_t *mem, void *obj, uint new_num_elements,\ 124 client_name_t cname) 125 126 #define gs_resize_object(mem, obj, newn, cname)\ 127 ((mem)->procs.resize_object(mem, obj, newn, cname)) 128 129 /* 130 * Free an object (at the object memory level, this includes 131 * everything except strings). Note: data == 0 must be 132 * allowed, and must be a no-op. 133 */ 134 135 #define gs_memory_t_proc_free_object(proc, mem_t)\ 136 void proc(mem_t *mem, void *data, client_name_t cname) 137 138 #define gs_free_object(mem, data, cname)\ 139 ((mem)->procs.free_object(mem, data, cname)) 140 141 /* 142 * Report status (assigned, used). 143 */ 144 145 #define gs_memory_t_proc_status(proc, mem_t)\ 146 void proc(mem_t *mem, gs_memory_status_t *status) 147 148 #define gs_memory_status(mem, pst)\ 149 ((mem)->procs.status(mem, pst)) 150 151 /* 152 * Return the stable allocator for this allocator. The 153 * stable allocator allocates from the same heap and in 154 * the same VM space, but is not subject to save and restore. 155 * (It is the client's responsibility to avoid creating 156 * dangling pointers.) 157 * 158 * Note that the stable allocator may be the same allocator 159 * as this one. 160 */ 161 162 #define gs_memory_t_proc_stable(proc, mem_t)\ 163 mem_t *proc(mem_t *mem) 164 165 #define gs_memory_stable(mem)\ 166 ((mem)->procs.stable(mem)) 167 168 /* 169 * Free one or more of: data memory acquired by the allocator 170 * (FREE_ALL_DATA), overhead structures other than the 171 * allocator itself (FREE_ALL_STRUCTURES), and the allocator 172 * itself (FREE_ALL_ALLOCATOR). Note that this requires 173 * allocators to keep track of all the memory they have ever 174 * acquired, and where they acquired it. Note that this 175 * operation propagates to the stable allocator (if 176 * different). 177 */ 178 179 #define FREE_ALL_DATA 1 180 #define FREE_ALL_STRUCTURES 2 181 #define FREE_ALL_ALLOCATOR 4 182 #define FREE_ALL_EVERYTHING\ 183 (FREE_ALL_DATA | FREE_ALL_STRUCTURES | FREE_ALL_ALLOCATOR) 184 185 #define gs_memory_t_proc_free_all(proc, mem_t)\ 186 void proc(mem_t *mem, uint free_mask, client_name_t cname) 187 188 #define gs_memory_free_all(mem, free_mask, cname)\ 189 ((mem)->procs.free_all(mem, free_mask, cname)) 190 /* Backward compatibility */ 191 #define gs_free_all(mem)\ 192 gs_memory_free_all(mem, FREE_ALL_DATA, "(free_all)") 193 194 /* 195 * Consolidate free space. This may be used as part of (or 196 * as an alternative to) garbage collection, or before 197 * giving up on an attempt to allocate. 198 */ 199 200 #define gs_memory_t_proc_consolidate_free(proc, mem_t)\ 201 void proc(mem_t *mem) 202 203 #define gs_consolidate_free(mem)\ 204 ((mem)->procs.consolidate_free(mem)) 205 206 /* Define the members of the procedure structure. */ 207 #define gs_raw_memory_procs(mem_t)\ 208 gs_memory_t_proc_alloc_bytes((*alloc_bytes_immovable), mem_t);\ 209 gs_memory_t_proc_resize_object((*resize_object), mem_t);\ 210 gs_memory_t_proc_free_object((*free_object), mem_t);\ 211 gs_memory_t_proc_stable((*stable), mem_t);\ 212 gs_memory_t_proc_status((*status), mem_t);\ 213 gs_memory_t_proc_free_all((*free_all), mem_t);\ 214 gs_memory_t_proc_consolidate_free((*consolidate_free), mem_t) 215 216 /* 217 * Define an abstract raw-memory allocator instance. 218 * Subclasses may have additional state. 219 */ 220 typedef struct gs_raw_memory_procs_s { 221 gs_raw_memory_procs(gs_raw_memory_t); 222 } gs_raw_memory_procs_t; 223 224 225 226 struct gs_raw_memory_s { 227 gs_raw_memory_t *stable_memory; /* cache the stable allocator */ 228 gs_raw_memory_procs_t procs; 229 }; 230 231 #endif /* 0 */ 232 #endif /* gsmemraw_INCLUDED */ 233