boehm-gc -vs- Sparc Linux

Tom Tromey tromey@cygnus.com
Wed Apr 26 17:40:00 GMT 2000


FYI, I'm checking in this patch from Jakub Jelinek which adds a Sparc
Linux port to the Boehm GC.  I've already forwarded this to Boehm as
well.

The original message is appended.

Tom


This is what I needed to get boehm-gc's gctest succeed on SparcLinux.
As 32bit library it works in all --disable-shared, --enable-shared,
--enable-shared --enable-threads, with 64bit library it for some reason
loops forever with --enable-shared --enable-threads. I'll try to debug that
later on (but it is well possible it is unrelated to boehm-gc).

2000-04-26  Jakub Jelinek  <jakub@redhat.com>

	* gcconfig.h (SPARC): Define ALIGNMENT to 8 for 64bit SPARC.
	(SPARC/LINUX): Use GC_SysVGetDataStart instead of LINUX_DATA_START
	- sparc glibc does not provide it.
	(SAVE_CALL_CHAIN, ASM_CLEAR_CODE): Define on sparc*-linux*.
	Make STACKBOTTOM depend on the wordsize.
	* os_dep.c (GC_SysVGetDataStart): Compile in on sparc*-linux*.
	(struct frame): Declare on sparc*-linux*.
	(GC_save_callers): Bias the frame pointers if needed (sparc64).
	* mach_dep.c (GC_save_regs_in_stack): Optimize on sparc32.
	Implement on sparc64.
	(GC_clear_stack_inner): Implement on sparc64.
	* gc_priv.h (GC_test_and_set): Implement for sparc.
	* linux_threads.c (GC_suspend_handler, GC_push_all_stacks): Use
	GC_save_regs_in_stack on sparc.

--- libgcj/boehm-gc/gcconfig.h.jj	Tue Apr 25 10:33:06 2000
+++ libgcj/boehm-gc/gcconfig.h	Tue Apr 25 19:22:55 2000
@@ -326,8 +326,8 @@
                     /*		   RT	      ==> IBM PC/RT		*/
                     /*		   HP_PA      ==> HP9000/700 & /800	*/
                     /*				  HP/UX			*/
-		    /*		   SPARC      ==> SPARC under SunOS	*/
-		    /*			(SUNOS4, SUNOS5,		*/
+		    /*		   SPARC      ==> SPARC	v7/v8/v9	*/
+		    /*			(SUNOS4, SUNOS5, LINUX,		*/
 		    /*			 DRSNX variants)		*/
 		    /* 		   ALPHA      ==> DEC Alpha 		*/
 		    /*			(OSF1 and LINUX variants)	*/
@@ -595,7 +595,11 @@
 
 # ifdef SPARC
 #   define MACH_TYPE "SPARC"
-#   define ALIGNMENT 4	/* Required by hardware	*/
+#   if defined(__arch64__) || defined(__sparcv9)
+#     define ALIGNMENT 8
+#   else
+#     define ALIGNMENT 4	/* Required by hardware	*/
+#   endif
 #   define ALIGN_DOUBLE
     extern int etext;
 #   ifdef SUNOS5
@@ -656,15 +660,22 @@
 #   ifdef LINUX
 #     define OS_TYPE "LINUX"
 #     ifdef __ELF__
-#       define LINUX_DATA_START
 #       define DYNAMIC_LOADING
 #     else
-          Linux Sparc non elf ?
+          Linux Sparc/a.out not supported
 #     endif
+      extern int _etext;
       extern int _end;
 #     define DATAEND (&_end)
 #     define SVR4
-#     define STACKBOTTOM ((ptr_t) 0xf0000000)
+#     ifdef __arch64__
+#       define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
+#	define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, &_etext)
+#	define CPP_WORDSZ 64
+#     else
+#       define STACKBOTTOM ((ptr_t) 0xf0000000)
+#	define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
+#     endif
 #   endif
 #   ifdef OPENBSD
 #     define OS_TYPE "OPENBSD"
@@ -1331,7 +1342,7 @@
 	/* Use setjmp based hack to mark from callee-save registers. */
 #	define USE_GENERIC_PUSH_REGS
 # endif
-# if defined(SPARC) && !defined(LINUX)
+# if defined(SPARC)
 #   define SAVE_CALL_CHAIN
 #   define ASM_CLEAR_CODE	/* Stack clearing is crucial, and we 	*/
 				/* include assembly code to do it well.	*/
