- /* Object is a pointer into from space - not FP. */
-
- first = trans_list(object);
- gc_assert(first != object);
-
- first_pointer = (lispobj *) native_pointer(object);
-
- /* Set forwarding pointer */
- first_pointer[0] = 0x01;
- first_pointer[1] = first;
-
- gc_assert(is_lisp_pointer(first));
- gc_assert(!from_space_p(first));
- *where = first;
- return 1;
-}
-
-static lispobj
-trans_list(lispobj object)
-{
- lispobj new_list_pointer;
- struct cons *cons, *new_cons;
- lispobj cdr;
-
- gc_assert(from_space_p(object));
-
- cons = (struct cons *) native_pointer(object);
-
- /* Copy 'object'. */
- new_cons = (struct cons *) gc_quick_alloc(sizeof(struct cons));
- new_cons->car = cons->car;
- new_cons->cdr = cons->cdr; /* updated later */
- new_list_pointer = (lispobj)new_cons | LowtagOf(object);
-
- /* Grab the cdr before it is clobbered. */
- cdr = cons->cdr;
-
- /* Set forwarding pointer (clobbers start of list). */
- cons->car = 0x01;
- cons->cdr = new_list_pointer;
-
- /* Try to linearize the list in the cdr direction to help reduce
- * paging. */
- while (1) {
- lispobj new_cdr;
- struct cons *cdr_cons, *new_cdr_cons;
-
- if (LowtagOf(cdr) != type_ListPointer || !from_space_p(cdr)
- || (*((lispobj *)native_pointer(cdr)) == 0x01))
- break;
-
- cdr_cons = (struct cons *) native_pointer(cdr);
-
- /* Copy 'cdr'. */
- new_cdr_cons = (struct cons*) gc_quick_alloc(sizeof(struct cons));
- new_cdr_cons->car = cdr_cons->car;
- new_cdr_cons->cdr = cdr_cons->cdr;
- new_cdr = (lispobj)new_cdr_cons | LowtagOf(cdr);
-
- /* Grab the cdr before it is clobbered. */
- cdr = cdr_cons->cdr;
-
- /* Set forwarding pointer. */
- cdr_cons->car = 0x01;
- cdr_cons->cdr = new_cdr;
-
- /* Update the cdr of the last cons copied into new space to
- * keep the newspace scavenge from having to do it. */
- new_cons->cdr = new_cdr;
-
- new_cons = new_cdr_cons;
- }
-
- return new_list_pointer;
-}
-
-\f
-/*
- * scavenging and transporting other pointers
- */
-
-static int
-scav_other_pointer(lispobj *where, lispobj object)
-{
- lispobj first, *first_pointer;
-
- gc_assert(is_lisp_pointer(object));
-
- /* Object is a pointer into from space - not FP. */
- first_pointer = (lispobj *) native_pointer(object);
-
- first = (transother[TypeOf(*first_pointer)])(object);
-
- if (first != object) {
- /* Set forwarding pointer. */
- first_pointer[0] = 0x01;
- first_pointer[1] = first;
- *where = first;
- }
-
- gc_assert(is_lisp_pointer(first));
- gc_assert(!from_space_p(first));
-
- return 1;
-}
-\f
-/*
- * immediate, boxed, and unboxed objects
- */
-
-static int
-size_pointer(lispobj *where)
-{
- return 1;
-}
-
-static int
-scav_immediate(lispobj *where, lispobj object)
-{
- return 1;
-}
-
-static lispobj
-trans_immediate(lispobj object)
-{
- lose("trying to transport an immediate");
- return NIL; /* bogus return value to satisfy static type checking */
-}
-
-static int
-size_immediate(lispobj *where)
-{
- return 1;
-}
-
-
-static int
-scav_boxed(lispobj *where, lispobj object)
-{
- return 1;
-}
-
-static lispobj
-trans_boxed(lispobj object)
-{
- lispobj header;
- unsigned long length;
-
- gc_assert(is_lisp_pointer(object));
-
- header = *((lispobj *) native_pointer(object));
- length = HeaderValue(header) + 1;
- length = CEILING(length, 2);
-
- return copy_object(object, length);
-}
-
-static lispobj
-trans_boxed_large(lispobj object)
-{
- lispobj header;
- unsigned long length;
-
- gc_assert(is_lisp_pointer(object));
-
- header = *((lispobj *) native_pointer(object));
- length = HeaderValue(header) + 1;
- length = CEILING(length, 2);
-
- return copy_large_object(object, length);
-}
-
-static int
-size_boxed(lispobj *where)
-{
- lispobj header;
- unsigned long length;
-
- header = *where;
- length = HeaderValue(header) + 1;
- length = CEILING(length, 2);
-
- return length;
-}
-
-static int
-scav_fdefn(lispobj *where, lispobj object)
-{
- struct fdefn *fdefn;
-
- fdefn = (struct fdefn *)where;
-
- /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n",
- fdefn->function, fdefn->raw_addr)); */
-
- if ((char *)(fdefn->function + RAW_ADDR_OFFSET) == fdefn->raw_addr) {
- scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1);
-
- /* Don't write unnecessarily. */
- if (fdefn->raw_addr != (char *)(fdefn->function + RAW_ADDR_OFFSET))
- fdefn->raw_addr = (char *)(fdefn->function + RAW_ADDR_OFFSET);
-
- return sizeof(struct fdefn) / sizeof(lispobj);
- } else {
- return 1;
- }
-}
-
-static int
-scav_unboxed(lispobj *where, lispobj object)
-{
- unsigned long length;
-
- length = HeaderValue(object) + 1;
- length = CEILING(length, 2);
-
- return length;
-}
-
-static lispobj
-trans_unboxed(lispobj object)
-{
- lispobj header;
- unsigned long length;
-
-
- gc_assert(is_lisp_pointer(object));
-
- header = *((lispobj *) native_pointer(object));
- length = HeaderValue(header) + 1;
- length = CEILING(length, 2);
-
- return copy_unboxed_object(object, length);
-}
-
-static lispobj
-trans_unboxed_large(lispobj object)
-{
- lispobj header;
- unsigned long length;
-
-
- gc_assert(is_lisp_pointer(object));
-
- header = *((lispobj *) native_pointer(object));
- length = HeaderValue(header) + 1;
- length = CEILING(length, 2);
-
- return copy_large_unboxed_object(object, length);
-}
-
-static int
-size_unboxed(lispobj *where)
-{
- lispobj header;
- unsigned long length;
-
- header = *where;
- length = HeaderValue(header) + 1;
- length = CEILING(length, 2);
-
- return length;
-}
-\f
-/*
- * vector-like objects
- */
-
-#define NWORDS(x,y) (CEILING((x),(y)) / (y))
-
-static int
-scav_string(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- /* NOTE: Strings contain one more byte of data than the length */
- /* slot indicates. */
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length) + 1;
- nwords = CEILING(NWORDS(length, 4) + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_string(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- /* NOTE: A string contains one more byte of data (a terminating
- * '\0' to help when interfacing with C functions) than indicated
- * by the length slot. */
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length) + 1;
- nwords = CEILING(NWORDS(length, 4) + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_string(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- /* NOTE: A string contains one more byte of data (a terminating
- * '\0' to help when interfacing with C functions) than indicated
- * by the length slot. */
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length) + 1;
- nwords = CEILING(NWORDS(length, 4) + 2, 2);
-
- return nwords;
-}
-
-/* FIXME: What does this mean? */
-int gencgc_hash = 1;
-
-static int
-scav_vector(lispobj *where, lispobj object)
-{
- unsigned int kv_length;
- lispobj *kv_vector;
- unsigned int length = 0; /* (0 = dummy to stop GCC warning) */
- lispobj *hash_table;
- lispobj empty_symbol;
- unsigned int *index_vector = NULL; /* (NULL = dummy to stop GCC warning) */
- unsigned int *next_vector = NULL; /* (NULL = dummy to stop GCC warning) */
- unsigned int *hash_vector = NULL; /* (NULL = dummy to stop GCC warning) */
- lispobj weak_p_obj;
- unsigned next_vector_length = 0;
-
- /* FIXME: A comment explaining this would be nice. It looks as
- * though SB-VM:VECTOR-VALID-HASHING-SUBTYPE is set for EQ-based
- * hash tables in the Lisp HASH-TABLE code, and nowhere else. */
- if (HeaderValue(object) != subtype_VectorValidHashing)
- return 1;
-
- if (!gencgc_hash) {
- /* This is set for backward compatibility. FIXME: Do we need
- * this any more? */
- *where = (subtype_VectorMustRehash << type_Bits) | type_SimpleVector;
- return 1;
- }
-
- kv_length = fixnum_value(where[1]);
- kv_vector = where + 2; /* Skip the header and length. */
- /*FSHOW((stderr,"/kv_length = %d\n", kv_length));*/
-
- /* Scavenge element 0, which may be a hash-table structure. */
- scavenge(where+2, 1);
- if (!is_lisp_pointer(where[2])) {
- lose("no pointer at %x in hash table", where[2]);
- }
- hash_table = (lispobj *)native_pointer(where[2]);
- /*FSHOW((stderr,"/hash_table = %x\n", hash_table));*/
- if (TypeOf(hash_table[0]) != type_InstanceHeader) {
- lose("hash table not instance (%x at %x)", hash_table[0], hash_table);
- }
-
- /* Scavenge element 1, which should be some internal symbol that
- * the hash table code reserves for marking empty slots. */
- scavenge(where+3, 1);
- if (!is_lisp_pointer(where[3])) {
- lose("not empty-hash-table-slot symbol pointer: %x", where[3]);
- }
- empty_symbol = where[3];
- /* fprintf(stderr,"* empty_symbol = %x\n", empty_symbol);*/
- if (TypeOf(*(lispobj *)native_pointer(empty_symbol)) != type_SymbolHeader) {
- lose("not a symbol where empty-hash-table-slot symbol expected: %x",
- *(lispobj *)native_pointer(empty_symbol));
- }
-
- /* Scavenge hash table, which will fix the positions of the other
- * needed objects. */
- scavenge(hash_table, 16);
-
- /* Cross-check the kv_vector. */
- if (where != (lispobj *)native_pointer(hash_table[9])) {
- lose("hash_table table!=this table %x", hash_table[9]);
- }
-
- /* WEAK-P */
- weak_p_obj = hash_table[10];
-
- /* index vector */
- {
- lispobj index_vector_obj = hash_table[13];
-
- if (is_lisp_pointer(index_vector_obj) &&
- (TypeOf(*(lispobj *)native_pointer(index_vector_obj)) == type_SimpleArrayUnsignedByte32)) {
- index_vector = ((unsigned int *)native_pointer(index_vector_obj)) + 2;
- /*FSHOW((stderr, "/index_vector = %x\n",index_vector));*/
- length = fixnum_value(((unsigned int *)native_pointer(index_vector_obj))[1]);
- /*FSHOW((stderr, "/length = %d\n", length));*/
- } else {
- lose("invalid index_vector %x", index_vector_obj);
- }
- }
-
- /* next vector */
- {
- lispobj next_vector_obj = hash_table[14];
-
- if (is_lisp_pointer(next_vector_obj) &&
- (TypeOf(*(lispobj *)native_pointer(next_vector_obj)) == type_SimpleArrayUnsignedByte32)) {
- next_vector = ((unsigned int *)native_pointer(next_vector_obj)) + 2;
- /*FSHOW((stderr, "/next_vector = %x\n", next_vector));*/
- next_vector_length = fixnum_value(((unsigned int *)native_pointer(next_vector_obj))[1]);
- /*FSHOW((stderr, "/next_vector_length = %d\n", next_vector_length));*/
- } else {
- lose("invalid next_vector %x", next_vector_obj);
- }
- }
-
- /* maybe hash vector */
- {
- /* FIXME: This bare "15" offset should become a symbolic
- * expression of some sort. And all the other bare offsets
- * too. And the bare "16" in scavenge(hash_table, 16). And
- * probably other stuff too. Ugh.. */
- lispobj hash_vector_obj = hash_table[15];
-
- if (is_lisp_pointer(hash_vector_obj) &&
- (TypeOf(*(lispobj *)native_pointer(hash_vector_obj))
- == type_SimpleArrayUnsignedByte32)) {
- hash_vector = ((unsigned int *)native_pointer(hash_vector_obj)) + 2;
- /*FSHOW((stderr, "/hash_vector = %x\n", hash_vector));*/
- gc_assert(fixnum_value(((unsigned int *)native_pointer(hash_vector_obj))[1])
- == next_vector_length);
- } else {
- hash_vector = NULL;
- /*FSHOW((stderr, "/no hash_vector: %x\n", hash_vector_obj));*/
- }
- }
-
- /* These lengths could be different as the index_vector can be a
- * different length from the others, a larger index_vector could help
- * reduce collisions. */
- gc_assert(next_vector_length*2 == kv_length);
-
- /* now all set up.. */
-
- /* Work through the KV vector. */
- {
- int i;
- for (i = 1; i < next_vector_length; i++) {
- lispobj old_key = kv_vector[2*i];
- unsigned int old_index = (old_key & 0x1fffffff)%length;
-
- /* Scavenge the key and value. */
- scavenge(&kv_vector[2*i],2);
-
- /* Check whether the key has moved and is EQ based. */
- {
- lispobj new_key = kv_vector[2*i];
- unsigned int new_index = (new_key & 0x1fffffff)%length;
-
- if ((old_index != new_index) &&
- ((!hash_vector) || (hash_vector[i] == 0x80000000)) &&
- ((new_key != empty_symbol) ||
- (kv_vector[2*i] != empty_symbol))) {
-
- /*FSHOW((stderr,
- "* EQ key %d moved from %x to %x; index %d to %d\n",
- i, old_key, new_key, old_index, new_index));*/
-
- if (index_vector[old_index] != 0) {
- /*FSHOW((stderr, "/P1 %d\n", index_vector[old_index]));*/
-
- /* Unlink the key from the old_index chain. */
- if (index_vector[old_index] == i) {
- /*FSHOW((stderr, "/P2a %d\n", next_vector[i]));*/
- index_vector[old_index] = next_vector[i];
- /* Link it into the needing rehash chain. */
- next_vector[i] = fixnum_value(hash_table[11]);
- hash_table[11] = make_fixnum(i);
- /*SHOW("P2");*/
- } else {
- unsigned prior = index_vector[old_index];
- unsigned next = next_vector[prior];
-
- /*FSHOW((stderr, "/P3a %d %d\n", prior, next));*/
-
- while (next != 0) {
- /*FSHOW((stderr, "/P3b %d %d\n", prior, next));*/
- if (next == i) {
- /* Unlink it. */
- next_vector[prior] = next_vector[next];
- /* Link it into the needing rehash
- * chain. */
- next_vector[next] =
- fixnum_value(hash_table[11]);
- hash_table[11] = make_fixnum(next);
- /*SHOW("/P3");*/
- break;
- }
- prior = next;
- next = next_vector[next];
- }
- }
- }
- }
- }
- }
- }
- return (CEILING(kv_length + 2, 2));
-}
-
-static lispobj
-trans_vector(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
-
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return copy_large_object(object, nwords);
-}
-
-static int
-size_vector(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return nwords;
-}
-
-
-static int
-scav_vector_bit(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 32) + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_bit(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 32) + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_bit(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 32) + 2, 2);
-
- return nwords;
-}
-
-
-static int
-scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 16) + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_unsigned_byte_2(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 16) + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_unsigned_byte_2(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 16) + 2, 2);
-
- return nwords;
-}
-
-
-static int
-scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 8) + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_unsigned_byte_4(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 8) + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_unsigned_byte_4(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 8) + 2, 2);
-
- return nwords;
-}
-
-static int
-scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 4) + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_unsigned_byte_8(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 4) + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_unsigned_byte_8(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 4) + 2, 2);
-
- return nwords;
-}
-
-
-static int
-scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 2) + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_unsigned_byte_16(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 2) + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_unsigned_byte_16(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(NWORDS(length, 2) + 2, 2);
-
- return nwords;
-}
-
-static int
-scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_unsigned_byte_32(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_unsigned_byte_32(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return nwords;
-}
-
-static int
-scav_vector_single_float(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_single_float(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_single_float(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length + 2, 2);
-
- return nwords;
-}
-
-static int
-scav_vector_double_float(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 2 + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_double_float(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 2 + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_double_float(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 2 + 2, 2);
-
- return nwords;
-}
-
-#ifdef type_SimpleArrayLongFloat
-static int
-scav_vector_long_float(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 3 + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_long_float(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 3 + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_long_float(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 3 + 2, 2);
-
- return nwords;
-}
-#endif
-
-
-#ifdef type_SimpleArrayComplexSingleFloat
-static int
-scav_vector_complex_single_float(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 2 + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_complex_single_float(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 2 + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_complex_single_float(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 2 + 2, 2);
-
- return nwords;
-}
-#endif
-
-#ifdef type_SimpleArrayComplexDoubleFloat
-static int
-scav_vector_complex_double_float(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 4 + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_complex_double_float(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 4 + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_complex_double_float(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 4 + 2, 2);
-
- return nwords;
-}
-#endif
-
-
-#ifdef type_SimpleArrayComplexLongFloat
-static int
-scav_vector_complex_long_float(lispobj *where, lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 6 + 2, 2);
-
- return nwords;
-}
-
-static lispobj
-trans_vector_complex_long_float(lispobj object)
-{
- struct vector *vector;
- int length, nwords;
-
- gc_assert(is_lisp_pointer(object));
-
- vector = (struct vector *) native_pointer(object);
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 6 + 2, 2);
-
- return copy_large_unboxed_object(object, nwords);
-}
-
-static int
-size_vector_complex_long_float(lispobj *where)
-{
- struct vector *vector;
- int length, nwords;
-
- vector = (struct vector *) where;
- length = fixnum_value(vector->length);
- nwords = CEILING(length * 6 + 2, 2);
-
- return nwords;
-}
-#endif
-
-\f
-/*
- * weak pointers
- */
-
-/* XX This is a hack adapted from cgc.c. These don't work too well with the
- * gencgc as a list of the weak pointers is maintained within the
- * objects which causes writes to the pages. A limited attempt is made
- * to avoid unnecessary writes, but this needs a re-think. */
-
-#define WEAK_POINTER_NWORDS \
- CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
-
-static int
-scav_weak_pointer(lispobj *where, lispobj object)
-{
- struct weak_pointer *wp = weak_pointers;
- /* Push the weak pointer onto the list of weak pointers.
- * Do I have to watch for duplicates? Originally this was
- * part of trans_weak_pointer but that didn't work in the
- * case where the WP was in a promoted region.
- */
-
- /* Check whether it's already in the list. */
- while (wp != NULL) {
- if (wp == (struct weak_pointer*)where) {
- break;
- }
- wp = wp->next;
- }
- if (wp == NULL) {
- /* Add it to the start of the list. */
- wp = (struct weak_pointer*)where;
- if (wp->next != weak_pointers) {
- wp->next = weak_pointers;
- } else {
- /*SHOW("avoided write to weak pointer");*/
- }
- weak_pointers = wp;
- }
-
- /* Do not let GC scavenge the value slot of the weak pointer.
- * (That is why it is a weak pointer.) */
-
- return WEAK_POINTER_NWORDS;
-}
-
-static lispobj
-trans_weak_pointer(lispobj object)
-{
- lispobj copy;
- /* struct weak_pointer *wp; */
-
- gc_assert(is_lisp_pointer(object));
-
-#if defined(DEBUG_WEAK)
- FSHOW((stderr, "Transporting weak pointer from 0x%08x\n", object));
-#endif
-
- /* Need to remember where all the weak pointers are that have */
- /* been transported so they can be fixed up in a post-GC pass. */
-
- copy = copy_object(object, WEAK_POINTER_NWORDS);
- /* wp = (struct weak_pointer *) native_pointer(copy);*/
-
-
- /* Push the weak pointer onto the list of weak pointers. */
- /* wp->next = weak_pointers;
- * weak_pointers = wp;*/
-
- return copy;
-}
-
-static int
-size_weak_pointer(lispobj *where)
-{
- return WEAK_POINTER_NWORDS;
-}
-
-void scan_weak_pointers(void)
-{
- struct weak_pointer *wp;
- for (wp = weak_pointers; wp != NULL; wp = wp->next) {
- lispobj value = wp->value;
- lispobj *first_pointer;
-
- first_pointer = (lispobj *)native_pointer(value);
-
- /*
- FSHOW((stderr, "/weak pointer at 0x%08x\n", (unsigned long) wp));
- FSHOW((stderr, "/value: 0x%08x\n", (unsigned long) value));
- */
-
- if (is_lisp_pointer(value) && from_space_p(value)) {
- /* Now, we need to check whether the object has been forwarded. If
- * it has been, the weak pointer is still good and needs to be
- * updated. Otherwise, the weak pointer needs to be nil'ed
- * out. */
- if (first_pointer[0] == 0x01) {
- wp->value = first_pointer[1];
- } else {
- /* Break it. */
- SHOW("broken");
- wp->value = NIL;
- wp->broken = T;
- }
- }
- }
-}
-\f
-/*
- * initialization
- */
-
-static int
-scav_lose(lispobj *where, lispobj object)
-{
- lose("no scavenge function for object 0x%08x", (unsigned long) object);
- return 0; /* bogus return value to satisfy static type checking */
-}
-
-static lispobj
-trans_lose(lispobj object)
-{
- lose("no transport function for object 0x%08x", (unsigned long) object);
- return NIL; /* bogus return value to satisfy static type checking */
-}
-
-static int
-size_lose(lispobj *where)
-{
- lose("no size function for object at 0x%08x", (unsigned long) where);
- return 1; /* bogus return value to satisfy static type checking */
-}
-
-static void
-gc_init_tables(void)
-{
- int i;
-
- /* Set default value in all slots of scavenge table. */
- for (i = 0; i < 256; i++) { /* FIXME: bare constant length, ick! */
- scavtab[i] = scav_lose;
- }
-
- /* For each type which can be selected by the low 3 bits of the tag
- * alone, set multiple entries in our 8-bit scavenge table (one for each
- * possible value of the high 5 bits). */
- for (i = 0; i < 32; i++) { /* FIXME: bare constant length, ick! */
- scavtab[type_EvenFixnum|(i<<3)] = scav_immediate;
- scavtab[type_FunctionPointer|(i<<3)] = scav_function_pointer;
- /* OtherImmediate0 */
- scavtab[type_ListPointer|(i<<3)] = scav_list_pointer;
- scavtab[type_OddFixnum|(i<<3)] = scav_immediate;
- scavtab[type_InstancePointer|(i<<3)] = scav_instance_pointer;
- /* OtherImmediate1 */
- scavtab[type_OtherPointer|(i<<3)] = scav_other_pointer;
- }
-
- /* Other-pointer types (those selected by all eight bits of the tag) get
- * one entry each in the scavenge table. */
- scavtab[type_Bignum] = scav_unboxed;
- scavtab[type_Ratio] = scav_boxed;
- scavtab[type_SingleFloat] = scav_unboxed;
- scavtab[type_DoubleFloat] = scav_unboxed;
-#ifdef type_LongFloat
- scavtab[type_LongFloat] = scav_unboxed;
-#endif
- scavtab[type_Complex] = scav_boxed;
-#ifdef type_ComplexSingleFloat
- scavtab[type_ComplexSingleFloat] = scav_unboxed;
-#endif
-#ifdef type_ComplexDoubleFloat
- scavtab[type_ComplexDoubleFloat] = scav_unboxed;
-#endif
-#ifdef type_ComplexLongFloat
- scavtab[type_ComplexLongFloat] = scav_unboxed;
-#endif
- scavtab[type_SimpleArray] = scav_boxed;
- scavtab[type_SimpleString] = scav_string;
- scavtab[type_SimpleBitVector] = scav_vector_bit;
- scavtab[type_SimpleVector] = scav_vector;
- scavtab[type_SimpleArrayUnsignedByte2] = scav_vector_unsigned_byte_2;
- scavtab[type_SimpleArrayUnsignedByte4] = scav_vector_unsigned_byte_4;
- scavtab[type_SimpleArrayUnsignedByte8] = scav_vector_unsigned_byte_8;
- scavtab[type_SimpleArrayUnsignedByte16] = scav_vector_unsigned_byte_16;
- scavtab[type_SimpleArrayUnsignedByte32] = scav_vector_unsigned_byte_32;
-#ifdef type_SimpleArraySignedByte8
- scavtab[type_SimpleArraySignedByte8] = scav_vector_unsigned_byte_8;
-#endif
-#ifdef type_SimpleArraySignedByte16
- scavtab[type_SimpleArraySignedByte16] = scav_vector_unsigned_byte_16;
-#endif
-#ifdef type_SimpleArraySignedByte30
- scavtab[type_SimpleArraySignedByte30] = scav_vector_unsigned_byte_32;
-#endif
-#ifdef type_SimpleArraySignedByte32
- scavtab[type_SimpleArraySignedByte32] = scav_vector_unsigned_byte_32;
-#endif
- scavtab[type_SimpleArraySingleFloat] = scav_vector_single_float;
- scavtab[type_SimpleArrayDoubleFloat] = scav_vector_double_float;
-#ifdef type_SimpleArrayLongFloat
- scavtab[type_SimpleArrayLongFloat] = scav_vector_long_float;
-#endif
-#ifdef type_SimpleArrayComplexSingleFloat
- scavtab[type_SimpleArrayComplexSingleFloat] = scav_vector_complex_single_float;
-#endif
-#ifdef type_SimpleArrayComplexDoubleFloat
- scavtab[type_SimpleArrayComplexDoubleFloat] = scav_vector_complex_double_float;
-#endif
-#ifdef type_SimpleArrayComplexLongFloat
- scavtab[type_SimpleArrayComplexLongFloat] = scav_vector_complex_long_float;
-#endif
- scavtab[type_ComplexString] = scav_boxed;
- scavtab[type_ComplexBitVector] = scav_boxed;
- scavtab[type_ComplexVector] = scav_boxed;
- scavtab[type_ComplexArray] = scav_boxed;
- scavtab[type_CodeHeader] = scav_code_header;
- /*scavtab[type_FunctionHeader] = scav_function_header;*/
- /*scavtab[type_ClosureFunctionHeader] = scav_function_header;*/
- /*scavtab[type_ReturnPcHeader] = scav_return_pc_header;*/
-#ifdef __i386__
- scavtab[type_ClosureHeader] = scav_closure_header;
- scavtab[type_FuncallableInstanceHeader] = scav_closure_header;
- scavtab[type_ByteCodeFunction] = scav_closure_header;
- scavtab[type_ByteCodeClosure] = scav_closure_header;
-#else
- scavtab[type_ClosureHeader] = scav_boxed;
- scavtab[type_FuncallableInstanceHeader] = scav_boxed;
- scavtab[type_ByteCodeFunction] = scav_boxed;
- scavtab[type_ByteCodeClosure] = scav_boxed;
-#endif
- scavtab[type_ValueCellHeader] = scav_boxed;
- scavtab[type_SymbolHeader] = scav_boxed;
- scavtab[type_BaseChar] = scav_immediate;
- scavtab[type_Sap] = scav_unboxed;
- scavtab[type_UnboundMarker] = scav_immediate;
- scavtab[type_WeakPointer] = scav_weak_pointer;
- scavtab[type_InstanceHeader] = scav_boxed;
- scavtab[type_Fdefn] = scav_fdefn;
-
- /* transport other table, initialized same way as scavtab */
- for (i = 0; i < 256; i++)
- transother[i] = trans_lose;
- transother[type_Bignum] = trans_unboxed;
- transother[type_Ratio] = trans_boxed;
- transother[type_SingleFloat] = trans_unboxed;
- transother[type_DoubleFloat] = trans_unboxed;
-#ifdef type_LongFloat
- transother[type_LongFloat] = trans_unboxed;
-#endif
- transother[type_Complex] = trans_boxed;
-#ifdef type_ComplexSingleFloat
- transother[type_ComplexSingleFloat] = trans_unboxed;
-#endif
-#ifdef type_ComplexDoubleFloat
- transother[type_ComplexDoubleFloat] = trans_unboxed;
-#endif
-#ifdef type_ComplexLongFloat
- transother[type_ComplexLongFloat] = trans_unboxed;
-#endif
- transother[type_SimpleArray] = trans_boxed_large;
- transother[type_SimpleString] = trans_string;
- transother[type_SimpleBitVector] = trans_vector_bit;
- transother[type_SimpleVector] = trans_vector;
- transother[type_SimpleArrayUnsignedByte2] = trans_vector_unsigned_byte_2;
- transother[type_SimpleArrayUnsignedByte4] = trans_vector_unsigned_byte_4;
- transother[type_SimpleArrayUnsignedByte8] = trans_vector_unsigned_byte_8;
- transother[type_SimpleArrayUnsignedByte16] = trans_vector_unsigned_byte_16;
- transother[type_SimpleArrayUnsignedByte32] = trans_vector_unsigned_byte_32;
-#ifdef type_SimpleArraySignedByte8
- transother[type_SimpleArraySignedByte8] = trans_vector_unsigned_byte_8;
-#endif
-#ifdef type_SimpleArraySignedByte16
- transother[type_SimpleArraySignedByte16] = trans_vector_unsigned_byte_16;
-#endif
-#ifdef type_SimpleArraySignedByte30
- transother[type_SimpleArraySignedByte30] = trans_vector_unsigned_byte_32;
-#endif
-#ifdef type_SimpleArraySignedByte32
- transother[type_SimpleArraySignedByte32] = trans_vector_unsigned_byte_32;
-#endif
- transother[type_SimpleArraySingleFloat] = trans_vector_single_float;
- transother[type_SimpleArrayDoubleFloat] = trans_vector_double_float;
-#ifdef type_SimpleArrayLongFloat
- transother[type_SimpleArrayLongFloat] = trans_vector_long_float;
-#endif
-#ifdef type_SimpleArrayComplexSingleFloat
- transother[type_SimpleArrayComplexSingleFloat] = trans_vector_complex_single_float;
-#endif
-#ifdef type_SimpleArrayComplexDoubleFloat
- transother[type_SimpleArrayComplexDoubleFloat] = trans_vector_complex_double_float;
-#endif
-#ifdef type_SimpleArrayComplexLongFloat
- transother[type_SimpleArrayComplexLongFloat] = trans_vector_complex_long_float;
-#endif
- transother[type_ComplexString] = trans_boxed;
- transother[type_ComplexBitVector] = trans_boxed;
- transother[type_ComplexVector] = trans_boxed;
- transother[type_ComplexArray] = trans_boxed;
- transother[type_CodeHeader] = trans_code_header;
- transother[type_FunctionHeader] = trans_function_header;
- transother[type_ClosureFunctionHeader] = trans_function_header;
- transother[type_ReturnPcHeader] = trans_return_pc_header;
- transother[type_ClosureHeader] = trans_boxed;
- transother[type_FuncallableInstanceHeader] = trans_boxed;
- transother[type_ByteCodeFunction] = trans_boxed;
- transother[type_ByteCodeClosure] = trans_boxed;
- transother[type_ValueCellHeader] = trans_boxed;
- transother[type_SymbolHeader] = trans_boxed;
- transother[type_BaseChar] = trans_immediate;
- transother[type_Sap] = trans_unboxed;
- transother[type_UnboundMarker] = trans_immediate;
- transother[type_WeakPointer] = trans_weak_pointer;
- transother[type_InstanceHeader] = trans_boxed;
- transother[type_Fdefn] = trans_boxed;
-
- /* size table, initialized the same way as scavtab */
- for (i = 0; i < 256; i++)
- sizetab[i] = size_lose;
- for (i = 0; i < 32; i++) {
- sizetab[type_EvenFixnum|(i<<3)] = size_immediate;
- sizetab[type_FunctionPointer|(i<<3)] = size_pointer;
- /* OtherImmediate0 */
- sizetab[type_ListPointer|(i<<3)] = size_pointer;
- sizetab[type_OddFixnum|(i<<3)] = size_immediate;
- sizetab[type_InstancePointer|(i<<3)] = size_pointer;
- /* OtherImmediate1 */
- sizetab[type_OtherPointer|(i<<3)] = size_pointer;
- }
- sizetab[type_Bignum] = size_unboxed;
- sizetab[type_Ratio] = size_boxed;
- sizetab[type_SingleFloat] = size_unboxed;
- sizetab[type_DoubleFloat] = size_unboxed;
-#ifdef type_LongFloat
- sizetab[type_LongFloat] = size_unboxed;
-#endif
- sizetab[type_Complex] = size_boxed;
-#ifdef type_ComplexSingleFloat
- sizetab[type_ComplexSingleFloat] = size_unboxed;
-#endif
-#ifdef type_ComplexDoubleFloat
- sizetab[type_ComplexDoubleFloat] = size_unboxed;
-#endif
-#ifdef type_ComplexLongFloat
- sizetab[type_ComplexLongFloat] = size_unboxed;
-#endif
- sizetab[type_SimpleArray] = size_boxed;
- sizetab[type_SimpleString] = size_string;
- sizetab[type_SimpleBitVector] = size_vector_bit;
- sizetab[type_SimpleVector] = size_vector;
- sizetab[type_SimpleArrayUnsignedByte2] = size_vector_unsigned_byte_2;
- sizetab[type_SimpleArrayUnsignedByte4] = size_vector_unsigned_byte_4;
- sizetab[type_SimpleArrayUnsignedByte8] = size_vector_unsigned_byte_8;
- sizetab[type_SimpleArrayUnsignedByte16] = size_vector_unsigned_byte_16;
- sizetab[type_SimpleArrayUnsignedByte32] = size_vector_unsigned_byte_32;
-#ifdef type_SimpleArraySignedByte8
- sizetab[type_SimpleArraySignedByte8] = size_vector_unsigned_byte_8;
-#endif
-#ifdef type_SimpleArraySignedByte16
- sizetab[type_SimpleArraySignedByte16] = size_vector_unsigned_byte_16;
-#endif
-#ifdef type_SimpleArraySignedByte30
- sizetab[type_SimpleArraySignedByte30] = size_vector_unsigned_byte_32;
-#endif
-#ifdef type_SimpleArraySignedByte32
- sizetab[type_SimpleArraySignedByte32] = size_vector_unsigned_byte_32;
-#endif
- sizetab[type_SimpleArraySingleFloat] = size_vector_single_float;
- sizetab[type_SimpleArrayDoubleFloat] = size_vector_double_float;
-#ifdef type_SimpleArrayLongFloat
- sizetab[type_SimpleArrayLongFloat] = size_vector_long_float;
-#endif
-#ifdef type_SimpleArrayComplexSingleFloat
- sizetab[type_SimpleArrayComplexSingleFloat] = size_vector_complex_single_float;
-#endif
-#ifdef type_SimpleArrayComplexDoubleFloat
- sizetab[type_SimpleArrayComplexDoubleFloat] = size_vector_complex_double_float;
-#endif
-#ifdef type_SimpleArrayComplexLongFloat
- sizetab[type_SimpleArrayComplexLongFloat] = size_vector_complex_long_float;
-#endif
- sizetab[type_ComplexString] = size_boxed;
- sizetab[type_ComplexBitVector] = size_boxed;
- sizetab[type_ComplexVector] = size_boxed;
- sizetab[type_ComplexArray] = size_boxed;
- sizetab[type_CodeHeader] = size_code_header;
-#if 0
- /* We shouldn't see these, so just lose if it happens. */
- sizetab[type_FunctionHeader] = size_function_header;
- sizetab[type_ClosureFunctionHeader] = size_function_header;
- sizetab[type_ReturnPcHeader] = size_return_pc_header;
-#endif
- sizetab[type_ClosureHeader] = size_boxed;
- sizetab[type_FuncallableInstanceHeader] = size_boxed;
- sizetab[type_ValueCellHeader] = size_boxed;
- sizetab[type_SymbolHeader] = size_boxed;
- sizetab[type_BaseChar] = size_immediate;
- sizetab[type_Sap] = size_unboxed;
- sizetab[type_UnboundMarker] = size_immediate;
- sizetab[type_WeakPointer] = size_weak_pointer;
- sizetab[type_InstanceHeader] = size_boxed;
- sizetab[type_Fdefn] = size_boxed;
-}
-\f
-/* Scan an area looking for an object which encloses the given pointer.
- * Return the object start on success or NULL on failure. */
-static lispobj *
-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)
- || ((thing & 3) == 0) /* fixnum */
- || (TypeOf(thing) == type_BaseChar)
- || (TypeOf(thing) == type_UnboundMarker))
- count = 2;
- else
- count = (sizetab[TypeOf(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);
-}
-
-static lispobj*
-search_read_only_space(lispobj *pointer)
-{
- lispobj* start = (lispobj*)READ_ONLY_SPACE_START;
- lispobj* end = (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER);
- if ((pointer < start) || (pointer >= end))
- return NULL;
- return (search_space(start, (pointer+2)-start, pointer));
-}
-
-static lispobj *
-search_static_space(lispobj *pointer)
-{
- lispobj* start = (lispobj*)STATIC_SPACE_START;
- lispobj* end = (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER);
- if ((pointer < start) || (pointer >= end))
- return NULL;
- return (search_space(start, (pointer+2)-start, pointer));
-}
-
-/* a faster version for searching the dynamic space. This will work even
- * if the object is in a current allocation region. */
-lispobj *
-search_dynamic_space(lispobj *pointer)
-{
- int page_index = find_page_index(pointer);
- lispobj *start;
-
- /* The address may be invalid, so do some checks. */
- if ((page_index == -1) || (page_table[page_index].allocated == FREE_PAGE))
- return NULL;
- start = (lispobj *)((void *)page_address(page_index)
- + page_table[page_index].first_object_offset);
- return (search_space(start, (pointer+2)-start, pointer));
-}
-
-/* Is there any possibility that pointer is a valid Lisp object
- * reference, and/or something else (e.g. subroutine call return
- * address) which should prevent us from moving the referred-to thing? */
-static int
-possibly_valid_dynamic_space_pointer(lispobj *pointer)
-{
- lispobj *start_addr;
-
- /* Find the object start address. */
- if ((start_addr = search_dynamic_space(pointer)) == NULL) {
- return 0;
- }
-
- /* We need to allow raw pointers into Code objects for return
- * addresses. This will also pick up pointers to functions in code
- * objects. */
- if (TypeOf(*start_addr) == type_CodeHeader) {
- /* XXX could do some further checks here */
- return 1;
- }
-
- /* If it's not a return address then it needs to be a valid Lisp
- * pointer. */
- if (!is_lisp_pointer((lispobj)pointer)) {
- return 0;
- }