1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
14
/* $Id: gsmemraw.h 8022 2007-06-05 22:23:38Z giles $ */
15
/* Client interface for "raw memory" allocator */
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> */
20
#ifndef gsmemraw_INCLUDED
21
# define gsmemraw_INCLUDED
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.
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.
43
* Define the structure for reporting memory manager statistics.
45
typedef struct gs_memory_status_s {
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.
53
* "Used" space is the amount of space used by allocated data
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;
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.
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,
84
* CLIENTS CANNOT ASSUME THAT BLOCKS RETURNED BY ANY OF THE ALLOCATION
85
* PROCEDURES ARE ALIGNED ANY MORE STRICTLY THAN IS REQUIRED BY THE
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.
97
* Allocate bytes. The bytes are always aligned maximally
98
* if the processor requires alignment.
100
* Note that the object memory level can allocate bytes as
101
* either movable or immovable: raw memory blocks are
105
#define gs_memory_t_proc_alloc_bytes(proc, mem_t)\
106
byte *proc(mem_t *mem, uint nbytes, client_name_t cname)
108
#define gs_alloc_bytes_immovable(mem, nbytes, cname)\
109
((mem)->procs.alloc_bytes_immovable(mem, nbytes, cname))
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.
122
#define gs_memory_t_proc_resize_object(proc, mem_t)\
123
void *proc(mem_t *mem, void *obj, uint new_num_elements,\
126
#define gs_resize_object(mem, obj, newn, cname)\
127
((mem)->procs.resize_object(mem, obj, newn, cname))
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.
135
#define gs_memory_t_proc_free_object(proc, mem_t)\
136
void proc(mem_t *mem, void *data, client_name_t cname)
138
#define gs_free_object(mem, data, cname)\
139
((mem)->procs.free_object(mem, data, cname))
142
* Report status (assigned, used).
145
#define gs_memory_t_proc_status(proc, mem_t)\
146
void proc(mem_t *mem, gs_memory_status_t *status)
148
#define gs_memory_status(mem, pst)\
149
((mem)->procs.status(mem, pst))
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.)
158
* Note that the stable allocator may be the same allocator
162
#define gs_memory_t_proc_stable(proc, mem_t)\
163
mem_t *proc(mem_t *mem)
165
#define gs_memory_stable(mem)\
166
((mem)->procs.stable(mem))
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
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)
185
#define gs_memory_t_proc_free_all(proc, mem_t)\
186
void proc(mem_t *mem, uint free_mask, client_name_t cname)
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)")
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.
200
#define gs_memory_t_proc_consolidate_free(proc, mem_t)\
201
void proc(mem_t *mem)
203
#define gs_consolidate_free(mem)\
204
((mem)->procs.consolidate_free(mem))
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)
217
* Define an abstract raw-memory allocator instance.
218
* Subclasses may have additional state.
220
typedef struct gs_raw_memory_procs_s {
221
gs_raw_memory_procs(gs_raw_memory_t);
222
} gs_raw_memory_procs_t;
226
struct gs_raw_memory_s {
227
gs_raw_memory_t *stable_memory; /* cache the stable allocator */
228
gs_raw_memory_procs_t procs;
232
#endif /* gsmemraw_INCLUDED */