Re: Problem with STk 3.99.4 on Solaris 2.6

From: Paul Anderson <paul_at_grammatech.com>
Date: Mon, 13 Dec 1999 13:14:01 -0500

Erick:

I am quite sure I have it.

The problem is in the marking phase of the garbage collector.
In the call to STk_cons(x,y), if the garbage collector is called
via NEWCELL I can find x on the freelist after it has returned.
If the code for STk_cons is NOT optimized then the
x and y variables were stored on the stack. If it was
optimized then these were stored in registers.

The issue is that the setjmp(save_regs_gc_mark) in gc_mark_and_sweep()
is not getting the registers in the frame for STk_cons.

In the Synthesizer Generator we use a garbage collector
that uses part of Hans Boehm's garbage collector package.
This does stack scanning in a way very similar to STk.
In that package, the register scanning is done on some
architectures in essentially the same way it is done on
STk. However, on a sparc the system does the register
scanning by flushing the registers to the stack, then
doing the stack scan in the normal way. It does the
flush using the following assembly language.

        .seg "text"
        .globl register_scan
register_scan:
        ta 0x3 ! ST_FLUSH_WINDOWS
        mov %sp,%o0
        retl
        nop
        

Clearly the setjmp method does work on some sparcs.
My own desktop machine is a sun4u, where things work
perfectly. The machine on which the problem shows up
is a sun4m, so that would explain why it has now
shown up before.

I tried this code and now things work perfectly.
Details of the fix are below.

The Boehm code I mentioned above also has a lot of
other machine-specific assembler files for making
sure that the registers get scanned properly.
It may be worthwhile to look at this to see if any of
it applies for STk.

If you have any questions about any of this, feel free
to email. However, do so soon as I shall be going on
vacation on Wednesday until after the new year.

Best regards and Happy Millenium to all!

Paul.


--------------------
Details of the fix:

In gc.c I have now:

  /**** Marking phase */
  register_scan();

On a non-sparc machine this is implemented in a file named
register_scan.c containing the old code:

void register_scan()
{
  setjmp(save_regs_gc_mark); /* registers */
  STk_mark_stack((SCM *) save_regs_gc_mark,
                 (SCM *) (((char *) save_regs_gc_mark)+
                          sizeof(save_regs_gc_mark)));
}


I have configured the makefiles to compile register_scan.o
either from a file containing the above assember (named sparc.s)
or the register_scan.c. I do this using:

ifneq (,$(findstring sun4,$(MACHINE)))
# IMPORTANT: DO NOT OPTIMIZE THIS FILE!!!
register_scan.o:
        $(CC) -c -o register_scan.o sparc.s
else
register_scan.o:
        $(CC) -c register_scan.c
endif


-----

______
Paul Anderson. GrammaTech, Inc. Tel: +1 607 273-7340
mailto:paul_at_grammatech.com http://www.grammatech.com
Received on Mon Dec 13 1999 - 19:16:57 CET

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST