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