-#ifndef __i386__
- /* KLUDGE: This has an implicit dependence on the ordering of
- * address spaces, and is therefore basically wrong. I'd fix it,
- * but I don't have a non-386 port to test it on. Porters are
- * encouraged to fix it. -- WHN 2000-10-17 */
- return (ptr >= (lispobj)DYNAMIC_SPACE_START);
-#else
- /* Be more conservative, and remember, this is a maybe. */
- return (ptr >= (lispobj)DYNAMIC_SPACE_START
- &&
- ptr < (lispobj)dynamic_space_free_pointer);
-#endif
-}
-
-\f
-#ifdef __i386__
-
-#ifdef GENCGC
-/*
- * enhanced x86/GENCGC stack scavenging by Douglas Crosher
- *
- * Scavenging the stack on the i386 is problematic due to conservative
- * roots and raw return addresses. Here it is handled in two passes:
- * the first pass runs before any objects are moved and tries to
- * identify valid pointers and return address on the stack, the second
- * pass scavenges these.
- */
-
-static unsigned pointer_filter_verbose = 0;
-
-/* FIXME: This is substantially the same code as in gencgc.c. (There
- * are some differences, at least (1) the gencgc.c code needs to worry
- * about return addresses on the stack pinning code objects, (2) the
- * gencgc.c code needs to worry about the GC maybe happening in an
- * interrupt service routine when the main thread of control was
- * interrupted just as it had allocated memory and before it
- * initialized it, while PURIFY needn't worry about that, and (3) the
- * gencgc.c code has mutated more under maintenance since the fork
- * from CMU CL than the code here has.) The two versions should be
- * made to explicitly share common code, instead of just two different
- * cut-and-pasted versions. */
-static int
-valid_dynamic_space_pointer(lispobj *pointer, lispobj *start_addr)
-{
- /* If it's not a return address then it needs to be a valid Lisp
- * pointer. */
- if (!is_lisp_pointer((lispobj)pointer))
- return 0;
-
- /* Check that the object pointed to is consistent with the pointer
- * low tag. */
- switch (lowtagof((lispobj)pointer)) {
- case FUN_POINTER_LOWTAG:
- /* Start_addr should be the enclosing code object, or a closure
- * header. */
- switch (TypeOf(*start_addr)) {
- case type_CodeHeader:
- /* This case is probably caught above. */
- break;
- case type_ClosureHeader:
- case type_FuncallableInstanceHeader:
- if ((int)pointer != ((int)start_addr+FUN_POINTER_LOWTAG)) {
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wf2: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- break;
- default:
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wf3: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- break;
- case LIST_POINTER_LOWTAG:
- if ((int)pointer != ((int)start_addr+LIST_POINTER_LOWTAG)) {
- if (pointer_filter_verbose)
- fprintf(stderr,"*Wl1: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- return 0;
- }
- /* Is it plausible cons? */
- if((is_lisp_pointer(start_addr[0])
- || ((start_addr[0] & 3) == 0) /* fixnum */
- || (TypeOf(start_addr[0]) == type_BaseChar)
- || (TypeOf(start_addr[0]) == type_UnboundMarker))
- && (is_lisp_pointer(start_addr[1])
- || ((start_addr[1] & 3) == 0) /* fixnum */
- || (TypeOf(start_addr[1]) == type_BaseChar)
- || (TypeOf(start_addr[1]) == type_UnboundMarker))) {
- break;
- } else {
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wl2: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- case INSTANCE_POINTER_LOWTAG:
- if ((int)pointer != ((int)start_addr+INSTANCE_POINTER_LOWTAG)) {
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wi1: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- if (TypeOf(start_addr[0]) != type_InstanceHeader) {
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wi2: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- break;
- case OTHER_POINTER_LOWTAG:
- if ((int)pointer != ((int)start_addr+OTHER_POINTER_LOWTAG)) {
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wo1: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- /* Is it plausible? Not a cons. X should check the headers. */
- if(is_lisp_pointer(start_addr[0]) || ((start_addr[0] & 3) == 0)) {
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wo2: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- switch (TypeOf(start_addr[0])) {
- case type_UnboundMarker:
- case type_BaseChar:
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wo3: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
-
- /* only pointed to by function pointers? */
- case type_ClosureHeader:
- case type_FuncallableInstanceHeader:
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wo4: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
-
- case type_InstanceHeader:
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wo5: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
-
- /* the valid other immediate pointer objects */
- case type_SimpleVector:
- case type_Ratio:
- case type_Complex:
-#ifdef type_ComplexSingleFloat
- case type_ComplexSingleFloat:
-#endif
-#ifdef type_ComplexDoubleFloat
- case type_ComplexDoubleFloat:
-#endif
-#ifdef type_ComplexLongFloat
- case type_ComplexLongFloat:
-#endif
- case type_SimpleArray:
- case type_ComplexString:
- case type_ComplexBitVector:
- case type_ComplexVector:
- case type_ComplexArray:
- case type_ValueCellHeader:
- case type_SymbolHeader:
- case type_Fdefn:
- case type_CodeHeader:
- case type_Bignum:
- case type_SingleFloat:
- case type_DoubleFloat:
-#ifdef type_LongFloat
- case type_LongFloat:
-#endif
- case type_SimpleString:
- case type_SimpleBitVector:
- case type_SimpleArrayUnsignedByte2:
- case type_SimpleArrayUnsignedByte4:
- case type_SimpleArrayUnsignedByte8:
- case type_SimpleArrayUnsignedByte16:
- case type_SimpleArrayUnsignedByte32:
-#ifdef type_SimpleArraySignedByte8
- case type_SimpleArraySignedByte8:
-#endif
-#ifdef type_SimpleArraySignedByte16
- case type_SimpleArraySignedByte16:
-#endif
-#ifdef type_SimpleArraySignedByte30
- case type_SimpleArraySignedByte30:
-#endif
-#ifdef type_SimpleArraySignedByte32
- case type_SimpleArraySignedByte32:
-#endif
- case type_SimpleArraySingleFloat:
- case type_SimpleArrayDoubleFloat:
-#ifdef type_SimpleArrayLongFloat
- case type_SimpleArrayLongFloat:
-#endif
-#ifdef type_SimpleArrayComplexSingleFloat
- case type_SimpleArrayComplexSingleFloat:
-#endif
-#ifdef type_SimpleArrayComplexDoubleFloat
- case type_SimpleArrayComplexDoubleFloat:
-#endif
-#ifdef type_SimpleArrayComplexLongFloat
- case type_SimpleArrayComplexLongFloat:
-#endif
- case type_Sap:
- case type_WeakPointer:
- break;
-
- default:
- if (pointer_filter_verbose) {
- fprintf(stderr,"*Wo6: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
- break;
- default:
- if (pointer_filter_verbose) {
- fprintf(stderr,"*W?: %x %x %x\n", (unsigned int) pointer,
- (unsigned int) start_addr, *start_addr);
- }
- return 0;
- }
-
- /* looks good */
- return 1;
-}
-
-#define MAX_STACK_POINTERS 256
-lispobj *valid_stack_locations[MAX_STACK_POINTERS];
-unsigned int num_valid_stack_locations;
-
-#define MAX_STACK_RETURN_ADDRESSES 128
-lispobj *valid_stack_ra_locations[MAX_STACK_RETURN_ADDRESSES];
-lispobj *valid_stack_ra_code_objects[MAX_STACK_RETURN_ADDRESSES];
-unsigned int num_valid_stack_ra_locations;
-
-/* Identify valid stack slots. */
-static void
-setup_i386_stack_scav(lispobj *lowaddr, lispobj *base)
-{
- lispobj *sp = lowaddr;
- num_valid_stack_locations = 0;
- num_valid_stack_ra_locations = 0;
- for (sp = lowaddr; sp < base; sp++) {
- lispobj thing = *sp;
- /* Find the object start address */
- lispobj *start_addr = search_dynamic_space((void *)thing);
- if (start_addr) {
- /* 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) {
- gc_assert(num_valid_stack_ra_locations <
- MAX_STACK_RETURN_ADDRESSES);
- valid_stack_ra_locations[num_valid_stack_ra_locations] = sp;
- valid_stack_ra_code_objects[num_valid_stack_ra_locations++] =
- (lispobj *)((int)start_addr + OTHER_POINTER_LOWTAG);
- } else {
- if (valid_dynamic_space_pointer((void *)thing, start_addr)) {
- gc_assert(num_valid_stack_locations < MAX_STACK_POINTERS);
- valid_stack_locations[num_valid_stack_locations++] = sp;
- }
- }
- }
- }
- if (pointer_filter_verbose) {
- fprintf(stderr, "number of valid stack pointers = %d\n",
- num_valid_stack_locations);
- fprintf(stderr, "number of stack return addresses = %d\n",
- num_valid_stack_ra_locations);
- }