/* Copyright (C) 1993, 1996, 1997, 1998, 1999, 2001 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gsmemory.h,v 1.3.2.1.2.1 2003/01/17 00:49:03 giles Exp $ */ /* Client interface for memory allocation */ /* * The allocator knows about two basic kinds of memory: objects, which are * aligned and cannot have pointers to their interior, and strings, which * are not aligned and which can have interior references. * * The standard allocator is designed to interface to a garbage collector, * although it does not include or call one. The allocator API recognizes * that the garbage collector may move objects, relocating pointers to them; * the API provides for allocating both movable (the default) and immovable * objects. Clients must not attempt to resize immovable objects, and must * not create references to substrings of immovable strings. */ #ifndef gsmemory_INCLUDED # define gsmemory_INCLUDED #include "gsmemraw.h" #include "gstypes.h" /* for gs_bytestring */ /* Define the opaque type for a structure descriptor. */ typedef struct gs_memory_struct_type_s gs_memory_struct_type_t; typedef const gs_memory_struct_type_t *gs_memory_type_ptr_t; /* Define the opaque type for an allocator. */ /* (The actual structure is defined later in this file.) */ #ifndef gs_memory_DEFINED # define gs_memory_DEFINED typedef struct gs_memory_s gs_memory_t; #endif /* Define the opaque type for a pointer type. */ typedef struct gs_ptr_procs_s gs_ptr_procs_t; typedef const gs_ptr_procs_t *gs_ptr_type_t; /* Define the opaque type for a GC root. */ typedef struct gs_gc_root_s gs_gc_root_t; /* Accessors for structure types. */ typedef client_name_t struct_name_t; /* Get the size of a structure from the descriptor. */ uint gs_struct_type_size(P1(gs_memory_type_ptr_t)); /* Get the name of a structure from the descriptor. */ struct_name_t gs_struct_type_name(P1(gs_memory_type_ptr_t)); #define gs_struct_type_name_string(styp)\ ((const char *)gs_struct_type_name(styp)) /* * Define the memory manager procedural interface. */ typedef struct gs_memory_procs_s { gs_raw_memory_procs(gs_memory_t); /* defined in gsmemraw.h */ /* Redefine inherited procedures with the new allocator type. */ #define gs_memory_proc_alloc_bytes(proc)\ gs_memory_t_proc_alloc_bytes(proc, gs_memory_t) #define gs_memory_proc_resize_object(proc)\ gs_memory_t_proc_resize_object(proc, gs_memory_t) #define gs_memory_proc_free_object(proc)\ gs_memory_t_proc_free_object(proc, gs_memory_t) #define gs_memory_proc_stable(proc)\ gs_memory_t_proc_stable(proc, gs_memory_t) #define gs_memory_proc_status(proc)\ gs_memory_t_proc_status(proc, gs_memory_t) #define gs_memory_proc_free_all(proc)\ gs_memory_t_proc_free_all(proc, gs_memory_t) #define gs_memory_proc_consolidate_free(proc)\ gs_memory_t_proc_consolidate_free(proc, gs_memory_t) /* * Allocate possibly movable bytes. (We inherit allocating immovable * bytes from the raw memory allocator.) */ #define gs_alloc_bytes(mem, nbytes, cname)\ (*(mem)->procs.alloc_bytes)(mem, nbytes, cname) gs_memory_proc_alloc_bytes((*alloc_bytes)); /* * Allocate a structure. */ #define gs_memory_proc_alloc_struct(proc)\ void *proc(P3(gs_memory_t *mem, gs_memory_type_ptr_t pstype,\ client_name_t cname)) #define gs_alloc_struct(mem, typ, pstype, cname)\ (typ *)(*(mem)->procs.alloc_struct)(mem, pstype, cname) gs_memory_proc_alloc_struct((*alloc_struct)); #define gs_alloc_struct_immovable(mem, typ, pstype, cname)\ (typ *)(*(mem)->procs.alloc_struct_immovable)(mem, pstype, cname) gs_memory_proc_alloc_struct((*alloc_struct_immovable)); /* * Allocate an array of bytes. */ #define gs_memory_proc_alloc_byte_array(proc)\ byte *proc(P4(gs_memory_t *mem, uint num_elements, uint elt_size,\ client_name_t cname)) #define gs_alloc_byte_array(mem, nelts, esize, cname)\ (*(mem)->procs.alloc_byte_array)(mem, nelts, esize, cname) gs_memory_proc_alloc_byte_array((*alloc_byte_array)); #define gs_alloc_byte_array_immovable(mem, nelts, esize, cname)\ (*(mem)->procs.alloc_byte_array_immovable)(mem, nelts, esize, cname) gs_memory_proc_alloc_byte_array((*alloc_byte_array_immovable)); /* * Allocate an array of structures. */ #define gs_memory_proc_alloc_struct_array(proc)\ void *proc(P4(gs_memory_t *mem, uint num_elements,\ gs_memory_type_ptr_t pstype, client_name_t cname)) #define gs_alloc_struct_array(mem, nelts, typ, pstype, cname)\ (typ *)(*(mem)->procs.alloc_struct_array)(mem, nelts, pstype, cname) gs_memory_proc_alloc_struct_array((*alloc_struct_array)); #define gs_alloc_struct_array_immovable(mem, nelts, typ, pstype, cname)\ (typ *)(*(mem)->procs.alloc_struct_array_immovable)(mem, nelts, pstype, cname) gs_memory_proc_alloc_struct_array((*alloc_struct_array_immovable)); /* * Get the size of an object (anything except a string). */ #define gs_memory_proc_object_size(proc)\ uint proc(P2(gs_memory_t *mem, const void *obj)) #define gs_object_size(mem, obj)\ (*(mem)->procs.object_size)(mem, obj) gs_memory_proc_object_size((*object_size)); /* * Get the type of an object (anything except a string). * The value returned for byte objects is useful only for * printing. */ #define gs_memory_proc_object_type(proc)\ gs_memory_type_ptr_t proc(P2(gs_memory_t *mem, const void *obj)) #define gs_object_type(mem, obj)\ (*(mem)->procs.object_type)(mem, obj) gs_memory_proc_object_type((*object_type)); /* * Allocate a string (unaligned bytes). */ #define gs_memory_proc_alloc_string(proc)\ byte *proc(P3(gs_memory_t *mem, uint nbytes, client_name_t cname)) #define gs_alloc_string(mem, nbytes, cname)\ (*(mem)->procs.alloc_string)(mem, nbytes, cname) gs_memory_proc_alloc_string((*alloc_string)); #define gs_alloc_string_immovable(mem, nbytes, cname)\ (*(mem)->procs.alloc_string_immovable)(mem, nbytes, cname) gs_memory_proc_alloc_string((*alloc_string_immovable)); /* * Resize a string. The specification is the same as resize_object * (in gsmemraw.h), except that the element size is always a byte. */ #define gs_memory_proc_resize_string(proc)\ byte *proc(P5(gs_memory_t *mem, byte *data, uint old_num, uint new_num,\ client_name_t cname)) #define gs_resize_string(mem, data, oldn, newn, cname)\ (*(mem)->procs.resize_string)(mem, data, oldn, newn, cname) gs_memory_proc_resize_string((*resize_string)); /* * Free a string. */ #define gs_memory_proc_free_string(proc)\ void proc(P4(gs_memory_t *mem, byte *data, uint nbytes,\ client_name_t cname)) #define gs_free_string(mem, data, nbytes, cname)\ (*(mem)->procs.free_string)(mem, data, nbytes, cname) gs_memory_proc_free_string((*free_string)); /* * Register a root for the garbage collector. root = NULL * asks the memory manager to allocate the root object * itself (immovable, in the manager's parent): this is the usual * way to call this procedure. */ #define gs_memory_proc_register_root(proc)\ int proc(P5(gs_memory_t *mem, gs_gc_root_t *root, gs_ptr_type_t ptype,\ void **pp, client_name_t cname)) #define gs_register_root(mem, root, ptype, pp, cname)\ (*(mem)->procs.register_root)(mem, root, ptype, pp, cname) gs_memory_proc_register_root((*register_root)); /* * Unregister a root. The root object itself will be freed iff * it was allocated by gs_register_root. */ #define gs_memory_proc_unregister_root(proc)\ void proc(P3(gs_memory_t *mem, gs_gc_root_t *root, client_name_t cname)) #define gs_unregister_root(mem, root, cname)\ (*(mem)->procs.unregister_root)(mem, root, cname) gs_memory_proc_unregister_root((*unregister_root)); /* * Enable or disable the freeing operations: when disabled, * these operations return normally but do nothing. The * garbage collector and the PostScript interpreter * 'restore' operator need to temporarily disable the * freeing functions of (an) allocator(s) while running * finalization procedures. */ #define gs_memory_proc_enable_free(proc)\ void proc(P2(gs_memory_t *mem, bool enable)) #define gs_enable_free(mem, enable)\ (*(mem)->procs.enable_free)(mem, enable) gs_memory_proc_enable_free((*enable_free)); } gs_memory_procs_t; /* * Define versions of the freeing procedures that are applicable even if the * pointer is declared as const T *. These are intended for use where a * structure contains a pointer member whose referent is declared as const * because it is const for all ordinary clients. */ void gs_free_const_object(P3(gs_memory_t *mem, const void *data, client_name_t cname)); void gs_free_const_string(P4(gs_memory_t *mem, const byte *data, uint nbytes, client_name_t cname)); /* * Free a [const] bytestring. Note that this is *not* a member procedure of * the allocator: it calls the free_object or free_string procedure. */ void gs_free_bytestring(gs_memory_t *mem, gs_bytestring *pbs, client_name_t cname); void gs_free_const_bytestring(gs_memory_t *mem, gs_const_bytestring *pbs, client_name_t cname); /* * Either allocate (if obj == 0) or resize (if obj != 0) a structure array. * If obj != 0, pstype is used only for checking (in DEBUG configurations). */ void *gs_resize_struct_array(P5(gs_memory_t *mem, void *obj, uint num_elements, gs_memory_type_ptr_t pstype, client_name_t cname)); /* Register a structure root. This just calls gs_register_root. */ int gs_register_struct_root(P4(gs_memory_t *mem, gs_gc_root_t *root, void **pp, client_name_t cname)); /* Define no-op freeing procedures for use by enable_free. */ gs_memory_proc_free_object(gs_ignore_free_object); gs_memory_proc_free_string(gs_ignore_free_string); /* Define a no-op consolidation procedure. */ gs_memory_proc_consolidate_free(gs_ignore_consolidate_free); /* * Allocate a structure using a "raw memory" allocator. Note that this does * not retain the identity of the structure. Note also that it returns a * void *, and does not take the type of the returned pointer as a * parameter. */ void *gs_raw_alloc_struct_immovable(P3(gs_raw_memory_t * rmem, gs_memory_type_ptr_t pstype, client_name_t cname)); /* * Define an abstract allocator instance. * Subclasses may have state as well. * Note that the initial part of this must match gs_raw_memory_t. */ #define gs_memory_common\ gs_memory_t *stable_memory;\ gs_memory_procs_t procs struct gs_memory_s { gs_memory_common; }; #endif /* gsmemory_INCLUDED */