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