--- libgcj/boehm-gc/os_dep.c.jj	Tue Apr 25 07:35:26 2000
+++ libgcj/boehm-gc/os_dep.c	Wed Apr 26 15:50:20 2000
@@ -1064,7 +1064,8 @@ void GC_register_data_segments()
 
 # else
 
-# if (defined(SVR4) || defined(AUX) || defined(DGUX)) && !defined(PCR)
+# if (defined(SVR4) || defined(AUX) || defined(DGUX) \
+      || (defined(LINUX) && defined(SPARC))) && !defined(PCR)
 char * GC_SysVGetDataStart(max_page_size, etext_addr)
 int max_page_size;
 int * etext_addr;
@@ -2580,23 +2581,37 @@ struct hblk *h;
  * Call stack save code for debugging.
  * Should probably be in mach_dep.c, but that requires reorganization.
  */
-#if defined(SPARC) && !defined(LINUX)
-#   if defined(SUNOS4)
-#     include <machine/frame.h>
-#   else
-#     if defined (DRSNX)
-#	include <sys/sparc/frame.h>
-#     else
-#        if defined(OPENBSD)
-#          include <frame.h>
-#        else
-#          include <sys/frame.h>
-#        endif
-#     endif
-#   endif
-#   if NARGS > 6
+#if defined(SPARC)
+#  if defined(LINUX)
+struct frame {
+	long	fr_local[8];
+	long	fr_arg[6];
+	struct frame *fr_savfp;
+	long	fr_savpc;
+#    ifndef __arch64__
+	char	*fr_stret;
+#    endif
+	long	fr_argd[6];
+	long	fr_argx[0];
+};
+#  else
+#    if defined(SUNOS4)
+#      include <machine/frame.h>
+#    else
+#      if defined (DRSNX)
+#	 include <sys/sparc/frame.h>
+#      else
+#	 if defined(OPENBSD)
+#	   include <frame.h>
+#	 else
+#	   include <sys/frame.h>
+#	 endif
+#      endif
+#    endif
+#  endif
+#  if NARGS > 6
 	--> We only know how to to get the first 6 arguments
-#   endif
+#  endif
 
 #ifdef SAVE_CALL_CHAIN
 /* Fill in the pc and argument information for up to NFRAMES of my	*/
@@ -2610,6 +2625,12 @@ struct hblk *h;
 #  define FR_SAVPC fr_savpc
 #endif
 
