X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgc-common.c;h=8e8b3fa244598cc0e8e871ee1afc66fcc7289871;hb=e3547b45241fdc4a2aaab382f1e7e8f71566beba;hp=946873cacaa116336cdad2ba9281c87dc2616a1f;hpb=a3649ba68e298d9203e8bb1de5629ff788586fe1;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 946873c..8e8b3fa 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -41,6 +41,7 @@ #include "gc.h" #include "genesis/primitive-objects.h" #include "genesis/static-symbols.h" +#include "genesis/layout.h" #include "gc-internal.h" #ifdef LISP_FEATURE_SPARC @@ -382,7 +383,7 @@ size_code_header(lispobj *where) return nwords; } -#ifndef LISP_FEATURE_X86 || LISP_FEATURE_X86_64 +#if !defined(LISP_FEATURE_X86) && ! defined(LISP_FEATURE_X86_64) static long scav_return_pc_header(lispobj *where, lispobj object) { @@ -643,6 +644,24 @@ scav_boxed(lispobj *where, lispobj object) return 1; } +static long +scav_instance(lispobj *where, lispobj object) +{ + lispobj nuntagged; + long ntotal = HeaderValue(object); + lispobj layout = ((struct instance *)native_pointer(where))->slots[0]; + + if (!layout) + return 1; + if (forwarding_pointer_p(native_pointer(layout))) + layout = (lispobj) forwarding_pointer_value(native_pointer(layout)); + + nuntagged = ((struct layout *)native_pointer(layout))->n_untagged_slots; + scavenge(where + 1, ntotal - fixnum_value(nuntagged)); + + return ntotal + 1; +} + static lispobj trans_boxed(lispobj object) { @@ -1708,7 +1727,7 @@ gc_init_tables(void) scavtab[CHARACTER_WIDETAG] = scav_immediate; scavtab[SAP_WIDETAG] = scav_unboxed; scavtab[UNBOUND_MARKER_WIDETAG] = scav_immediate; - scavtab[INSTANCE_HEADER_WIDETAG] = scav_boxed; + scavtab[INSTANCE_HEADER_WIDETAG] = scav_instance; #ifdef LISP_FEATURE_SPARC scavtab[FDEFN_WIDETAG] = scav_boxed; #else @@ -2007,3 +2026,40 @@ component_ptr_from_pc(lispobj *pc) return (NULL); } + +/* Scan an area looking for an object which encloses the given pointer. + * Return the object start on success or NULL on failure. */ +lispobj * +gc_search_space(lispobj *start, size_t words, lispobj *pointer) +{ + while (words > 0) { + size_t count = 1; + lispobj thing = *start; + + /* If thing is an immediate then this is a cons. */ + if (is_lisp_pointer(thing) + || (fixnump(thing)) + || (widetag_of(thing) == CHARACTER_WIDETAG) +#if N_WORD_BITS == 64 + || (widetag_of(thing) == SINGLE_FLOAT_WIDETAG) +#endif + || (widetag_of(thing) == UNBOUND_MARKER_WIDETAG)) + count = 2; + else + count = (sizetab[widetag_of(thing)])(start); + + /* Check whether the pointer is within this object. */ + if ((pointer >= start) && (pointer < (start+count))) { + /* found it! */ + /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/ + return(start); + } + + /* Round up the count. */ + count = CEILING(count,2); + + start += count; + words -= count; + } + return (NULL); +}