[gs-cvs] rev 9524 - trunk/ghostpdl/pl
henrys at ghostscript.com
henrys at ghostscript.com
Tue Mar 3 15:17:09 PST 2009
Author: henrys
Date: 2009-03-03 15:17:08 -0800 (Tue, 03 Mar 2009)
New Revision: 9524
Modified:
trunk/ghostpdl/pl/plalloc.c
trunk/ghostpdl/pl/plalloc.h
trunk/ghostpdl/pl/plmain.c
trunk/ghostpdl/pl/plmain.h
Log:
This change deprecates the pl allocator and reintigrates pcl with the
old ghostscript allocator (nogc) for better performance. -K does not
yet work properly and will be fixed shortly.
Modified: trunk/ghostpdl/pl/plalloc.c
===================================================================
--- trunk/ghostpdl/pl/plalloc.c 2009-03-03 22:43:53 UTC (rev 9523)
+++ trunk/ghostpdl/pl/plalloc.c 2009-03-03 23:17:08 UTC (rev 9524)
@@ -6,544 +6,20 @@
Hence a simple allocator based on malloc, realloc and free. */
/*$Id$*/
-#include "malloc_.h"
-#include "memory_.h"
-#include "gdebug.h"
-#include "gsmemret.h" /* for gs_memory_type_ptr_t */
+#include "std.h"
#include "gsmalloc.h"
-#include "gsstype.h"
+#include "gsalloc.h"
#include "plalloc.h"
-/* a screwed up mess, we try to make it manageable here */
-extern const gs_memory_struct_type_t st_bytes;
-
-/* assume doubles are the largest primitive types and malloc alignment
- is consistent. Covers the machines we care about */
-inline static uint
-round_up_to_align(uint size)
-{
- return ARCH_ALIGN_MEMORY_MOD;
-}
-
-/* aceesors to get size and type given the pointer returned to the
- client, *not* the pointer returned by malloc or realloc */
-inline static uint
-get_size(byte *ptr)
-{
- /* unpack the unsigned long we stored 2 words behind the object at
- alloc time... back up 2 */
- byte *bptr = ptr - (round_up_to_align(1) * 2);
- uint size;
- /* unpack */
- memcpy(&size, bptr, sizeof(uint));
- return size;
-}
-
-inline gs_memory_type_ptr_t
-get_type(char *ptr)
-{
- /* unpack the unsigned long we stored 1 word behind the object at
- alloc time... back up 1 */
- gs_memory_type_ptr_t type;
- byte *bptr = ptr - round_up_to_align(1);
- /* unpack */
- memcpy(&type, bptr, sizeof(gs_memory_type_ptr_t));
- return type;
-}
-
-/* aceesors to get size and typen give the pointer that was returned
- by malloc or realloc, *not* the pointer returned by malloc or
- realloc */
-inline void
-set_size(byte *bptr, uint size)
-{
- memcpy(bptr, &size, sizeof(size));
-}
-
-inline void
-set_type(byte *bptr, gs_memory_type_ptr_t type)
-{
- memcpy(&bptr[round_up_to_align(1)], &type, sizeof(type));
- return;
-}
-
-#ifndef PL_KEEP_GLOBAL_FREE_LIST
-#error "feature binding PL_KEEP_GLOBAL_FREE_LIST is undefined"
-#endif
-
-struct pl_mem_node_s {
- byte *address;
- struct pl_mem_node_s *next;
- const char *cname;
-#ifdef DEBUG
- long op_count;
-#endif
-};
-
-#ifdef DEBUG
-/* each add operation increments the operation count. So if a
- reference is reported unfreed in the remaining free list it's
- allocation can easily be found with a conditional
- breakpoint */
- static long mem_node_operation_count = 0;
- static long mem_node_operation_count_fastbreakpoint = 0xffffffff;
-#endif
-
-
-/* return -1 on error, 0 on success */
-int
-pl_mem_node_add(gs_memory_t * mem, byte *add, const char *cname)
-{
- if( PL_KEEP_GLOBAL_FREE_LIST ) {
- pl_mem_node_t *node = (pl_mem_node_t *)malloc(sizeof(pl_mem_node_t));
- if ( node == NULL )
- return -1;
- if (mem->head == NULL) {
- mem->head = node;
- mem->head->next = NULL;
- } else {
- node->next = mem->head;
- mem->head = node;
- }
- mem->head->address = add;
- mem->head->cname = cname;
-#ifdef DEBUG
- mem_node_operation_count++;
- mem->head->op_count = mem_node_operation_count;
- if ( mem_node_operation_count == mem_node_operation_count_fastbreakpoint )
- return 0;
-#endif
- }
- return 0;
-}
-
-int
-pl_mem_node_remove(gs_memory_t *mem, byte *addr)
-{
- if ( PL_KEEP_GLOBAL_FREE_LIST ) {
- pl_mem_node_t *head = mem->head;
- pl_mem_node_t *current;
- /* check the head first */
- if ( head == NULL ) {
- dprintf("FAIL - no nodes to be removed\n" );
- return -1;
- }
-
- if ( head && head->address == addr ) {
- pl_mem_node_t *tmp = head->next;
- free(head);
- mem->head = tmp;
- } else {
- /* stop in front of element */
- bool found = false;
- for (current = head; current != NULL; current = current->next) {
-
- if ( current->next && (current->next->address == addr) ) {
- pl_mem_node_t *tmp = current->next->next;
- free(current->next);
- current->next = tmp;
- found = true;
- break;
- }
-
- }
- if ( !found ) {
- dprintf1("FAIL freeing wild pointer freed address %x not found\n", (uint)addr );
- return -1;
- }
- }
- }
- return 0;
-}
-
-void
-pl_mem_node_free_all_remaining(gs_memory_t *mem)
-{
- if( PL_KEEP_GLOBAL_FREE_LIST ) {
- pl_mem_node_t *head = mem->head;
-# ifdef DEBUG
- static const bool print_recovered_block_info = true;
-# else
- static const bool print_recovered_block_info = false;
-# endif
- uint blk_count = 0;
- uint size = 0;
- uint total_size = 0;
- byte* ptr;
-
- pl_mem_node_t *current;
- pl_mem_node_t *next;
- current = head;
- while ( current != NULL ) {
- next = current->next;
- if ( print_recovered_block_info ) {
- ++blk_count;
- ptr = ((byte*)current->address) + (2 * round_up_to_align(1));
- size = get_size(ptr);
- total_size += size;
-#ifdef DEBUG
- dprintf4("Recovered %x size %d %ld'th allocation client %s\n",
- (uint)ptr, size, current->op_count, current->cname);
-#endif
- }
- if ((void*)current->address != (void*)mem->gs_lib_ctx)
- free(current->address);
- free(current);
- current = next;
- }
- if ( print_recovered_block_info && blk_count )
- dprintf2("Recovered %d blocks, %d bytes\n",
- blk_count, total_size);
- mem->head = NULL;
- }
-}
-
-
-/* all of the allocation routines modulo realloc reduce to the this
- function */
-static byte *
-pl_alloc(gs_memory_t *mem, uint size, gs_memory_type_ptr_t type, client_name_t cname)
-{
-
- uint minsize, newsize;
- /* use 2 starting machine words for size and type - assumes
- malloc() returns on max boundary and first 2 words will hold
- two longs. Doesn't check for overflow - malloc will fail for
- us. Update size. */
- minsize = round_up_to_align(1);
- newsize = size + minsize + minsize;
- {
-
- byte *ptr = (byte *)malloc(newsize);
- if ( !ptr )
- return NULL;
-#ifdef DEBUG
- if_debug2('A', "[da]:malloc:%x:%s\n", (uint)&ptr[minsize * 2], cname );
-#endif
- /* set the type and size */
- set_type(ptr, type);
- set_size(ptr, size);
- /* initialize for debugging */
-#ifdef DEBUG
- if ( gs_debug_c('@') )
- memset(&ptr[minsize * 2], 0xff, get_size(&ptr[minsize * 2]));
-#endif
- if ( pl_mem_node_add(mem, ptr, cname) ) {
- free( ptr );
- return NULL;
- }
- /* return the memory after the size and type words. */
- return &ptr[minsize * 2];
- }
-}
-
-static byte *
-pl_alloc_bytes_immovable(gs_memory_t * mem, uint size, client_name_t cname)
-{
- return pl_alloc(mem, size, &st_bytes, cname);
-}
-
-static byte *
-pl_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname)
-{
- return pl_alloc(mem, size, &st_bytes, cname);
-}
-
-static void *
-pl_alloc_struct_immovable(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
- client_name_t cname)
-{
- return pl_alloc(mem, pstype->ssize, pstype, cname);
-}
-
-static void *
-pl_alloc_struct(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
- client_name_t cname)
-{
- return pl_alloc(mem, pstype->ssize, pstype, cname);
-}
-
-static byte *
-pl_alloc_byte_array_immovable(gs_memory_t * mem, uint num_elements,
- uint elt_size, client_name_t cname)
-{
- return pl_alloc_bytes(mem, num_elements * elt_size, cname);
-}
-
-static byte *
-pl_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size,
- client_name_t cname)
-{
- return pl_alloc_bytes(mem, num_elements * elt_size, cname);
-}
-
-static void *
-pl_alloc_struct_array_immovable(gs_memory_t * mem, uint num_elements,
- gs_memory_type_ptr_t pstype, client_name_t cname)
-{
- return pl_alloc(mem, num_elements * pstype->ssize, pstype, cname);
-}
-
-static void *
-pl_alloc_struct_array(gs_memory_t * mem, uint num_elements,
- gs_memory_type_ptr_t pstype, client_name_t cname)
-{
- return pl_alloc(mem, num_elements * pstype->ssize, pstype, cname);
-}
-
-
-static void *
-pl_resize_object(gs_memory_t * mem, void *obj, uint new_num_elements, client_name_t cname)
-{
- byte *ptr;
-
- /* get the type from the old object */
- gs_memory_type_ptr_t objs_type = get_type(obj);
- /* type and size header size */
- ulong header_size = round_up_to_align(1) + round_up_to_align(1);
- /* get new object's size */
- ulong new_size = (objs_type->ssize * new_num_elements) + header_size;
- byte *bptr = (byte *)obj - header_size;
- /* replace the size field */
- ptr = (byte *)realloc(bptr, new_size);
- if ( !ptr )
- return NULL;
-
- pl_mem_node_remove(mem, bptr);
- pl_mem_node_add(mem, ptr, cname);
- /* da for debug allocator - so scripts can parse the trace */
- if_debug2('A', "[da]:realloc:%x:%s\n", (uint)ptr, cname );
- /* we reset size and type - the type in case realloc moved us */
- set_size(ptr, new_size - header_size);
- set_type(ptr, objs_type);
- return &ptr[round_up_to_align(1) * 2];
-}
-
-
-static void
-pl_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
-{
- if ( ptr != NULL ) {
- uint header_size = round_up_to_align(1) + round_up_to_align(1);
- byte *bptr = (byte *)ptr - header_size;
- gs_memory_type_ptr_t ptype = get_type((byte *)ptr);
- void (*finalize)(void *ptr) = ptype->finalize;
- if ( finalize != NULL )
- finalize(ptr);
-#ifdef DEBUG
- if ( gs_debug_c('@') )
- memset(bptr, 0xee, header_size + get_size(ptr));
-#endif
- if (!pl_mem_node_remove(mem, bptr))
- free(bptr);
-
-#ifdef DEBUG
- /* da for debug allocator - so scripts can parse the trace */
- if_debug2('A', "[da]:free:%x:%s\n", (uint)ptr, cname );
-#endif
- }
-}
-
-static byte *
-pl_alloc_string_immovable(gs_memory_t * mem, uint nbytes, client_name_t cname)
-{
- /* we just alloc bytes here */
- return pl_alloc_bytes(mem, nbytes, cname);
-}
-
-static byte *
-pl_alloc_string(gs_memory_t * mem, uint nbytes, client_name_t cname)
-{
- /* we just alloc bytes here */
- return pl_alloc_bytes(mem, nbytes, cname);
-}
-
-static byte *
-pl_resize_string(gs_memory_t * mem, byte * data, uint old_num, uint new_num,
- client_name_t cname)
-{
- /* just resize object - ignores old_num */
- return pl_resize_object(mem, data, new_num, cname);
-}
-
-static void
-pl_free_string(gs_memory_t * mem, byte * data, uint nbytes,
- client_name_t cname)
-{
- pl_free_object(mem, data, cname);
- return;
-}
-
-
-static void
-pl_status(gs_memory_t * mem, gs_memory_status_t * pstat)
-{
- return;
-}
-
-static void
-pl_enable_free(gs_memory_t * mem, bool enable)
-{
- return;
-}
-
-static void
-pl_free_all(gs_memory_t * mem, uint free_mask, client_name_t cname)
-{
- return;
-}
-
-static void
-pl_consolidate_free(gs_memory_t *mem)
-{
- return;
-}
-
-
-static uint
-pl_object_size(const gs_memory_t * mem, const void /*obj_header_t */ *obj)
-{
- return get_size((byte *)obj);
-}
-
-static gs_memory_type_ptr_t
-pl_object_type(const gs_memory_t * mem, const void /*obj_header_t */ *obj)
-{
- return get_type((byte *)obj);
-}
-
-static int
-pl_register_root(gs_memory_t * mem, gs_gc_root_t * rp, gs_ptr_type_t ptype,
- void **up, client_name_t cname)
-{
- return 0;
-}
-
-static void
-pl_unregister_root(gs_memory_t * mem, gs_gc_root_t * rp, client_name_t cname)
-{
- return;
-}
-
-/* Define a vacuous recovery procedure. */
-static gs_memory_recover_status_t
-no_recover_proc(gs_memory_retrying_t *rmem, void *proc_data)
-{
- return RECOVER_STATUS_NO_RETRY;
-}
-
-
-/* forward decl */
-static gs_memory_t * pl_stable(gs_memory_t *mem);
-
-
-gs_memory_retrying_t pl_mem = {
- (gs_memory_t *)&pl_mem, /* also this is stable_memory since no save/restore */
- { pl_alloc_bytes_immovable, /* alloc_bytes_immovable */
- pl_resize_object, /* resize_object */
- pl_free_object, /* free_object */
- pl_stable, /* stable */
- pl_status, /* status */
- pl_free_all, /* free_all */
- pl_consolidate_free, /* consolidate_free */
- pl_alloc_bytes, /* alloc_bytes */
- pl_alloc_struct, /* alloc_struct */
- pl_alloc_struct_immovable, /* alloc_struct_immovable */
- pl_alloc_byte_array, /* alloc_byte_array */
- pl_alloc_byte_array_immovable, /* alloc_byte_array_immovable */
- pl_alloc_struct_array, /* alloc_struct_array */
- pl_alloc_struct_array_immovable, /* alloc_struct_array_immovable */
- pl_object_size, /* object_size */
- pl_object_type, /* object_type */
- pl_alloc_string, /* alloc_string */
- pl_alloc_string_immovable, /* alloc_string_immovable */
- pl_resize_string, /* resize_string */
- pl_free_string, /* free_string */
- pl_register_root, /* register_root */
- pl_unregister_root, /* unregister_root */
- pl_enable_free /* enable_free */
- },
- NULL, /* gs_lib_ctx */
- NULL, /* head */
- NULL, /* non_gc_memory */
- NULL, /* target */
- no_recover_proc, /* recovery procedure */
- NULL /* recovery data */
-};
-
-static gs_memory_t *
-pl_stable(gs_memory_t *mem)
-{
- return (gs_memory_t *)&pl_mem;
-}
-
-const gs_malloc_memory_t pl_malloc_memory = {
- 0, /* stable */
- { pl_alloc_bytes_immovable, /* alloc_bytes_immovable */
- pl_resize_object, /* resize_object */
- pl_free_object, /* free_object */
- pl_stable, /* stable */
- pl_status, /* status */
- pl_free_all, /* free_all */
- pl_consolidate_free, /* consolidate_free */
- pl_alloc_bytes, /* alloc_bytes */
- pl_alloc_struct, /* alloc_struct */
- pl_alloc_struct_immovable, /* alloc_struct_immovable */
- pl_alloc_byte_array, /* alloc_byte_array */
- pl_alloc_byte_array_immovable, /* alloc_byte_array_immovable */
- pl_alloc_struct_array, /* alloc_struct_array */
- pl_alloc_struct_array_immovable, /* alloc_struct_array_immovable */
- pl_object_size, /* object_size */
- pl_object_type, /* object_type */
- pl_alloc_string, /* alloc_string */
- pl_alloc_string_immovable, /* alloc_string_immovable */
- pl_resize_string, /* resize_string */
- pl_free_string, /* free_string */
- pl_register_root, /* register_root */
- pl_unregister_root, /* unregister_root */
- pl_enable_free /* enable_free */
- },
- NULL, /* gs_lib_ctx */
- NULL, /* head */
- NULL, /* non_gc_memory */
- 0, /* allocated */
- 0, /* limit */
- 0, /* used */
- 0 /* max used */
-};
-
-#ifndef PSI_INCLUDED
-/* retrun the c-heap manager set the global default as well. */
-static gs_memory_t *
-pl_malloc_init(void)
-{
- return (gs_memory_t *)&pl_malloc_memory;
-}
-#endif
-
gs_memory_t *
pl_alloc_init()
{
-#ifndef PSI_INCLUDED
- if ( pl_malloc_init() == NULL )
- return NULL;
+ gs_memory_t *mem = gs_malloc_init(NULL);
+ /* fix me... the second parameter (chunk size) should be a member of
+ pl_main_instance_t */
+ gs_memory_t *pl_mem = ialloc_alloc_state(mem, 20000);
- gs_lib_ctx_init((gs_memory_t *)&pl_mem);
+ if ( (mem == NULL) || (pl_mem == NULL) ) return NULL;
- pl_mem.head = 0;
- pl_mem.non_gc_memory = (gs_memory_t *)&pl_mem;
-
- return (gs_memory_t *)&pl_mem;
-
-#else
-
- gs_memory_t *local_memory_t_default = 0;
-
- if( (local_memory_t_default = gs_malloc_init( 0 )) == 0 )
- return 0;
- local_memory_t_default->head = 0;
-
- return local_memory_t_default;
-#endif
+ return pl_mem;
}
-
Modified: trunk/ghostpdl/pl/plalloc.h
===================================================================
--- trunk/ghostpdl/pl/plalloc.h 2009-03-03 22:43:53 UTC (rev 9523)
+++ trunk/ghostpdl/pl/plalloc.h 2009-03-03 23:17:08 UTC (rev 9524)
@@ -11,25 +11,7 @@
San Rafael, CA 94903, (415)492-9861, for further information. */
/*$Id$*/
-/* A simple memory allocator for use by pcl and pxl */
+/* initialize the gs allocator. */
gs_memory_t *pl_alloc_init(void);
-#ifdef DEBUG
-/* If true PL_KEEP_GLOBAL_FREE_LIST will force all memory allocations to be stored
- * in a linked list, calling mem_node_free_all_remaining() will free any remaining
- * blocks. This can be used to force a return to zero memory usage prior to
- * program termination. Since this isn't free not all system will need/want the overhead
- * of searching for the block to be freed on every deallocation.
- *
- * To disable the feature define PL_KEEP_GLOBAL_FREE_LIST to false
- * We only set this in a DEBUG build to prevent poor performance in a release build.
- */
-
-# define PL_KEEP_GLOBAL_FREE_LIST true
-#else
-# define PL_KEEP_GLOBAL_FREE_LIST false
-#endif
-
-/* free all remaining memory blocks */
-void pl_mem_node_free_all_remaining(gs_memory_t *mem);
Modified: trunk/ghostpdl/pl/plmain.c
===================================================================
--- trunk/ghostpdl/pl/plmain.c 2009-03-03 22:43:53 UTC (rev 9523)
+++ trunk/ghostpdl/pl/plmain.c 2009-03-03 23:17:08 UTC (rev 9524)
@@ -73,16 +73,14 @@
/* Define the usage message. */
static const char *pl_usage = "\
Usage: %s [option* file]+...\n\
-Options: -dNOPAUSE -E[#] -h -C -L<PCL|PCLXL> -n -K<maxK> -P<PCL5C|PCL5E|RTL> -Z...\n\
+Options: -dNOPAUSE -E[#] -h -C -L<PCL|PCLXL> -K<maxK> -P<PCL5C|PCL5E|RTL> -Z...\n\
-sDEVICE=<dev> -g<W>x<H> -r<X>[x<Y>] -d{First|Last}Page=<#>\n\
-sOutputFile=<file> (-s<option>=<string> | -d<option>[=<value>])*\n\
-J<PJL commands>\n";
/* ---------------- Static data for memory management ------------------ */
-#ifdef PSI_INCLUDED
static gs_gc_root_t device_root;
-#endif
#if defined(DEBUG) && defined(ALLOW_VD_TRACE)
void *hwndtext; /* Hack: Should be of HWND type. */
@@ -472,9 +470,6 @@
dprintf("Final time" );
pl_platform_dnit(0);
- if ( inst.mem_cleanup ) {
- pl_mem_node_free_all_remaining(mem);
- }
return 0;
}
@@ -578,15 +573,10 @@
/* dealloc device if sel'd */
if (universe->curr_device) {
-#ifdef PSI_INCLUDED
gs_unregister_root(universe->curr_device->memory, &device_root, "pl_main_universe_select");
/* ps allocator retain's the device, pl_alloc doesn't */
gx_device_retain(universe->curr_device, false);
universe->curr_device = NULL;
-#else
- gs_free_object(universe->mem, universe->curr_device,
- "pl_main_universe_dnit(gx_device)");
-#endif
}
return 0;
@@ -631,9 +621,7 @@
return 0;
} else {
/* Delete the device. */
-# ifdef PSI_INCLUDED
gs_unregister_root(universe->curr_device->memory, &device_root, "pl_main_universe_select");
-# endif
gs_free_object(universe->curr_device->memory,
universe->curr_device, "pl_main_universe_select(gx_device)");
universe->curr_device = 0;
@@ -743,7 +731,6 @@
pti->last_page = max_int;
pti->page_count = 0;
pti->saved_hwres = false;
- pti->mem_cleanup = true;
pti->interpolate = false;
strncpy(&pti->pcl_personality[0], "PCL", sizeof(pti->pcl_personality)-1);
}
@@ -760,26 +747,22 @@
if ( !is_default || !pti->device ) {
const gx_device **list;
-# ifdef PSI_INCLUDED
/* We assume that nobody else changes pti->device,
and this function is called from this module only.
Due to that device_root is always consistent with pti->device,
- and it is regisrtered if and only if pti-<device != NULL.
+ and it is regisrtered if and only if pti->device != NULL.
*/
if (pti->device != NULL) {
pti->device = NULL;
gs_unregister_root(pti->device_memory, &device_root, "pl_main_universe_select");
}
-# endif
-
gs_lib_device_list((const gx_device * const **)&list, NULL);
code = gs_copydevice(&pti->device, list[index],
pti->device_memory);
-# ifdef PSI_INCLUDED
- if (pti->device != NULL)
- gs_register_struct_root(pti->device_memory, &device_root,
+ if (pti->device != NULL)
+ gs_register_struct_root(pti->device_memory, &device_root,
&pti->device, "pl_top_create_device");
-# endif
+
}
return code;
}
@@ -948,6 +931,7 @@
break;
case 'K': /* max memory in K */
{
+#ifdef OLD_ALLOCATOR
int maxk;
gs_malloc_memory_t *rawheap = gs_malloc_wrapped_contents(pmi->memory);
@@ -956,12 +940,10 @@
return -1;
}
rawheap->limit = (long)maxk << 10;
+#endif
}
break;
- case 'n':
- case 'N':
- pmi->mem_cleanup = false;
- break;
+
case 'p':
case 'P':
{
Modified: trunk/ghostpdl/pl/plmain.h
===================================================================
--- trunk/ghostpdl/pl/plmain.h 2009-03-03 22:43:53 UTC (rev 9523)
+++ trunk/ghostpdl/pl/plmain.h 2009-03-03 23:17:08 UTC (rev 9524)
@@ -49,7 +49,6 @@
bool saved_hwres;
float hwres[2];
bool viewer; /* speed optimizations for viewer; NB MAY not always be correct! */
- bool mem_cleanup;
char pcl_personality[6]; /* a character string to set pcl's
personality - rtl, pcl5c, pcl5e, and
pcl == default. NB doesn't belong here. */
More information about the gs-cvs
mailing list