1 /* Copyright (C) 1995, 1996, 1999, 2002 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: gxobj.h,v 1.7 2005/10/12 10:45:21 leonardo Exp $ */ 18 /* Memory manager implementation structures for Ghostscript */ 19 20 #ifndef gxobj_INCLUDED 21 # define gxobj_INCLUDED 22 23 #include "gxbitmap.h" 24 25 #ifdef DEBUG 26 #define IGC_PTR_STABILITY_CHECK 0 27 #else 28 #define IGC_PTR_STABILITY_CHECK 0 29 #endif 30 31 /* ================ Objects ================ */ 32 33 /* 34 * Object headers have the form: 35 -l- -mark/back- 36 -size- 37 -type/reloc- 38 * l (aLone) is a single bit. Mark/back is 1 bit shorter than a uint. We 39 * round the header size up to the next multiple of the most severe 40 * alignment restriction (4 or 8 bytes). 41 * 42 * The mark/back field is used for the mark during the marking phase of 43 * garbage collection, and for a back pointer value during the compaction 44 * phase. Since we want to be able to collect local VM independently of 45 * global VM, we need two different distinguished mark values: 46 * - For local objects that have not been traced and should be freed 47 * (compacted out), we use 1...11 in the mark field (o_unmarked). 48 * - For global objects that have not been traced but should be kept, 49 * we use 1...10 in the mark field (o_untraced). 50 * Note that neither of these values is a possible real relocation value. 51 * 52 * The back pointer's meaning depends on whether the object is 53 * free (unmarked) or in use (marked): 54 * - In free objects, the back pointer is an offset from the object 55 * header back to a chunk_head_t structure that contains the location 56 * to which all the data in this chunk will get moved; the reloc field 57 * contains the amount by which the following run of useful objects 58 * will be relocated downwards. 59 * - In useful objects, the back pointer is an offset from the object 60 * back to the previous free object; the reloc field is not used (it 61 * overlays the type field). 62 * These two cases can be distinguished when scanning a chunk linearly, 63 * but when simply examining an object via a pointer, the chunk pointer 64 * is also needed. 65 */ 66 #define obj_flag_bits 1 67 #define obj_mb_bits (arch_sizeof_int * 8 - obj_flag_bits) 68 #define o_unmarked (((uint)1 << obj_mb_bits) - 1) 69 #define o_set_unmarked(pp)\ 70 ((pp)->o_smark = o_unmarked) 71 #define o_is_unmarked(pp)\ 72 ((pp)->o_smark == o_unmarked) 73 #define o_untraced (((uint)1 << obj_mb_bits) - 2) 74 #define o_set_untraced(pp)\ 75 ((pp)->o_smark = o_untraced) 76 #define o_is_untraced(pp)\ 77 ((pp)->o_smark == o_untraced) 78 #define o_marked 0 79 #define o_mark(pp)\ 80 ((pp)->o_smark = o_marked) 81 #define obj_back_shift obj_flag_bits 82 #define obj_back_scale (1 << obj_back_shift) 83 typedef struct obj_header_data_s { 84 union _f { 85 struct _h { 86 unsigned alone:1; 87 } h; 88 struct _m { 89 unsigned _:1, smark:obj_mb_bits; 90 } m; 91 struct _b { 92 unsigned _:1, back:obj_mb_bits; 93 } b; 94 } f; 95 uint size; 96 union _t { 97 gs_memory_type_ptr_t type; 98 uint reloc; 99 } t; 100 # if IGC_PTR_STABILITY_CHECK 101 unsigned space_id:3; /* r_space_bits + 1 bit for "instability". */ 102 # endif 103 } obj_header_data_t; 104 105 /* 106 * Define the alignment modulus for aligned objects. We assume all 107 * alignment values are powers of 2; we can avoid nested 'max'es that way. 108 * The final | is because back pointer values are divided by obj_back_scale, 109 * so objects must be aligned at least 0 mod obj_back_scale. 110 * 111 * Note: OBJECTS ARE NOT GUARANTEED to be aligned any more strictly than 112 * required by the hardware, regardless of the value of obj_align_mod. 113 * See gsmemraw.h for more information about this. 114 */ 115 #define obj_align_mod\ 116 (((arch_align_memory_mod - 1) |\ 117 (align_bitmap_mod - 1) |\ 118 (obj_back_scale - 1)) + 1) 119 /* The only possible values for obj_align_mod are 4, 8, or 16.... */ 120 #if obj_align_mod == 4 121 # define log2_obj_align_mod 2 122 #else 123 #if obj_align_mod == 8 124 # define log2_obj_align_mod 3 125 #else 126 #if obj_align_mod == 16 127 # define log2_obj_align_mod 4 128 #endif 129 #endif 130 #endif 131 #define obj_align_mask (obj_align_mod-1) 132 #define obj_align_round(siz)\ 133 (uint)(((siz) + obj_align_mask) & -obj_align_mod) 134 #define obj_size_round(siz)\ 135 obj_align_round((siz) + sizeof(obj_header_t)) 136 137 /* Define the real object header type, taking alignment into account. */ 138 struct obj_header_s { /* must be a struct because of forward reference */ 139 union _d { 140 obj_header_data_t o; 141 byte _pad[ROUND_UP(sizeof(obj_header_data_t), obj_align_mod)]; 142 } 143 d; 144 }; 145 146 /* Define some reasonable abbreviations for the fields. */ 147 #define o_alone d.o.f.h.alone 148 #define o_back d.o.f.b.back 149 #define o_smark d.o.f.m.smark 150 #define o_size d.o.size 151 #define o_type d.o.t.type 152 #define o_nreloc d.o.t.reloc 153 154 /* 155 * The macros for getting the sizes of objects all take pointers to 156 * the object header, for use when scanning storage linearly. 157 */ 158 #define pre_obj_contents_size(pp)\ 159 ((pp)->o_size) 160 161 #define pre_obj_rounded_size(pp)\ 162 obj_size_round(pre_obj_contents_size(pp)) 163 #define pre_obj_next(pp)\ 164 ((obj_header_t *)((byte *)(pp) + obj_align_round(\ 165 pre_obj_contents_size(pp) + sizeof(obj_header_t) ))) 166 167 /* 168 * Define the header that free objects point back to when relocating. 169 * Every chunk, including inner chunks, has one of these. 170 */ 171 typedef struct chunk_head_s { 172 byte *dest; /* destination for objects */ 173 #if obj_align_mod > arch_sizeof_ptr 174 byte *_pad[obj_align_mod / arch_sizeof_ptr - 1]; 175 #endif 176 obj_header_t free; /* header for a free object, */ 177 /* in case the first real object */ 178 /* is in use */ 179 } chunk_head_t; 180 181 #endif /* gxobj_INCLUDED */ 182