Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/gs/src/gsmemory.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1993, 1996, 1997, 1998, 1999 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.c,v 1.9 2004/08/04 19:36:12 stefan Exp $ */
18
/* Generic allocator support */
19
#include "memory_.h"
20
#include "gdebug.h"
21
#include "gstypes.h"
22
#include "gsmemory.h"
23
#include "gsmdebug.h"
24
#include "gsrefct.h"		/* to check prototype */
25
#include "gsstruct.h"		/* ditto */
26
 
27
/* Define the fill patterns for unallocated memory. */
28
const byte gs_alloc_fill_alloc = 0xa1;
29
const byte gs_alloc_fill_block = 0xb1;
30
const byte gs_alloc_fill_collected = 0xc1;
31
const byte gs_alloc_fill_deleted = 0xd1;
32
const byte gs_alloc_fill_free = 0xf1;
33
 
34
/* A 'structure' type descriptor for free blocks. */
35
gs_public_st_simple(st_free, byte, "(free)");
36
 
37
/* The 'structure' type descriptor for bytes. */
38
gs_public_st_simple(st_bytes, byte, "bytes");
39
 
40
/* The structure type descriptor for GC roots. */
41
public_st_gc_root_t();
42
 
43
/* The descriptors for elements and arrays of const strings. */
44
private_st_const_string();
45
public_st_const_string_element();
46
 
47
/* GC procedures for bytestrings */
48
gs_ptr_type_t
49
enum_bytestring(enum_ptr_t *pep, const gs_bytestring *pbs)
50
{
51
    return (pbs->bytes ? ENUM_OBJ(pbs->bytes) : ENUM_STRING(pbs));
52
}
53
gs_ptr_type_t
54
enum_const_bytestring(enum_ptr_t *pep, const gs_const_bytestring *pbs)
55
{
56
    return (pbs->bytes ? ENUM_OBJ(pbs->bytes) : ENUM_CONST_STRING(pbs));
57
}
58
void
59
reloc_bytestring(gs_bytestring *pbs, gc_state_t *gcst)
60
{
61
    if (pbs->bytes) {
62
	byte *bytes = pbs->bytes;
63
	long offset = pbs->data - bytes;
64
 
65
	pbs->bytes = bytes = RELOC_OBJ(bytes);
66
	pbs->data = bytes + offset;
67
    } else
68
	RELOC_STRING_VAR(*(gs_string *)pbs);
69
}
70
void
71
reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst)
72
{
73
    if (pbs->bytes) {
74
	const byte *bytes = pbs->bytes;
75
	long offset = pbs->data - bytes;
76
 
77
	pbs->bytes = bytes = RELOC_OBJ(bytes);
78
	pbs->data = bytes + offset;
79
    } else
80
	RELOC_CONST_STRING_VAR(*(gs_const_string *)pbs);
81
}
82
 
83
/* Fill an unoccupied block with a pattern. */
84
/* Note that the block size may be too large for a single memset. */
85
void
86
gs_alloc_memset(void *ptr, int /*byte */ fill, ulong lsize)
87
{
88
    ulong msize = lsize;
89
    char *p = ptr;
90
    int isize;
91
 
92
    for (; msize; msize -= isize, p += isize) {
93
	isize = min(msize, max_int);
94
	memset(p, fill, isize);
95
    }
96
}
97
 
98
/*
99
 * Either allocate (if obj == 0) or resize (if obj != 0) a structure array.
100
 * If obj != 0, pstype is used only for checking (in DEBUG configurations).
101
 */
102
void *
103
gs_resize_struct_array(gs_memory_t *mem, void *obj, uint num_elements,
104
		       gs_memory_type_ptr_t pstype, client_name_t cname)
105
{
106
    if (obj == 0)
107
	return gs_alloc_struct_array(mem, num_elements, void, pstype, cname);
108
#ifdef DEBUG
109
    if (gs_object_type(mem, obj) != pstype) {
110
	lprintf3("resize_struct_array 0x%lx, type was 0x%lx, expected 0x%lx!\n",
111
		 (ulong)obj, (ulong)gs_object_type(mem, obj), (ulong)pstype);
112
	return 0;
113
    }
114
#endif
115
    return gs_resize_object(mem, obj, num_elements, cname);
116
}
117
 
118
 
119
/* Allocate a structure using a "raw memory" allocator.
120
 * really just an alias for gs_alloc_struct_immovable 
121
 * with the clients false expectation that it is saving memory   
122
 */
123
 
124
void *
125
gs_raw_alloc_struct_immovable(gs_memory_t * rmem,
126
			      gs_memory_type_ptr_t pstype,
127
			      client_name_t cname)
