summaryrefslogtreecommitdiff
path: root/gs/src/gsalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/gsalloc.c')
-rw-r--r--gs/src/gsalloc.c272
1 files changed, 175 insertions, 97 deletions
diff --git a/gs/src/gsalloc.c b/gs/src/gsalloc.c
index 915cbe4c3..ee1dea4b0 100644
--- a/gs/src/gsalloc.c
+++ b/gs/src/gsalloc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -16,13 +16,14 @@
all copies.
*/
-/* gsalloc.c */
+/*Id: gsalloc.c */
/* Standard memory allocator */
#include "gx.h"
#include "memory_.h"
#include "gsmdebug.h"
#include "gsstruct.h"
#include "gxalloc.h"
+#include "stream.h" /* for clearing stream list */
/*
* This allocator produces tracing messages of the form
@@ -35,22 +36,53 @@
* S is {freelist = F, LIFO = space, own chunk = L, lost = #,
* lost own chunk = ~, other = .}.
*/
+#ifdef DEBUG
+private void
+alloc_trace(const char *chars, gs_ref_memory_t * imem, client_name_t cname,
+ gs_memory_type_ptr_t stype, uint size, const void *ptr)
+{
+ if_debug7('A', "[a%d%s]%s %s(%u) %s0x%lx\n",
+ imem->space, chars, client_name_string(cname),
+ (ptr == 0 || stype == 0 ? "" :
+ struct_type_name_string(stype)),
+ size, (chars[1] == '+' ? "= " : ""), (ulong) ptr);
+}
+private bool
+alloc_size_is_ok(gs_memory_type_ptr_t stype)
+{
+ return (stype->ssize > 0 && stype->ssize < 0x100000);
+}
+# define ALLOC_CHECK_SIZE(stype)\
+ BEGIN\
+ if (!alloc_size_is_ok(stype)) {\
+ lprintf2("size of struct type 0x%lx is 0x%lx!\n",\
+ (ulong)(stype), (ulong)((stype)->ssize));\
+ return 0;\
+ }\
+ END
+#else
+# define alloc_trace(chars, imem, cname, stype, size, ptr) DO_NOTHING
+# define ALLOC_CHECK_SIZE(stype) DO_NOTHING
+#endif
-/* The structure descriptor for allocators. Even though allocators */
-/* are allocated outside GC space, they reference objects within it. */
+/*
+ * The structure descriptor for allocators. Even though allocators
+ * are allocated outside GC space, they reference objects within it.
+ */
public_st_ref_memory();
#define mptr ((gs_ref_memory_t *)vptr)
private
ENUM_PTRS_BEGIN(ref_memory_enum_ptrs) return 0;
-ENUM_PTR(0, gs_ref_memory_t, changes);
-ENUM_PTR(1, gs_ref_memory_t, saved);
+ENUM_PTR3(0, gs_ref_memory_t, streams, changes, saved);
ENUM_PTRS_END
private RELOC_PTRS_BEGIN(ref_memory_reloc_ptrs)
{
+ RELOC_PTR(gs_ref_memory_t, streams);
RELOC_PTR(gs_ref_memory_t, changes);
- /* Don't relocate the pointer now -- see igc.c for details. */
- mptr->reloc_saved = gs_reloc_struct_ptr(mptr->saved, gcst);
+ /* Don't relocate the saved pointer now -- see igc.c for details. */
+ mptr->reloc_saved =
+ (*gc_proc(gcst, reloc_struct_ptr)) (mptr->saved, gcst);
}
RELOC_PTRS_END
@@ -66,49 +98,56 @@ void alloc_close_chunk(P1(gs_ref_memory_t *));
* Define the standard implementation (with garbage collection)
* of Ghostscript's memory manager interface.
*/
-private gs_memory_proc_alloc_bytes(i_alloc_bytes);
+/* Raw memory procedures */
private gs_memory_proc_alloc_bytes(i_alloc_bytes_immovable);
+private gs_memory_proc_resize_object(i_resize_object);
+private gs_memory_proc_free_object(i_free_object);
+private gs_memory_proc_status(i_status);
+private gs_memory_proc_free_all(i_free_all);
+
+/* Object memory procedures */
+private gs_memory_proc_alloc_bytes(i_alloc_bytes);
private gs_memory_proc_alloc_struct(i_alloc_struct);
private gs_memory_proc_alloc_struct(i_alloc_struct_immovable);
private gs_memory_proc_alloc_byte_array(i_alloc_byte_array);
private gs_memory_proc_alloc_byte_array(i_alloc_byte_array_immovable);
private gs_memory_proc_alloc_struct_array(i_alloc_struct_array);
private gs_memory_proc_alloc_struct_array(i_alloc_struct_array_immovable);
-private gs_memory_proc_resize_object(i_resize_object);
private gs_memory_proc_object_size(i_object_size);
private gs_memory_proc_object_type(i_object_type);
-private gs_memory_proc_free_object(i_free_object);
private gs_memory_proc_alloc_string(i_alloc_string);
private gs_memory_proc_alloc_string(i_alloc_string_immovable);
private gs_memory_proc_resize_string(i_resize_string);
private gs_memory_proc_free_string(i_free_string);
private gs_memory_proc_register_root(i_register_root);
private gs_memory_proc_unregister_root(i_unregister_root);
-private gs_memory_proc_status(i_status);
private gs_memory_proc_enable_free(i_enable_free);
/* We export the procedures for subclasses. */
const gs_memory_procs_t gs_ref_memory_procs =
{
- i_alloc_bytes,
+ /* Raw memory procedures */
i_alloc_bytes_immovable,
+ i_resize_object,
+ i_free_object,
+ i_status,
+ i_free_all,
+ /* Object memory procedures */
+ i_alloc_bytes,
i_alloc_struct,
i_alloc_struct_immovable,
i_alloc_byte_array,
i_alloc_byte_array_immovable,
i_alloc_struct_array,
i_alloc_struct_array_immovable,
- i_resize_object,
i_object_size,
i_object_type,
- i_free_object,
i_alloc_string,
i_alloc_string_immovable,
i_resize_string,
i_free_string,
i_register_root,
i_unregister_root,
- i_status,
i_enable_free
};
@@ -116,9 +155,10 @@ const gs_memory_procs_t gs_ref_memory_procs =
* Allocate and mostly initialize the state of an allocator (system, global,
* or local). Does not initialize global or space.
*/
-private void *ialloc_solo(P3(gs_memory_t *, gs_memory_type_ptr_t, chunk_t **));
+private void *ialloc_solo(P3(gs_raw_memory_t *, gs_memory_type_ptr_t,
+ chunk_t **));
gs_ref_memory_t *
-ialloc_alloc_state(gs_memory_t * parent, uint chunk_size)
+ialloc_alloc_state(gs_raw_memory_t * parent, uint chunk_size)
{
chunk_t *cp;
gs_ref_memory_t *iimem = ialloc_solo(parent, &st_ref_memory, &cp);
@@ -140,25 +180,29 @@ ialloc_alloc_state(gs_memory_t * parent, uint chunk_size)
ialloc_set_limit(iimem);
iimem->cc.cbot = iimem->cc.ctop = 0;
iimem->pcc = 0;
+ iimem->streams = 0;
iimem->roots = 0;
- iimem->num_contexts = 1;
+ iimem->num_contexts = 0;
iimem->saved = 0;
return iimem;
}
+
/* Allocate a 'solo' object with its own chunk. */
private void *
-ialloc_solo(gs_memory_t * parent, gs_memory_type_ptr_t pstype, chunk_t ** pcp)
-{ /*
- * We can't assume that the parent uses the same object header
- * that we do, but the GC requires that allocators have
- * such a header. Therefore, we prepend one explicitly.
- */
- chunk_t *cp = gs_alloc_struct_immovable(parent, chunk_t, &st_chunk,
- "ialloc_solo(chunk)");
+ialloc_solo(gs_raw_memory_t * parent, gs_memory_type_ptr_t pstype,
+ chunk_t ** pcp)
+{ /*
+ * We can't assume that the parent uses the same object header
+ * that we do, but the GC requires that allocators have
+ * such a header. Therefore, we prepend one explicitly.
+ */
+ chunk_t *cp =
+ gs_raw_alloc_struct_immovable(parent, &st_chunk,
+ "ialloc_solo(chunk)");
uint csize =
- round_up(sizeof(chunk_head_t) + sizeof(obj_header_t) +
- pstype->ssize,
- obj_align_mod);
+ round_up(sizeof(chunk_head_t) + sizeof(obj_header_t) +
+ pstype->ssize,
+ obj_align_mod);
byte *cdata = gs_alloc_bytes_immovable(parent, csize, "ialloc_solo");
obj_header_t *obj = (obj_header_t *) (cdata + sizeof(chunk_head_t));
@@ -174,6 +218,23 @@ ialloc_solo(gs_memory_t * parent, gs_memory_type_ptr_t pstype, chunk_t ** pcp)
*pcp = cp;
return (void *)(obj + 1);
}
+
+/* Prepare for a GC by clearing the stream list. */
+/* This probably belongs somewhere else.... */
+void
+ialloc_gc_prepare(gs_ref_memory_t * mem)
+{ /*
+ * We have to unlink every stream from its neighbors,
+ * so that referenced streams don't keep all streams around.
+ */
+ while (mem->streams != 0) {
+ stream *s = mem->streams;
+
+ mem->streams = s->next;
+ s->prev = s->next = 0;
+ }
+}
+
/* Initialize after a save. */
void
ialloc_reset(gs_ref_memory_t * mem)
@@ -188,6 +249,7 @@ ialloc_reset(gs_ref_memory_t * mem)
mem->changes = 0;
ialloc_reset_free(mem);
}
+
/* Initialize after a save or GC. */
void
ialloc_reset_free(gs_ref_memory_t * mem)
@@ -202,6 +264,7 @@ ialloc_reset_free(gs_ref_memory_t * mem)
for (i = 0, p = &mem->freelists[0]; i < num_freelists; i++, p++)
*p = 0;
}
+
/* Set the allocation limit after a change in one or more of */
/* vm_threshold, max_vm, or enabled, or after a GC. */
void
@@ -236,6 +299,28 @@ ialloc_set_limit(register gs_ref_memory_t * mem)
(long)mem->gc_status.vm_threshold, (long)mem->limit);
}
+/*
+ * Free all the memory owned by the allocator, except the allocator itself.
+ * Note that this only frees memory at the current save level: the client
+ * is responsible for restoring to the outermost level if desired.
+ */
+private void
+i_free_all(gs_memory_t * mem)
+{
+ chunk_t *cp;
+ chunk_t *csucc;
+
+ /*
+ * Free the chunks in reverse order, to encourage LIFO behavior.
+ * Don't free the chunk holding the allocator itself!
+ */
+ for (cp = imem->clast; cp != 0; cp = csucc) {
+ csucc = cp->cprev; /* save before freeing */
+ if (cp->cbase + sizeof(obj_header_t) != (byte *) mem)
+ alloc_free_chunk(cp, imem);
+ }
+}
+
/* ================ Accessors ================ */
/* Get the size of an object from the header. */
@@ -309,21 +394,15 @@ i_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname)
obj_header_t **pfl;
IF_FREELIST_ALLOC(obj, imem, size, &st_bytes, pfl)
- if_debug4('A', "[a%d:+bF]%s -bytes-(%u) = 0x%lx\n",
- imem->space,
- client_name_string(cname), size, (ulong) obj);
+ alloc_trace(":+bF", imem, cname, NULL, size, obj);
ELSEIF_LIFO_ALLOC(obj, imem, size, &st_bytes)
- if_debug4('A', "[a%d:+b ]%s -bytes-(%u) = 0x%lx\n",
- imem->space,
- client_name_string(cname), size, (ulong) obj);
+ alloc_trace(":+b ", imem, cname, NULL, size, obj);
ELSE_ALLOC
{
obj = alloc_obj(imem, size, &st_bytes, false, cname);
if (obj == 0)
return 0;
- if_debug4('A', "[a%d:+b.]%s -bytes-(%u) = 0x%lx\n",
- imem->space,
- client_name_string(cname), size, (ulong) obj);
+ alloc_trace(":+b.", imem, cname, NULL, size, obj);
}
return (byte *) obj;
}
@@ -334,8 +413,7 @@ i_alloc_bytes_immovable(gs_memory_t * mem, uint size, client_name_t cname)
if (obj == 0)
return 0;
- if_debug4('A', "[a%d|+b.]%s -bytes-(%u) = 0x%lx\n",
- imem->space, client_name_string(cname), size, (ulong) obj);
+ alloc_trace("|+b.", imem, cname, NULL, size, obj);
return (byte *) obj;
}
private void *
@@ -346,22 +424,17 @@ i_alloc_struct(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
obj_header_t *obj;
obj_header_t **pfl;
+ ALLOC_CHECK_SIZE(pstype);
IF_FREELIST_ALLOC(obj, imem, size, pstype, pfl)
- if_debug5('A', "[a%d:+<F]%s %s(%u) = 0x%lx\n",
- imem->space, client_name_string(cname),
- struct_type_name_string(pstype), size, (ulong) obj);
+ alloc_trace(":+<F", imem, cname, pstype, size, obj);
ELSEIF_LIFO_ALLOC(obj, imem, size, pstype)
- if_debug5('A', "[a%d:+< ]%s %s(%u) = 0x%lx\n",
- imem->space, client_name_string(cname),
- struct_type_name_string(pstype), size, (ulong) obj);
+ alloc_trace(":+< ", imem, cname, pstype, size, obj);
ELSE_ALLOC
{
obj = alloc_obj(imem, size, pstype, false, cname);
if (obj == 0)
return 0;
- if_debug5('A', "[a%d:+<.]%s %s(%u) = 0x%lx\n",
- imem->space, client_name_string(cname),
- struct_type_name_string(pstype), size, (ulong) obj);
+ alloc_trace(":+<.", imem, cname, pstype, size, obj);
}
return obj;
}
@@ -370,13 +443,11 @@ i_alloc_struct_immovable(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
client_name_t cname)
{
uint size = pstype->ssize;
- obj_header_t *obj = alloc_obj(imem, size, pstype, true, cname);
+ obj_header_t *obj;
- if (obj == 0)
- return 0;
- if_debug5('A', "[a%d|+<.]%s %s(%u) = 0x%lx\n",
- imem->space, client_name_string(cname),
- struct_type_name_string(pstype), size, (ulong) obj);
+ ALLOC_CHECK_SIZE(pstype);
+ obj = alloc_obj(imem, size, pstype, true, cname);
+ alloc_trace("|+<.", imem, cname, pstype, size, obj);
return obj;
}
private byte *
@@ -409,10 +480,12 @@ private void *
i_alloc_struct_array(gs_memory_t * mem, uint num_elements,
gs_memory_type_ptr_t pstype, client_name_t cname)
{
- obj_header_t *obj = alloc_obj(imem,
- (ulong) num_elements * pstype->ssize,
- pstype, false, cname);
+ obj_header_t *obj;
+ ALLOC_CHECK_SIZE(pstype);
+ obj = alloc_obj(imem,
+ (ulong) num_elements * pstype->ssize,
+ pstype, false, cname);
if_debug7('A', "[a%d:+<.]%s %s*(%lu=%u*%u) = 0x%lx\n",
imem->space,
client_name_string(cname), struct_type_name_string(pstype),
@@ -424,10 +497,12 @@ private void *
i_alloc_struct_array_immovable(gs_memory_t * mem, uint num_elements,
gs_memory_type_ptr_t pstype, client_name_t cname)
{
- obj_header_t *obj = alloc_obj(imem,
- (ulong) num_elements * pstype->ssize,
- pstype, true, cname);
+ obj_header_t *obj;
+ ALLOC_CHECK_SIZE(pstype);
+ obj = alloc_obj(imem,
+ (ulong) num_elements * pstype->ssize,
+ pstype, true, cname);
if_debug7('A', "[a%d|+<.]%s %s*(%lu=%u*%u) = 0x%lx\n",
imem->space,
client_name_string(cname), struct_type_name_string(pstype),
@@ -472,6 +547,7 @@ private void
i_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
{
obj_header_t *pp;
+ gs_memory_type_ptr_t pstype;
struct_proc_finalize((*finalize));
uint size;
@@ -479,11 +555,12 @@ i_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
if (ptr == 0)
return;
pp = (obj_header_t *) ptr - 1;
+ pstype = pp->o_type;
#ifdef DEBUG
if (gs_debug_c('?')) {
chunk_locator_t cld;
- if (pp->o_type == &st_free) {
+ if (pstype == &st_free) {
lprintf2("%s: object 0x%lx already free!\n",
client_name_string(cname), (ulong) ptr);
return; /*gs_abort(); */
@@ -518,16 +595,15 @@ i_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
}
#endif
size = pre_obj_contents_size(pp);
- finalize = pp->o_type->finalize;
+ finalize = pstype->finalize;
if (finalize != 0) {
if_debug3('u', "[u]finalizing %s 0x%lx (%s)\n",
- struct_type_name_string(pp->o_type),
+ struct_type_name_string(pstype),
(ulong) ptr, client_name_string(cname));
(*finalize) (ptr);
}
if ((byte *) ptr + obj_align_round(size) == imem->cc.cbot) {
- if_debug4('A', "[a%d:-o ]%s(%u) 0x%lx\n", imem->space,
- client_name_string(cname), size, (ulong) ptr);
+ alloc_trace(":-o ", imem, cname, pstype, size, ptr);
gs_alloc_fill(ptr, gs_alloc_fill_free, size);
imem->cc.cbot = (byte *) pp;
return;
@@ -545,9 +621,10 @@ i_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
cld.memory = imem;
cld.cp = 0;
- if_debug5('a', "[a%d:-o%c]%s(%u) 0x%lx\n", imem->space,
- (chunk_locate_ptr(ptr, &cld) ? 'L' : '~'),
- client_name_string(cname), size, (ulong) ptr);
+ if (gs_debug_c('a'))
+ alloc_trace(
+ (chunk_locate_ptr(ptr, &cld) ? ":-oL" : ":-o~"),
+ imem, cname, pstype, size, ptr);
}
#endif
cl.memory = imem;
@@ -575,9 +652,7 @@ i_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
gs_alloc_fill(ptr, gs_alloc_fill_free, size);
*(obj_header_t **) ptr = *pfl;
*pfl = (obj_header_t *) ptr;
- if_debug4('A', "[a%d:-oF]%s(%u) 0x%lx\n",
- imem->space, client_name_string(cname),
- size, (ulong) ptr);
+ alloc_trace(":-oF", imem, cname, pstype, size, ptr);
return;
}
/* Don't overwrite even if gs_alloc_debug is set. */
@@ -585,8 +660,7 @@ i_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
pp->o_type = &st_free; /* don't confuse GC */
gs_alloc_fill(ptr, gs_alloc_fill_free, size);
}
- if_debug4('A', "[a%d:-o#]%s(%u) 0x%lx\n", imem->space,
- client_name_string(cname), size, (ulong) ptr);
+ alloc_trace(":-o#", imem, cname, pstype, size, ptr);
imem->lost.objects += obj_size_round(size);
}
private byte *
@@ -690,6 +764,7 @@ i_free_string(gs_memory_t * mem, byte * data, uint nbytes,
}
gs_alloc_fill(data, gs_alloc_fill_free, nbytes);
}
+
private void
i_status(gs_memory_t * mem, gs_memory_status_t * pstat)
{
@@ -809,6 +884,15 @@ private void
i_register_root(gs_memory_t * mem, gs_gc_root_t * rp, gs_ptr_type_t ptype,
void **up, client_name_t cname)
{
+ if (rp == NULL) {
+ rp = gs_raw_alloc_struct_immovable(imem->parent, &st_gc_root_t,
+ "i_register_root");
+ if (rp == 0) {
+ lprintf1("Unable to allocate root for %s!\n",
+ client_name_string(cname));
+ return; /*gs_abort(); */
+ }
+ }
if_debug3('8', "[8]register root(%s) 0x%lx -> 0x%lx\n",
client_name_string(cname), (ulong) rp, (ulong) up);
rp->ptype = ptype, rp->p = up;
@@ -871,15 +955,14 @@ private chunk_t *
alloc_add_chunk(gs_ref_memory_t * mem, ulong csize, bool has_strings,
client_name_t cname)
{
- gs_memory_t *parent = mem->parent;
- chunk_t *cp = gs_alloc_struct_immovable(parent, chunk_t, &st_chunk,
- cname);
+ gs_raw_memory_t *parent = mem->parent;
+ chunk_t *cp =
+ gs_raw_alloc_struct_immovable(parent, &st_chunk, cname);
byte *cdata;
- /* If csize is larger than max_uint, */
- /* we have to fake it using gs_alloc_byte_array. */
- ulong elt_size = csize;
- uint num_elts = 1;
+ /* If csize is larger than max_uint, punt. */
+ if (csize != (uint) csize)
+ return 0;
if ((ulong) (mem->allocated + mem->inherited) >= mem->limit) {
mem->gc_status.requested += csize;
@@ -892,11 +975,7 @@ alloc_add_chunk(gs_ref_memory_t * mem, ulong csize, bool has_strings,
(long)mem->limit, (long)mem->gc_status.requested);
*mem->gc_status.psignal = mem->gc_status.signal_value;
}
- while ((uint) elt_size != elt_size)
- elt_size = (elt_size + 1) >> 1,
- num_elts <<= 1;
- cdata = gs_alloc_byte_array_immovable(parent, num_elts, elt_size,
- cname);
+ cdata = gs_alloc_bytes_immovable(parent, csize, cname);
if (cp == 0 || cdata == 0) {
gs_free_object(parent, cdata, cname);
gs_free_object(parent, cp, cname);
@@ -905,8 +984,7 @@ alloc_add_chunk(gs_ref_memory_t * mem, ulong csize, bool has_strings,
}
alloc_init_chunk(cp, cdata, cdata + csize, has_strings, (chunk_t *) 0);
alloc_link_chunk(cp, mem);
- mem->allocated +=
- gs_object_size(parent, cdata) + gs_object_size(parent, cp);
+ mem->allocated += st_chunk.ssize + csize;
return cp;
}
@@ -974,7 +1052,7 @@ alloc_close_chunk(gs_ref_memory_t * mem)
*mem->pcc = mem->cc;
#ifdef DEBUG
if (gs_debug_c('a')) {
- dprintf1("[a%d]", mem->space);
+ dlprintf1("[a%d]", mem->space);
dprintf_chunk("closing chunk", mem->pcc);
}
#endif
@@ -989,7 +1067,7 @@ alloc_open_chunk(gs_ref_memory_t * mem)
mem->cc = *mem->pcc;
#ifdef DEBUG
if (gs_debug_c('a')) {
- dprintf1("[a%d]", mem->space);
+ dlprintf1("[a%d]", mem->space);
dprintf_chunk("opening chunk", mem->pcc);
}
#endif
@@ -1031,11 +1109,11 @@ alloc_unlink_chunk(chunk_t * cp, gs_ref_memory_t * mem)
}
}
-/* Free a chunk. This is exported for save/restore and for the GC. */
+/* Free a chunk. This is exported for the GC. */
void
alloc_free_chunk(chunk_t * cp, gs_ref_memory_t * mem)
{
- gs_memory_t *parent = mem->parent;
+ gs_raw_memory_t *parent = mem->parent;
alloc_unlink_chunk(cp, mem);
if (mem->cfreed.cp == cp)
@@ -1043,11 +1121,11 @@ alloc_free_chunk(chunk_t * cp, gs_ref_memory_t * mem)
if (cp->outer == 0) {
byte *cdata = (byte *) cp->chead;
- mem->allocated -= gs_object_size(parent, cdata);
+ mem->allocated -= cp->cend - cdata;
gs_free_object(parent, cdata, "alloc_free_chunk(data)");
} else
cp->outer->inner_count--;
- mem->allocated -= gs_object_size(parent, cp);
+ mem->allocated -= st_chunk.ssize;
gs_free_object(parent, cp, "alloc_free_chunk(chunk struct)");
}
@@ -1259,8 +1337,8 @@ debug_print_object(const void *obj, const dump_control_t * control)
* will require adding 'const' to the first prototype argument
* of struct_proc_enum_ptrs.
*/
- if (proc != 0)
- for (; (ptype = (*proc) ((obj_header_t *) pre + 1, size, index, &ptr)) != 0;
+ if (proc != gs_no_struct_enum_ptrs)
+ for (; (ptype = (*proc) ((obj_header_t *) pre + 1, size, index, &ptr, type, NULL)) != 0;
++index
) {
dprintf1(" ptr %u: ", index);