static void display_banner (void) { printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string)); printf(RELOC("Board: " CONFIG_BOARDINFO "\n")); }
/* untraced space, so relocate all refs, not just marked ones. */ void igc_reloc_refs(ref_packed * from, ref_packed * to, gc_state_t * gcst) { int min_trace = gcst->min_collect; ref_packed *rp = from; bool do_all = gcst->relocating_untraced; vm_spaces spaces = gcst->spaces; const gs_memory_t *cmem = space_system->stable_memory; while (rp < to) { ref *pref; #ifdef DEBUG const void *before = 0; const void *after = 0; # define DO_RELOC(var, stat)\ BEGIN before = (var); stat; after = (var); END # define SET_RELOC(var, expr)\ BEGIN before = (var); after = (var) = (expr); END #else # define DO_RELOC(var, stat) stat # define SET_RELOC(var, expr) var = expr #endif if (r_is_packed(rp)) { rp++; continue; } /* The following assignment is logically unnecessary; */ /* we do it only for convenience in debugging. */ pref = (ref *) rp; if_debug3('8', " [8]relocating %s %d ref at 0x%lx\n", (r_has_attr(pref, l_mark) ? "marked" : "unmarked"), r_btype(pref), (ulong) pref); if ((r_has_attr(pref, l_mark) || do_all) && r_space(pref) >= min_trace ) { switch (r_type(pref)) { /* Struct cases */ case t_file: DO_RELOC(pref->value.pfile, RELOC_VAR(pref->value.pfile)); break; case t_device: DO_RELOC(pref->value.pdevice, RELOC_VAR(pref->value.pdevice)); break; case t_fontID: case t_struct: case t_astruct: DO_RELOC(pref->value.pstruct, RELOC_VAR(pref->value.pstruct)); break; /* Non-trivial non-struct cases */ case t_dictionary: rputc('d'); SET_RELOC(pref->value.pdict, (dict *)igc_reloc_ref_ptr((ref_packed *)pref->value.pdict, gcst)); break; case t_array: { uint size = r_size(pref); if (size != 0) { /* value.refs might be NULL */ /* * If the array is large, we allocated it in its * own object (at least originally -- this might * be a pointer to a subarray.) In this case, * we know it is the only object in its * containing st_refs object, so we know that * the mark containing the relocation appears * just after it. */ if (size < max_size_st_refs / sizeof(ref)) { rputc('a'); SET_RELOC(pref->value.refs, (ref *) igc_reloc_ref_ptr( (ref_packed *) pref->value.refs, gcst)); } else { rputc('A'); /* * See the t_shortarray case below for why we * decrement size. */ --size; SET_RELOC(pref->value.refs, (ref *) igc_reloc_ref_ptr( (ref_packed *) (pref->value.refs + size), gcst) - size); } } } break; case t_mixedarray: if (r_size(pref) != 0) { /* value.refs might be NULL */ rputc('m'); SET_RELOC(pref->value.packed, igc_reloc_ref_ptr(pref->value.packed, gcst)); } break; case t_shortarray: { uint size = r_size(pref); /* * Since we know that igc_reloc_ref_ptr works by * scanning forward, and we know that all the * elements of this array itself are marked, we can * save some scanning time by relocating the pointer * to the end of the array rather than the * beginning. */ if (size != 0) { /* value.refs might be NULL */ rputc('s'); /* * igc_reloc_ref_ptr has to be able to determine * whether the pointer points into a space that * isn't being collected. It does this by * checking whether the referent of the pointer * is marked. For this reason, we have to pass * a pointer to the last real element of the * array, rather than just beyond it. */ --size; SET_RELOC(pref->value.packed, igc_reloc_ref_ptr(pref->value.packed + size, gcst) - size); } } break; case t_name: { void *psub = name_ref_sub_table(cmem, pref); void *rsub = RELOC_OBJ(psub); /* gcst implicit */ SET_RELOC(pref->value.pname, (name *) ((char *)rsub + ((char *)pref->value.pname - (char *)psub))); } break; case t_string: { gs_string str; str.data = pref->value.bytes; str.size = r_size(pref); DO_RELOC(str.data, RELOC_STRING_VAR(str)); pref->value.bytes = str.data; } break; case t_oparray: rputc('o'); SET_RELOC(pref->value.const_refs, (const ref *)igc_reloc_ref_ptr((const ref_packed *)pref->value.const_refs, gcst)); break; default: goto no_reloc; /* don't print trace message */ } if_debug2('8', " [8]relocated 0x%lx => 0x%lx\n", (ulong)before, (ulong)after); } no_reloc: rp += packed_per_ref; } }