128
{
129
    return gs_alloc_bytes_immovable(rmem, gs_struct_type_size(pstype), cname);
130
}
131
 
132
/* No-op freeing procedures */
133
void
134
gs_ignore_free_object(gs_memory_t * mem, void *data, client_name_t cname)
135
{
136
}
137
void
138
gs_ignore_free_string(gs_memory_t * mem, byte * data, uint nbytes,
139
		      client_name_t cname)
140
{
141
}
142
 
143
/* Deconstifying freeing procedures. */
144
/* These procedures rely on a severely deprecated pun. */
145
void
146
gs_free_const_object(gs_memory_t * mem, const void *data, client_name_t cname)
147
{
148
    union { const void *r; void *w; } u;
149
 
150
    u.r = data;
151
    gs_free_object(mem, u.w, cname);
152
}
153
void
154
gs_free_const_string(gs_memory_t * mem, const byte * data, uint nbytes,
155
		     client_name_t cname)
156
{
157
    union { const byte *r; byte *w; } u;
158
 
159
    u.r = data;
160
    gs_free_string(mem, u.w, nbytes, cname);
161
}
162
 
163
/* Free a [const] bytestring. */
164
void
165
gs_free_bytestring(gs_memory_t *mem, gs_bytestring *pbs, client_name_t cname)
166
{
167
    if (pbs->bytes)
168
	gs_free_object(mem, pbs->bytes, cname);
169
    else
170
	gs_free_string(mem, pbs->data, pbs->size, cname);
171
}
172
void
173
gs_free_const_bytestring(gs_memory_t *mem, gs_const_bytestring *pbs,
174
			 client_name_t cname)
175
{
176
    if (pbs->bytes)
177
	gs_free_const_object(mem, pbs->bytes, cname);
178
    else
179
	gs_free_const_string(mem, pbs->data, pbs->size, cname);
180
}
181
 
182
/* No-op consolidation procedure */
183
void
184
gs_ignore_consolidate_free(gs_memory_t *mem)
185
{
186
}
187
 
188
/* No-op pointer enumeration procedure */
189
ENUM_PTRS_BEGIN_PROC(gs_no_struct_enum_ptrs)
190
{
191
    return 0;
192
    ENUM_PTRS_END_PROC
193
}
194
 
195
/* No-op pointer relocation procedure */
196
RELOC_PTRS_BEGIN(gs_no_struct_reloc_ptrs)
197
{
198
}
199
RELOC_PTRS_END
200
 
201
/* Get the size of a structure from the descriptor. */
202
uint
203
gs_struct_type_size(gs_memory_type_ptr_t pstype)
204
{
205
    return pstype->ssize;
206
}
207
 
208
/* Get the name of a structure from the descriptor. */
209
struct_name_t
210
gs_struct_type_name(gs_memory_type_ptr_t pstype)
211
{
212
    return pstype->sname;
213
}
214
 
215
/* Register a structure root. */
216
int
217
gs_register_struct_root(gs_memory_t *mem, gs_gc_root_t *root,
218
			void **pp, client_name_t cname)
219
{
220
    return gs_register_root(mem, root, ptr_struct_type, pp, cname);
221
}
222
 
223
/* ---------------- Reference counting ---------------- */
224
 
225
#ifdef DEBUG
226
 
227
private const char *
228
rc_object_type_name(const void *vp, const rc_header *prc)
229
{
230
    gs_memory_type_ptr_t pstype;
231
 
232
    if (prc->memory == 0)
233
	return "(unknown)";
234
    pstype = gs_object_type(prc->memory, vp);
235
    if (prc->free != rc_free_struct_only) {
236
	/*
237
	 * This object might be stack-allocated or have other unusual memory
238
	 * management properties.  Make some reasonableness checks.
239
	 * ****** THIS IS A HACK. ******
240
	 */
241
	long dist;
242
 
243
	dist = (const char *)&dist - (const char *)vp;
244
	if (dist < 10000 && dist > -10000)
245
	    return "(on stack)";
246
	if ((ulong)pstype < 0x10000 || (long)pstype < 0)
247
	    return "(anomalous)";
248
    }
249
    return client_name_string(gs_struct_type_name(pstype));
250
}
251
 