+#if defined(SPARC) && (defined(__arch64__) || defined(__sparcv9))
+#define BIAS 2047
+#else
+#define BIAS 0
+#endif
+
 void GC_save_callers (info) 
 struct callinfo info[NFRAMES];
 {
@@ -2620,8 +2641,9 @@ struct callinfo info[NFRAMES];
 
   frame = (struct frame *) GC_save_regs_in_stack ();
   
-  for (fp = frame -> FR_SAVFP; fp != 0 && nframes < NFRAMES;
-       fp = fp -> FR_SAVFP, nframes++) {
+  for (fp = (struct frame *)((long) frame -> FR_SAVFP + BIAS);
+       fp != 0 && nframes < NFRAMES;
+       fp = (struct frame *)((long) fp -> FR_SAVFP + BIAS), nframes++) {
       register int i;
       
       info[nframes].ci_pc = fp->FR_SAVPC;
--- libgcj/boehm-gc/mach_dep.c.jj	Tue Apr 25 07:35:25 2000
+++ libgcj/boehm-gc/mach_dep.c	Wed Apr 26 15:49:01 2000
@@ -437,10 +437,16 @@ ptr_t cold_gc_frame;
       asm("	.globl	_GC_save_regs_in_stack");
       asm("_GC_save_regs_in_stack:");
 #   endif
+#   if defined(__arch64__) || defined(__sparcv9)
+    asm("	save	%sp,-128,%sp");
+    asm("	flushw");
+    asm("	ret");
+    asm("	restore %sp,2047+128,%o0");
+#   else
     asm("	ta	0x3   ! ST_FLUSH_WINDOWS");
-    asm("	mov	%sp,%o0");
     asm("	retl");
-    asm("	nop");
+    asm("	mov	%sp,%o0");
+#endif
 #   ifdef SVR4
       asm("	.GC_save_regs_in_stack_end:");
       asm("	.size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack");
@@ -488,6 +494,21 @@ ptr_t cold_gc_frame;
     asm("GC_clear_stack_inner:");
     asm(".type GC_save_regs_in_stack,#function");
 # endif
+#if defined(__arch64__) || defined(__sparcv9)
+  asm("mov %sp,%o2");		/* Save sp			*/
+  asm("add %sp,2047-8,%o3");	/* p = sp+bias-8		*/
+  asm("add %o1,-2047-192,%sp");	/* Move sp out of the way,	*/
+  				/* so that traps still work.	*/
+  				/* Includes some extra words	*/
+  				/* so we can be sloppy below.	*/
+  asm("loop:");
+  asm("stx %g0,[%o3]");		/* *(long *)p = 0		*/
+  asm("cmp %o3,%o1");
+  asm("bgu,pt %xcc, loop");	/* if (p > limit) goto loop	*/
+    asm("add %o3,-8,%o3");	/* p -= 8 (delay slot) */
+  asm("retl");
+    asm("mov %o2,%sp");		/* Restore sp., delay slot	*/
+#else
   asm("mov %sp,%o2");		/* Save sp	*/
   asm("add %sp,-8,%o3");	/* p = sp-8	*/
   asm("clr %g1");		/* [g0,g1] = 0	*/
@@ -502,6 +523,7 @@ ptr_t cold_gc_frame;
     asm("add %o3,-8,%o3");	/* p -= 8 (delay slot) */
   asm("retl");
     asm("mov %o2,%sp");		/* Restore sp., delay slot	*/
+#endif
   /* First argument = %o0 = return value */
 #   ifdef SVR4
       asm("	.GC_clear_stack_inner_end:");
--- libgcj/boehm-gc/gc_priv.h.jj	Tue Apr 25 07:35:23 2000
+++ libgcj/boehm-gc/gc_priv.h	Tue Apr 25 11:22:16 2000
@@ -439,7 +439,7 @@ void GC_print_callers (/* struct callinf
 #  endif
 #  if defined(LINUX_THREADS) 
 #   if defined(I386)|| defined(POWERPC) || defined(ALPHA) || defined(IA64) \
-    || defined(M68K)
+    || defined(M68K) || defined(SPARC)
 #    include <pthread.h>
 #    define USE_SPIN_LOCK
 #    if defined(I386)
@@ -464,6 +464,16 @@ void GC_print_callers (/* struct callinf
 	 __asm__ __volatile__("st4.rel %0=r0" : "=m" (*addr));
        }
 #      define GC_CLEAR_DEFINED
+#    endif
+#    ifdef SPARC
+       inline static int GC_test_and_set(volatile unsigned int *addr) {
+	 int oldval;
+
+	 __asm__ __volatile__("ldstub %1,%0"
+	 : "=r"(oldval), "=m"(*addr)
+	 : "m"(*addr));
+	 return oldval;
+       }
 #    endif
 #    ifdef M68K
        /* Contributed by Tony Mantler.  I'm not sure how well it was	*/
--- libgcj/boehm-gc/linux_threads.c.jj	Tue Apr 25 07:35:25 2000
+++ libgcj/boehm-gc/linux_threads.c	Tue Apr 25 14:39:23 2000
@@ -152,7 +152,7 @@ static inline ptr_t GC_linux_thread_top_
   return tos;
 }
 
-#ifdef IA64
+#if defined(SPARC) || defined(IA64)
   extern word GC_save_regs_in_stack();
 #endif
 
@@ -177,7 +177,11 @@ void GC_suspend_handler(int sig)
     /* of a thread which holds the allocation lock in order	*/
     /* to stop the world.  Thus concurrent modification of the	*/
     /* data structure is impossible.				*/
-    me -> stack_ptr = (ptr_t)(&dummy);
+#   ifdef SPARC
+	me -> stack_ptr = (ptr_t)GC_save_regs_in_stack();
+#   else
+	me -> stack_ptr = (ptr_t)(&dummy);
+#   endif
 #   ifdef IA64
 	me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack();
 #   endif
@@ -425,7 +429,11 @@ void GC_push_all_stacks()
       for (p = GC_threads[i]; p != 0; p = p -> next) {
         if (p -> flags & FINISHED) continue;
         if (pthread_equal(p -> id, me)) {
+#  ifdef SPARC
+	    lo = (ptr_t)GC_save_regs_in_stack();
+#  else
 	    lo = GC_approx_sp();
+#  endif
 	    IF_IA64(bs_hi = (ptr_t)GC_save_regs_in_stack();)
 	} else {
 	    lo = p -> stack_ptr;

	Jakub



More information about the Java-patches mailing list