1 /* Copyright (C) 1991, 1995, 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: isave.h,v 1.7 2004/08/04 19:36:13 stefan Exp $ */ 18 /* Procedures for save/restore */ 19 /* Requires imemory.h */ 20 21 #ifndef isave_INCLUDED 22 # define isave_INCLUDED 23 24 #include "idosave.h" 25 26 /* 27 * According to the PostScript language definition, save objects are simple, 28 * not composite. Consequently, we cannot use their natural representation, 29 * namely a t_struct pointing to an alloc_save_t, since we aren't willing to 30 * allocate them all in global VM and rely on garbage collection to clean 31 * them up. Instead, we assign each one a unique "save ID", and store this 32 * in the alloc_save_t object. Mapping the number to the object requires 33 * at most searching the local save chain for the current gs_dual_memory_t, 34 * and this approach means we don't have to do anything to invalidate 35 * save objects when we do a restore. 36 */ 37 #ifndef alloc_save_t_DEFINED /* also in inamedef.h */ 38 typedef struct alloc_save_s alloc_save_t; 39 # define alloc_save_t_DEFINED 40 #endif 41 42 /* Initialize the save machinery. */ 43 extern void alloc_save_init(gs_dual_memory_t *); 44 45 /* Map a save ID to its save object. Return 0 if the ID is invalid. */ 46 alloc_save_t *alloc_find_save(const gs_dual_memory_t *, ulong); 47 48 /* 49 * Save the state. Return 0 if we can't allocate the save object, 50 * otherwise return the save ID. The second argument is a client data 51 * pointer, assumed to point to an object. 52 */ 53 ulong alloc_save_state(gs_dual_memory_t *, void *); 54 55 /* Get the client pointer passed to alloc_saved_state. */ 56 void *alloc_save_client_data(const alloc_save_t *); 57 58 /* Return (the id of) the innermost externally visible save object. */ 59 ulong alloc_save_current_id(const gs_dual_memory_t *); 60 alloc_save_t *alloc_save_current(const gs_dual_memory_t *); 61 62 /* Check whether a pointer refers to an object allocated since a given save. */ 63 bool alloc_is_since_save(const void *, const alloc_save_t *); 64 65 /* Check whether a name was created since a given save. */ 66 bool alloc_name_is_since_save(const gs_memory_t *mem, const ref *, const alloc_save_t *); 67 bool alloc_name_index_is_since_save(const gs_memory_t *mem, uint, const alloc_save_t *); 68 69 /* 70 * Check whether any names have been created since a given save 71 * that might be released by the restore. 72 */ 73 bool alloc_any_names_since_save(const alloc_save_t *); 74 75 /* 76 * Do one step of restoring the state. Return true if the argument 77 * was the innermost save, in which case this is the last (or only) step. 78 * Assume the caller obtained the argument by calling alloc_find_save; 79 * if this is the case, the operation cannot fail. 80 */ 81 bool alloc_restore_step_in(gs_dual_memory_t *, alloc_save_t *); 82 /* Backward compatibility */ 83 #define alloc_restore_state_step(save) alloc_restore_step_in(idmemory, save) 84 85 /* 86 * Forget a save -- like committing a transaction (restore is like 87 * aborting a transaction). Assume the caller obtained the argument 88 * by calling alloc_find_save. Note that forgetting a save does not 89 * require checking pointers for recency. 90 */ 91 void alloc_forget_save_in(gs_dual_memory_t *, alloc_save_t *); 92 /* Backward compatibility */ 93 #define alloc_forget_save(save) alloc_forget_save_in(idmemory, save) 94 95 /* Release all memory -- like doing a restore "past the bottom". */ 96 void alloc_restore_all(gs_dual_memory_t *); 97 98 /* ------ Internals ------ */ 99 100 /* 101 * If we are in a save, we want to save the old contents if l_new is 102 * not set; if we are not in a save, we never want to save old contents. 103 * We can test this quickly with a single mask that is l_new if we are 104 * in a save, and -1 if we are not, since type_attrs of a valid ref 105 * cannot be 0; this is the test_mask in a gs_dual_memory_t. Similarly, 106 * we want to set the l_new bit in newly allocated objects iff we are in 107 * a save; this is the new_mask in a gs_dual_memory_t. 108 */ 109 110 /* Record that we are in a save. */ 111 void alloc_set_in_save(gs_dual_memory_t *); 112 113 /* Record that we are not in a save. */ 114 void alloc_set_not_in_save(gs_dual_memory_t *); 115 116 /* Remove entries from font and character caches. */ 117 void font_restore(const alloc_save_t * save); 118 119 #endif /* isave_INCLUDED */ 120