252
/* Trace reference count operations. */
253
void
254
rc_trace_init_free(const void *vp, const rc_header *prc)
255
{
256
    dprintf3("[^]%s 0x%lx init = %ld\n",
257
	     rc_object_type_name(vp, prc), (ulong)vp, (long)prc->ref_count);
258
}
259
void
260
rc_trace_free_struct(const void *vp, const rc_header *prc, client_name_t cname)
261
{
262
    dprintf3("[^]%s 0x%lx => free (%s)\n",
263
	      rc_object_type_name(vp, prc),
264
	      (ulong)vp, client_name_string(cname));
265
}
266
void
267
rc_trace_increment(const void *vp, const rc_header *prc)
268
{
269
    dprintf3("[^]%s 0x%lx ++ => %ld\n",
270
	      rc_object_type_name(vp, prc),
271
	      (ulong)vp, (long)prc->ref_count);
272
}
273
void
274
rc_trace_adjust(const void *vp, const rc_header *prc, int delta)
275
{
276
    dprintf4("[^]%s 0x%lx %+d => %ld\n",
277
	     rc_object_type_name(vp, prc),
278
	     (ulong)vp, delta, (long)(prc->ref_count + delta));
279
}
280
 
281
#endif /* DEBUG */
282
 
283
/* Normal freeing routine for reference-counted structures. */
284
void
285
rc_free_struct_only(gs_memory_t * mem, void *data, client_name_t cname)
286
{
287
    if (mem != 0)
288
	gs_free_object(mem, data, cname);
289
}
290
 
291
/* ---------------- Basic-structure GC procedures ---------------- */
292
 
293
/* Enumerate pointers */
294
ENUM_PTRS_BEGIN_PROC(basic_enum_ptrs)
295
{
296
    const gc_struct_data_t *psd = pstype->proc_data;
297
 
298
    /* This check is primarily for misuse of the alloc_struct_array */
299
    /* with number of elements 0 and allocation not passing 'element' */
300
    if (size == 0) {
301
#ifdef DEBUG
302
	dprintf2("  basic_enum_ptrs: Attempt to enum 0 size structure at 0x%lx, type: %s\n",
303
		vptr, pstype->sname);
304
#endif
305
	return 0;
306
    }
307
    if (index < psd->num_ptrs) {
308
	const gc_ptr_element_t *ppe = &psd->ptrs[index];
309
	EV_CONST char *pptr = (EV_CONST char *)vptr + ppe->offset;
310
 
311
#ifdef DEBUG
312
	/* some extra checking to make sure we aren't out of bounds */
313
	if (ppe->offset > size - sizeof(void *)) {
314
	    dprintf4("  basic_enum_ptrs: Attempt to enum ptr with offset=%d beyond size=%d: structure at 0x%lx, type: %s\n",
315
		    ppe->offset, size, vptr, pstype->sname);
316
	    return 0;
317
	}
318
#endif
319
	switch ((gc_ptr_type_index_t)ppe->type) {
320
	    case GC_ELT_OBJ:
321
		return ENUM_OBJ(*(const void *EV_CONST *)pptr);
322
	    case GC_ELT_STRING:
323
		return ENUM_STRING((const gs_string *)pptr);
324
	    case GC_ELT_CONST_STRING:
325
		return ENUM_CONST_STRING((const gs_const_string *)pptr);
326
	}
327
    }
328
    if (!psd->super_type)
329
	return 0;
330
    return ENUM_USING(*(psd->super_type),
331
		      (EV_CONST void *)
332
		        ((EV_CONST char *)vptr + psd->super_offset),
333
		      pstype->ssize, index - psd->num_ptrs);
334
}
335
ENUM_PTRS_END_PROC
336
 
337
/* Relocate pointers */
338
RELOC_PTRS_BEGIN(basic_reloc_ptrs)
339
{
340
    const gc_struct_data_t *psd = pstype->proc_data;
341
    uint i;
342
 
343
    for (i = 0; i < psd->num_ptrs; ++i) {
344
	const gc_ptr_element_t *ppe = &psd->ptrs[i];
345
	char *pptr = (char *)vptr + ppe->offset;
346
 
347
	switch ((gc_ptr_type_index_t) ppe->type) {
348
	    case GC_ELT_OBJ:
349
		RELOC_OBJ_VAR(*(void **)pptr);
350
		break;
351
	    case GC_ELT_STRING:
352
		RELOC_STRING_VAR(*(gs_string *)pptr);
353
		break;
354
	    case GC_ELT_CONST_STRING:
355
		RELOC_CONST_STRING_VAR(*(gs_const_string *)pptr);
356
		break;
357
	}
358
    }
359
    if (psd->super_type)
360
	RELOC_USING(*(psd->super_type),
361
		      (void *)((char *)vptr + psd->super_offset),
362
		      pstype->ssize);
363
} RELOC_PTRS_END