? autom4te.cache ? gcj3.4-darwin.patch Index: Makefile.direct =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/Makefile.direct,v retrieving revision 1.2 diff -u -r1.2 Makefile.direct --- Makefile.direct 12 Feb 2002 04:37:53 -0000 1.2 +++ Makefile.direct 16 Apr 2003 02:43:17 -0000 @@ -441,7 +441,7 @@ ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s # ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s # alpha_mach_dep.s assumes that pointers are not saved in fp registers. # Gcc on a 21264 can spill pointers to fp registers. Oops. @@ -491,7 +491,7 @@ ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs` ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld `./threadlibs` ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses - ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a + ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` Index: Makefile.dist =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/Makefile.dist,v retrieving revision 1.3 diff -u -r1.3 Makefile.dist --- Makefile.dist 17 Aug 2001 18:30:44 -0000 1.3 +++ Makefile.dist 16 Apr 2003 02:43:18 -0000 @@ -415,7 +415,7 @@ ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s # ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s # alpha_mach_dep.s assumes that pointers are not saved in fp registers. # Gcc on a 21264 can spill pointers to fp registers. Oops. @@ -462,7 +462,7 @@ ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs` ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld `./threadlibs` ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses - ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a + ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` Index: Makefile.dj =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/Makefile.dj,v retrieving revision 1.7 diff -u -r1.7 Makefile.dj --- Makefile.dj 16 Oct 2001 09:01:34 -0000 1.7 +++ Makefile.dj 16 Apr 2003 02:43:18 -0000 @@ -291,7 +291,7 @@ ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s Index: configure =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/configure,v retrieving revision 1.59 diff -u -r1.59 configure --- configure 11 Apr 2003 04:20:14 -0000 1.59 +++ configure 16 Apr 2003 02:43:21 -0000 @@ -2807,6 +2807,23 @@ *-*-cygwin*) THREADLIBS= ;; + *-*-darwin*) + cat >> confdefs.h <<\EOF +#define GC_DARWIN_THREADS 1 +EOF + + cat >> confdefs.h <<\EOF +#define THREAD_LOCAL_ALLOC 1 +EOF + + if test "${enable_parallel_mark}" = yes; then + cat >> confdefs.h <<\EOF +#define PARALLEL_MARK 1 +EOF + + fi + + ;; esac ;; win32) @@ -2828,8 +2845,11 @@ esac -echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:2833: checking for dlopen in -ldl" >&5 +case "$host" in + *-*-darwin*) ;; + *) + echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:2853: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2837,7 +2857,7 @@ ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2872: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2868,6 +2888,8 @@ echo "$ac_t""no" 1>&6 fi + ;; +esac target_all=libgcjgc.la Index: configure.in =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/configure.in,v retrieving revision 1.46 diff -u -r1.46 configure.in --- configure.in 12 Mar 2003 21:34:19 -0000 1.46 +++ configure.in 16 Apr 2003 02:43:21 -0000 @@ -111,6 +111,14 @@ *-*-cygwin*) THREADLIBS= ;; + *-*-darwin*) + AC_DEFINE(GC_DARWIN_THREADS) + AC_DEFINE(THREAD_LOCAL_ALLOC) + if test "${enable_parallel_mark}" = yes; then + AC_DEFINE(PARALLEL_MARK) + fi + + ;; esac ;; win32) @@ -126,7 +134,12 @@ esac AC_SUBST(THREADLIBS) -AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl") +case "$host" in + *-*-darwin*) ;; + *) + AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl") + ;; +esac AC_SUBST(EXTRA_TEST_LIBS) target_all=libgcjgc.la Index: dyn_load.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/dyn_load.c,v retrieving revision 1.19 diff -u -r1.19 dyn_load.c --- dyn_load.c 4 Mar 2003 22:18:08 -0000 1.19 +++ dyn_load.c 16 Apr 2003 02:43:22 -0000 @@ -57,7 +57,8 @@ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \ !defined(RS6000) && !defined(SCO_ELF) && \ !(defined(FREEBSD) && defined(__ELF__)) && \ - !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) + !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \ + !defined(DARWIN) --> We only know how to find data segments of dynamic libraries for the --> above. Additional SVR4 variants might not be too --> hard to add. @@ -1056,7 +1057,122 @@ } #endif /* RS6000 */ +#ifdef DARWIN +#warning FIXME __private_extern__ support in gcc +#define __private_extern__ +#include +#include + +/*#define DARWIN_DEBUG*/ + +const static struct { + const char *seg; + const char *sect; +} GC_dyld_sections[] = { + { SEG_DATA, SECT_DATA }, + { SEG_DATA, SECT_BSS }, + { SEG_DATA, SECT_COMMON } +}; + +#ifdef DARWIN_DEBUG +static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) { + unsigned long i,c; + c = _dyld_image_count(); + for(i=0;isize == 0) continue; + start = slide + sec->addr; + end = start + sec->size; +# ifdef DARWIN_DEBUG + GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n", + start,end,sec->size,GC_dyld_name_for_hdr(hdr)); +# endif + GC_add_roots((char*)start,(char*)end); + } +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif +} + +/* This should never be called by a thread holding the lock */ +static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) { + unsigned long start,end,i; + const struct section *sec; + for(i=0;isize == 0) continue; + start = slide + sec->addr; + end = start + sec->size; +# ifdef DARWIN_DEBUG + GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n", + start,end,sec->size,GC_dyld_name_for_hdr(hdr)); +# endif + GC_remove_roots((char*)start,(char*)end); + } +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif +} + +void GC_register_dynamic_libraries() { + /* Currently does nothing. The callbacks are setup by GC_init_dyld() + The dyld library takes it from there. */ +} + +/* The _dyld_* functions have an internal lock so no _dyld functions + can be called while the world is stopped without the risk of a deadlock. + Because of this we MUST setup callbacks BEFORE we ever stop the world. + This should be called BEFORE any thread in created and WITHOUT the + allocation lock held. */ + +void GC_init_dyld() { + static unsigned long dummy; +# ifdef DARWIN_DEBUG + GC_printf0("Forcing full bind of GC code...\n"); +# endif + + if(!_dyld_bind_fully_image_containing_address(&dummy)) + GC_abort("_dyld_bind_fully_image_containing_addres failed"); + +# ifdef DARWIN_DEBUG + GC_printf0("Registering dyld callbacks...\n"); +# endif + + /* Apple's Documentation: + When you call _dyld_register_func_for_add_image, the dynamic linker runtime calls + the specified callback (func) once for each of the images that is currently loaded + into the program. When a new image is added to the program, your callback is called + again with the mach_header for the new image, and the virtual memory slide amount + of the new image. + + This WILL properly register existing and all future libraries + */ + + _dyld_register_func_for_add_image(GC_dyld_image_add); + _dyld_register_func_for_remove_image(GC_dyld_image_remove); +} + +#define HAVE_REGISTER_MAIN_STATIC_DATA +GC_bool GC_register_main_static_data() +{ + /* Already done through dyld callbacks */ + return FALSE; +} + +#endif /* DARWIN */ #else /* !DYNAMIC_LOADING */ Index: gc_dlopen.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/gc_dlopen.c,v retrieving revision 1.3 diff -u -r1.3 gc_dlopen.c --- gc_dlopen.c 16 Oct 2001 09:01:35 -0000 1.3 +++ gc_dlopen.c 16 Apr 2003 02:43:22 -0000 @@ -24,7 +24,8 @@ #include "private/gc_priv.h" -# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) +# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \ + || defined(GC_SOLARIS_THREADS) # if defined(dlopen) && !defined(GC_USE_LD_WRAP) /* To support various threads pkgs, gc.h interposes on dlopen by */ Index: linux_threads.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/linux_threads.c,v retrieving revision 1.20 diff -u -r1.20 linux_threads.c --- linux_threads.c 29 Mar 2002 22:52:12 -0000 1.20 +++ linux_threads.c 16 Apr 2003 02:43:24 -0000 @@ -57,11 +57,15 @@ # include "private/gc_priv.h" -# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \ +# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_IFIC) \ && !defined(USE_HPUX_TLS) # define USE_HPUX_TLS # endif +#if defined(GC_DARWIN_THREADS) +# define USE_PTHREAD_SPECIFIC +#endif + # ifdef THREAD_LOCAL_ALLOC # if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_HPUX_TLS) # include "private/specific.h" @@ -87,12 +91,22 @@ # include # include # include -# include # include # include # include # include +#if !defined(GC_DARWIN_THREADS) +/* We have our own simple semaphore implementation of darwin */ +# include +#endif /* !GC_DARWIN_THREADS */ + +#if defined(GC_DARWIN_THREADS) +# include +# include +# include +#endif /* GC_DARWIN_THREADS */ + #ifndef __GNUC__ # define __inline__ #endif @@ -104,11 +118,91 @@ # define WRAP_FUNC(f) GC_##f # define REAL_FUNC(f) f # undef pthread_create +# if !defined(GC_DARWIN_THREADS) # undef pthread_sigmask +# endif # undef pthread_join # undef pthread_detach #endif +#if defined(GC_DARWIN_THREADS) + +/* + This is a very simple semaphore implementation for darwin. It + is implemented in terms of pthreads calls so it isn't async signal + safe. This isn't a problem because signals aren't used in to + suspend threads on darwin. +*/ + +typedef struct { + pthread_mutex_t mutex; + pthread_cond_t cond; + int value; +} sem_t; + +static int sem_init(sem_t *sem, int pshared, int value) { + int ret; + if(pshared) + GC_abort("sem_init with pshared set"); + sem->value = value; + + ret = pthread_mutex_init(&sem->mutex,NULL); + if(ret < 0) return -1; + ret = pthread_cond_init(&sem->cond,NULL); + if(ret < 0) return -1; + return 0; +} + +static int sem_post(sem_t *sem) { + if(pthread_mutex_lock(&sem->mutex) < 0) + return -1; + sem->value++; + if(pthread_cond_signal(&sem->cond) < 0) { + pthread_mutex_unlock(&sem->mutex); + return -1; + } + if(pthread_mutex_unlock(&sem->mutex) < 0) + return -1; + return 0; +} + +static int sem_wait(sem_t *sem) { + if(pthread_mutex_lock(&sem->mutex) < 0) + return -1; + while(sem->value == 0) { + pthread_cond_wait(&sem->cond,&sem->mutex); + } + sem->value--; + if(pthread_mutex_unlock(&sem->mutex) < 0) + return -1; + return 0; +} + +static int sem_destroy(sem_t *sem) { + int ret; + ret = pthread_cond_destroy(&sem->cond); + if(ret < 0) return -1; + ret = pthread_mutex_destroy(&sem->mutex); + if(ret < 0) return -1; + return 0; +} + +#ifdef POWERPC +/* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple + Page 49: + "The space beneath the stack pointer, where a new stack frame would normally + be allocated, is called the red zone. This area as shown in Figure 3-2 may + be used for any purpose as long as a new stack frame does not need to be + added to the stack." + + Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then + it must set up a stack frame just like routines that call other routines." +*/ +#define DARWIN_PPC_RED_ZONE 224 +#endif POWERPC + +#endif /* !GC_DARWIN_THREADS */ + void GC_thr_init(); @@ -143,6 +237,9 @@ /* guaranteed to be dead, but we may */ /* not yet have registered the join.) */ pthread_t id; +#ifdef GC_DARWIN_THREADS + mach_port_t mach_thread; +#endif short flags; # define FINISHED 1 /* Thread has exited. */ # define DETACHED 2 /* Thread is intended to be detached. */ @@ -160,7 +257,9 @@ ptr_t backing_store_end; ptr_t backing_store_ptr; # endif +#ifndef GC_DARWIN_THREADS int signal; +#endif void * status; /* The value returned from the thread. */ /* Used only to avoid premature */ /* reclamation of any data it might */ @@ -447,6 +546,7 @@ * pointer(s) and acknowledge. */ +#if !defined(GC_DARWIN_THREADS) #ifndef SIG_THR_RESTART # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) # define SIG_THR_RESTART _SIGRTMIN + 5 @@ -454,8 +554,11 @@ # define SIG_THR_RESTART SIGXCPU # endif #endif +#endif +#if !defined(GC_DARWIN_THREADS) sem_t GC_suspend_ack_sem; +#endif /* !GC_DARWIN_THREADS */ #if 0 /* @@ -571,6 +674,7 @@ #endif /* !PARALLEL_MARK */ +#if !defined(GC_DARWIN_THREADS) void GC_suspend_handler(int sig) { int dummy; @@ -633,7 +737,9 @@ GC_printf1("Continuing 0x%x\n", my_thread); #endif } +#endif /* !GC_DARWIN_THREADS */ +#if !defined(GC_DARWIN_THREADS) void GC_restart_handler(int sig) { GC_thread me; @@ -660,6 +766,7 @@ GC_printf1("In GC_restart_handler for 0x%x\n", pthread_self()); #endif } +#endif /* !GC_DARWIN_THREADS */ /* Defining INSTALL_LOOPING_SEGV_HANDLER causes SIGSEGV and SIGBUS to */ /* result in an infinite loop in a signal handler. This can be very */ @@ -807,6 +914,16 @@ register GC_thread p; register int n_live_threads = 0; register int result; +# if defined(GC_DARWIN_THREADS) + kern_return_t kern_result; +# if defined(POWERPC) + struct ppc_thread_state thread_state; + thread_state_flavor_t flavor = PPC_THREAD_STATE; + mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT; +# else +# error FIXME for non-ppc OS X +# endif +# endif GC_stopping_thread = my_thread; /* debugging only. */ GC_stopping_pid = getpid(); /* debugging only. */ @@ -828,6 +945,56 @@ #if DEBUG_THREADS GC_printf1("Sending suspend signal to 0x%x\n", p -> id); #endif +# if defined(GC_DARWIN_THREADS) + GC_ASSERT(p->mach_thread != 0 && p->id != 0); + kern_result = thread_suspend(p->mach_thread); + if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed"); + kern_result = thread_abort_safely(p->mach_thread); + /* This shouldn't really be fatal, I don't think. The documentation is kind of unclear */ + if(kern_result != KERN_SUCCESS) GC_printf1("thread_abort_safely failed (%ul)",kern_result); + kern_result = thread_get_state(p->mach_thread,flavor,(natural_t*)&thread_state,&thread_state_count); + if(kern_result != KERN_SUCCESS) ABORT("thread_get_state failed"); +# if defined(POWERPC) + /* The space just below the stack pointer can also be used. + See the comment about the red zone at the top of the file */ + p->stack_ptr = (void*)(thread_state.r1 - DARWIN_PPC_RED_ZONE); + /* Push all the general purpose registers, except the stack pointer. */ + GC_push_one(thread_state.r0); + GC_push_one(thread_state.r2); + GC_push_one(thread_state.r3); + GC_push_one(thread_state.r4); + GC_push_one(thread_state.r5); + GC_push_one(thread_state.r6); + GC_push_one(thread_state.r7); + GC_push_one(thread_state.r8); + GC_push_one(thread_state.r9); + GC_push_one(thread_state.r10); + GC_push_one(thread_state.r11); + GC_push_one(thread_state.r12); + GC_push_one(thread_state.r13); + GC_push_one(thread_state.r14); + GC_push_one(thread_state.r15); + GC_push_one(thread_state.r16); + GC_push_one(thread_state.r17); + GC_push_one(thread_state.r18); + GC_push_one(thread_state.r19); + GC_push_one(thread_state.r20); + GC_push_one(thread_state.r21); + GC_push_one(thread_state.r22); + GC_push_one(thread_state.r23); + GC_push_one(thread_state.r24); + GC_push_one(thread_state.r25); + GC_push_one(thread_state.r26); + GC_push_one(thread_state.r27); + GC_push_one(thread_state.r28); + GC_push_one(thread_state.r29); + GC_push_one(thread_state.r30); + GC_push_one(thread_state.r31); +# else +# error fixme for non ppc os x +# endif + +# else /* GC_DARWIN_THREADS */ result = pthread_kill(p -> id, SIG_SUSPEND); switch(result) { case ESRCH: @@ -839,13 +1006,16 @@ default: ABORT("pthread_kill failed"); } +# endif /* !GC_DARWIN_THREADS */ } } } +# if !defined(GC_DARWIN_THREADS) for (i = 0; i < n_live_threads; i++) { if (0 != sem_wait(&GC_suspend_ack_sem)) ABORT("sem_wait in handler failed"); } +# endif /* GC_DARWIN_THREADS */ # ifdef PARALLEL_MARK GC_release_mark_lock(); # endif @@ -864,7 +1034,9 @@ register GC_thread p; register int n_live_threads = 0; register int result; - +# if defined(GC_DARWIN_THREADS) + kern_return_t kern_result; +# endif # if DEBUG_THREADS GC_printf0("World starting\n"); # endif @@ -878,6 +1050,12 @@ #if DEBUG_THREADS GC_printf1("Sending restart signal to 0x%x\n", p -> id); #endif +# if defined(GC_DARWIN_THREADS) + + kern_result = thread_resume(p->mach_thread); + if(kern_result != KERN_SUCCESS) ABORT("thread_resume failed"); + +# else /* GC_DARWIN_THREADS */ result = pthread_kill(p -> id, SIG_THR_RESTART); switch(result) { case ESRCH: @@ -889,6 +1067,7 @@ default: ABORT("pthread_kill failed"); } +# endif /* !GC_DARWIN_THREADS */ } } } @@ -1039,8 +1218,10 @@ if (GC_thr_initialized) return; GC_thr_initialized = TRUE; +# if !defined(GC_DARWIN_THREADS) if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0) ABORT("sem_init failed"); + #endif act.sa_flags = SA_RESTART; if (sigfillset(&act.sa_mask) != 0) { @@ -1055,6 +1236,7 @@ } # endif +# if !defined(GC_DARWIN_THREADS) /* SIG_THR_RESTART is unmasked by the handler when necessary. */ act.sa_handler = GC_suspend_handler; if (sigaction(SIG_SUSPEND, &act, NULL) != 0) { @@ -1065,6 +1247,7 @@ if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) { ABORT("Cannot set SIG_THR_RESTART handler"); } +# endif /* !GC_DARWIN_THREADS */ # ifdef INSTALL_LOOPING_SEGV_HANDLER act.sa_handler = GC_looping_handler; if (sigaction(SIGSEGV, &act, NULL) != 0 @@ -1075,6 +1258,9 @@ /* Add the initial thread, so we can stop it. */ t = GC_new_thread(pthread_self()); +# ifdef GC_DARWIN_THREADS + t -> mach_thread = mach_thread_self(); +# endif t -> stack_ptr = (ptr_t)(&dummy); t -> flags = DETACHED | MAIN_THREAD; @@ -1091,6 +1277,12 @@ # if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS) GC_nprocs = 1; # endif +# if defined(GC_DARWIN_THREADS) + int ncpus = 1; + size_t len = sizeof(ncpus); + sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0); + GC_nprocs = ncpus; +# endif # if defined(GC_LINUX_THREADS) GC_nprocs = GC_get_nprocs(); # endif @@ -1150,7 +1342,7 @@ # endif } - +#if !defined(GC_DARWIN_THREADS) int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset) { sigset_t fudged_set; @@ -1162,6 +1354,7 @@ } return(REAL_FUNC(pthread_sigmask)(how, set, oset)); } +#endif /* !GC_DARWIN_THREADS */ /* Wrappers for functions that are likely to block for an appreciable */ /* length of time. Must be called in pairs, if at all. */ @@ -1331,6 +1524,9 @@ # endif LOCK(); me = GC_new_thread(my_pthread); +#ifdef GC_DARWIN_THREADS + me -> mach_thread = mach_thread_self(); +#endif me -> flags = si -> flags; me -> stack_ptr = 0; /* me -> stack_end = GC_linux_stack_base(); -- currently (11/99) */ Index: mark_rts.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/mark_rts.c,v retrieving revision 1.10 diff -u -r1.10 mark_rts.c --- mark_rts.c 3 Mar 2003 19:34:11 -0000 1.10 +++ mark_rts.c 16 Apr 2003 02:43:25 -0000 @@ -275,33 +275,72 @@ } /* Internal use only; lock held. */ +static void GC_remove_root_at_pos(i) +int i; +{ + GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start); + GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start; + GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end; + GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp; + n_root_sets--; +} + +#if !defined(MSWIN32) && !defined(MSWINCE) +static void GC_rebuild_root_index() +{ + register int i; + + for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0; + for (i = 0; i < n_root_sets; i++) + add_roots_to_index(GC_static_roots + i); +} +#endif + +/* Internal use only; lock held. */ void GC_remove_tmp_roots() { register int i; for (i = 0; i < n_root_sets; ) { if (GC_static_roots[i].r_tmp) { - GC_root_size -= - (GC_static_roots[i].r_end - GC_static_roots[i].r_start); - GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start; - GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end; - GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp; - n_root_sets--; + GC_remove_root_at_pos(i); } else { i++; } } -# if !defined(MSWIN32) && !defined(MSWINCE) - { - register int i; - - for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0; - for (i = 0; i < n_root_sets; i++) - add_roots_to_index(GC_static_roots + i); - } -# endif + #if !defined(MSWIN32) && !defined(MSWINCE) + GC_rebuild_root_index(); + #endif +} + +#if !defined(MSWIN32) && !defined(MSWINCE) +void GC_remove_roots(b, e) +char * b; char * e; +{ + DCL_LOCK_STATE; + DISABLE_SIGNALS(); + LOCK(); + GC_remove_roots_inner(b, e); + UNLOCK(); + ENABLE_SIGNALS(); +} + +/* Should only be called when the lock is held */ +void GC_remove_roots_inner(b,e) +char * b; char * e; +{ + int i; + for (i = 0; i < n_root_sets; ) { + if (GC_static_roots[i].r_start >= (ptr_t)b && GC_static_roots[i].r_end <= (ptr_t)e) { + GC_remove_root_at_pos(i); + } else { + i++; + } + } + GC_rebuild_root_index(); } +#endif /* !defined(MSWIN32) && !defined(MSWINCE) */ #if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION) /* Workaround for the OS mapping and unmapping behind our back: */ Index: misc.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/misc.c,v retrieving revision 1.26 diff -u -r1.26 misc.c --- misc.c 4 Mar 2003 22:18:08 -0000 1.26 +++ misc.c 16 Apr 2003 02:43:25 -0000 @@ -473,6 +473,14 @@ GC_init_parallel(); } # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ +# if defined(DYNAMIC_LOADING) && defined(DARWIN) + { + /* This must be called WITHOUT the allocation lock held + and before any threads are created */ + extern void GC_init_dyld(); + GC_init_dyld(); + } +# endif } #if defined(MSWIN32) || defined(MSWINCE) Index: os_dep.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/os_dep.c,v retrieving revision 1.25 diff -u -r1.25 os_dep.c --- os_dep.c 19 Jul 2002 08:54:43 -0000 1.25 +++ os_dep.c 16 Apr 2003 02:43:28 -0000 @@ -1087,7 +1087,7 @@ void GC_register_data_segments() { # if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \ - && !defined(MACOSX) + && !defined(DARWIN) # if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS) /* As of Solaris 2.3, the Solaris threads implementation */ /* allocates the data structure for the initial thread with */ @@ -1104,7 +1104,7 @@ # endif # endif # endif -# if !defined(PCR) && (defined(NEXT) || defined(MACOSX)) +# if !defined(PCR) && (defined(NEXT) || defined(DARWIN)) GC_add_roots_inner(DATASTART, (char *) get_end(), FALSE); # endif # if defined(MACOS) @@ -1829,7 +1829,7 @@ typedef void (* SIG_PF)(); #endif #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \ - || defined(MACOSX) || defined(HURD) + || defined(DARWIN) || defined(HURD) # ifdef __STDC__ typedef void (* SIG_PF)(int); # else @@ -1897,9 +1897,10 @@ # endif /* !ALPHA */ # endif -# if defined(MACOSX) /* Should also test for PowerPC? */ +# if defined(DARWIN) typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *); +# if defined(PPC) /* Decodes the machine instruction which was responsible for the sending of the SIGBUS signal. Sadly this is the only way to find the faulting address because the signal handler doesn't get it directly from the kernel (although it is @@ -2022,7 +2023,10 @@ #endif return (char *)addr; } -#endif /* MACOSX */ +#else /* non-ppc */ +--> FIXME for non-ppc os x +#endif +#endif /* DARWIN */ SIG_PF GC_old_bus_handler; SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ @@ -2146,7 +2150,7 @@ # endif # endif -# if defined(MACOSX) +# if defined(DARWIN) void GC_write_fault_handler(int sig, int code, struct sigcontext *scp) # define SIG_OK (sig == SIGBUS) # define CODE_OK (code == 0 /* experimentally determined */) @@ -2225,7 +2229,7 @@ # endif # endif # endif -# if defined(MACOSX) +# if defined(DARWIN) char * addr = get_fault_addr(scp); # endif # if defined(MSWIN32) || defined(MSWINCE) @@ -2291,7 +2295,7 @@ (*(REAL_SIG_PF)old_handler) (sig, code, scp); return; # endif -# ifdef MACOSX +# ifdef DARWIN (*(REAL_SIG_PF)old_handler) (sig, code, scp); # endif # ifdef MSWIN32 @@ -2389,7 +2393,7 @@ (void)sigaddset(&act.sa_mask, SIG_SUSPEND); # endif /* SIG_SUSPEND */ # endif -# if defined(MACOSX) +# if defined(DARWIN) struct sigaction act, oldact; act.sa_flags = SA_RESTART; @@ -2458,7 +2462,7 @@ # endif } # endif -# if defined(MACOSX) || defined(HPUX) || defined(LINUX) || defined(HURD) +# if defined(DARWIN) || defined(HPUX) || defined(LINUX) || defined(HURD) sigaction(SIGBUS, &act, &oldact); GC_old_bus_handler = oldact.sa_handler; if (GC_old_bus_handler == SIG_IGN) { Index: threadlibs.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/threadlibs.c,v retrieving revision 1.9 diff -u -r1.9 threadlibs.c --- threadlibs.c 12 Feb 2002 04:37:53 -0000 1.9 +++ threadlibs.c 16 Apr 2003 02:43:28 -0000 @@ -10,7 +10,8 @@ "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n"); # endif # if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \ - || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) + || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) \ + || defined(GC_DARWIN_THREADS) printf("-lpthread\n"); # endif # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) Index: include/gc.h =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/include/gc.h,v retrieving revision 1.9 diff -u -r1.9 gc.h --- include/gc.h 12 Feb 2002 04:37:56 -0000 1.9 +++ include/gc.h 16 Apr 2003 02:43:29 -0000 @@ -74,7 +74,8 @@ # if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \ defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \ - defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) + defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \ + defined(GC_DARWIN_THREADS) # define GC_PTHREADS # endif @@ -419,6 +420,10 @@ GC_API void GC_add_roots GC_PROTO((char * low_address, char * high_address_plus_1)); +/* Remove a root segment. Wizards only. */ +GC_API void GC_remove_roots GC_PROTO((char * low_address, + char * high_address_plus_1)); + /* Add a displacement to the set of those considered valid by the */ /* collector. GC_register_displacement(n) means that if p was returned */ /* by GC_malloc, then (char *)p + n will be considered to be a valid */ @@ -920,7 +925,11 @@ */ # define GC_INIT() { GC_add_roots(DATASTART, DATAEND); } # else -# define GC_INIT() +# if defined(__APPLE__) && defined(__MACH__) +# define GC_INIT() { GC_init(); } +# else +# define GC_INIT() +# endif # endif #endif Index: include/gc_pthread_redirects.h =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/include/gc_pthread_redirects.h,v retrieving revision 1.3 diff -u -r1.3 gc_pthread_redirects.h --- include/gc_pthread_redirects.h 17 Oct 2001 04:55:28 -0000 1.3 +++ include/gc_pthread_redirects.h 16 Apr 2003 02:43:30 -0000 @@ -52,15 +52,21 @@ int GC_pthread_create(pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); +#ifndef GC_DARWIN_THREADS int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset); +#endif int GC_pthread_join(pthread_t thread, void **retval); int GC_pthread_detach(pthread_t thread); # define pthread_create GC_pthread_create +#ifndef GC_DARWIN_THREADS # define pthread_sigmask GC_pthread_sigmask +#endif # define pthread_join GC_pthread_join # define pthread_detach GC_pthread_detach +#ifndef GC_DARWIN_THREADS # define dlopen GC_dlopen +#endif #endif /* GC_xxxxx_THREADS */ Index: include/private/gc_locks.h =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/include/private/gc_locks.h,v retrieving revision 1.8 diff -u -r1.8 gc_locks.h --- include/private/gc_locks.h 23 Mar 2003 01:36:22 -0000 1.8 +++ include/private/gc_locks.h 16 Apr 2003 02:43:30 -0000 @@ -141,23 +141,24 @@ # if defined(POWERPC) inline static int GC_test_and_set(volatile unsigned int *addr) { int oldval; - int temp = 1; // locked value + int temp = 1; /* locked value */ __asm__ __volatile__( - "1:\tlwarx %0,0,%3\n" // load and reserve - "\tcmpwi %0, 0\n" // if load is - "\tbne 2f\n" // non-zero, return already set - "\tstwcx. %2,0,%1\n" // else store conditional - "\tbne- 1b\n" // retry if lost reservation - "2:\t\n" // oldval is zero if we set + "1:\tlwarx %0,0,%3\n" /* load and reserve */ + "\tcmpwi %0, 0\n" /* if load is */ + "\tbne 2f\n" /* non-zero, return already set */ + "\tstwcx. %2,0,%1\n" /* else store conditional */ + "\tbne- 1b\n" /* retry if lost reservation */ + "\tsync\n" /* import barrier */ + "2:\t\n" /* oldval is zero if we set */ : "=&r"(oldval), "=p"(addr) : "r"(temp), "1"(addr) - : "memory"); - return (int)oldval; + : "cr0","memory"); + return oldval; } # define GC_TEST_AND_SET_DEFINED inline static void GC_clear(volatile unsigned int *addr) { - __asm__ __volatile__("eieio" ::: "memory"); + __asm__ __volatile__("eieio" : : : "memory"); *(addr) = 0; } # define GC_CLEAR_DEFINED @@ -319,6 +320,37 @@ __asm__ __volatile__("" : : : "memory"); } # endif /* I386 */ + +# if defined(POWERPC) +# if !defined(GENERIC_COMPARE_AND_SWAP) + /* Returns TRUE if the comparison succeeded. */ + inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, + GC_word old, GC_word new_val) + { + int result, dummy; + __asm__ __volatile__( + "1:\tlwarx %0,0,%5\n" + "\tcmpw %0,%4\n" + "\tbne 2f\n" + "\tstwcx. %3,0,%2\n" + "\tbne- 1b\n" + "\tsync\n" + "\tli %1, 1\n" + "\tb 3f\n" + "2:\tli %1, 0\n" + "3:\t\n" + : "=&r" (dummy), "=r" (result), "=p" (addr) + : "r" (new_val), "r" (old), "2"(addr) + : "cr0","memory"); + return (GC_bool) result; + } +# endif /* !GENERIC_COMPARE_AND_SWAP */ + inline static void GC_memory_barrier() + { + __asm__ __volatile__("sync" : : : "memory"); + } +# endif /* POWERPC */ + # if defined(IA64) # if !defined(GENERIC_COMPARE_AND_SWAP) inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, Index: include/private/gc_priv.h =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/include/private/gc_priv.h,v retrieving revision 1.11 diff -u -r1.11 gc_priv.h --- include/private/gc_priv.h 4 Mar 2003 22:18:08 -0000 1.11 +++ include/private/gc_priv.h 16 Apr 2003 02:43:32 -0000 @@ -347,7 +347,8 @@ # include # define BCOPY_EXISTS # endif -# if defined(MACOSX) +# if defined(DARWIN) +# include # define BCOPY_EXISTS # endif @@ -379,7 +380,8 @@ + GC_page_size) \ + GC_page_size-1) # else -# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \ +/* FIXME: Darwin mmap works properly in 6.2alpha4, backport the mmap code */ +# if defined(NEXT) || defined(DOS4GW) || defined(DARWIN) || \ (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \ (defined(SUNOS5) && !defined(USE_MMAP)) # define GET_MEM(bytes) HBLKPTR((size_t) \ @@ -1452,6 +1454,7 @@ /* Set all mark bits associated with */ /* a free list. */ void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp)); +void GC_remove_roots_inner GC_PROTO((char * b, char * e)); GC_bool GC_is_static_root GC_PROTO((ptr_t p)); /* Is the address p in one of the registered static */ /* root sections? */ Index: include/private/gcconfig.h =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/include/private/gcconfig.h,v retrieving revision 1.30 diff -u -r1.30 gcconfig.h --- include/private/gcconfig.h 10 Apr 2003 00:08:10 -0000 1.30 +++ include/private/gcconfig.h 16 Apr 2003 02:43:34 -0000 @@ -244,12 +244,12 @@ # endif # if defined(macosx) || \ defined(__APPLE__) && defined(__MACH__) && defined(__ppc__) -# define MACOSX +# define DARWIN # define POWERPC # define mach_type_known # endif # if defined(__APPLE__) && defined(__MACH__) && defined(__i386__) -# define MACOSX +# define DARWIN # define I386 --> Not really supported, but at least we recognize it. # endif @@ -676,16 +676,34 @@ extern int _end[]; # define DATAEND (_end) # endif -# ifdef MACOSX +# ifdef DARWIN /* There are reasons to suspect this may not be reliable. */ # define ALIGNMENT 4 -# define OS_TYPE "MACOSX" +# define OS_TYPE "DARWIN" +# define DYNAMIC_LOADING + /* XXX: see get_end(3), get_etext() and get_end() should not be used */ # define DATASTART ((ptr_t) get_etext()) # define STACKBOTTOM ((ptr_t) 0xc0000000) -# define DATAEND /* not needed */ -# undef MPROTECT_VDB +# define DATAEND ((ptr_t) get_end()) +/* +/* +MMAP support in this version of the collector is broken. It works properly +in 6.2alpha4. FIXME backport the MMAP changes. +# define USE_MMAP +# define USE_MMAP_ANON +*/ +/* # define MPROTECT_VDB -- There is some evidence that this breaks + * on some minor versions of DARWIN, i.e. 10.2.3. In theory, + * it should be OK */ # include # define GETPAGESIZE() getpagesize() +# if defined(USE_PPC_PREFETCH) && defined(__GNUC__) + /* The performance impact of prefetches is untested */ +# define PREFETCH(x) \ + __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x))) +# define PREFETCH_FOR_WRITE(x) \ + __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x))) +# endif # endif # ifdef NETBSD # define ALIGNMENT 4 @@ -1743,7 +1761,7 @@ # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \ || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \ - || defined(BSD) || defined(_AIX) || defined(MACOSX) || defined(OSF1) + || defined(BSD) || defined(_AIX) || defined(DARWIN) || defined(OSF1) # define UNIX_LIKE /* Basic Unix-like system calls work. */ # endif @@ -1848,7 +1866,7 @@ # define THREADS # endif -# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \ +# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \ || defined(LINT) || defined(MSWINCE) \ || (defined(I386) && defined(__LCC__)) /* Use setjmp based hack to mark from callee-save registers. */ Index: tests/test.c =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/tests/test.c,v retrieving revision 1.7 diff -u -r1.7 test.c --- tests/test.c 12 Feb 2002 04:37:57 -0000 1.7 +++ tests/test.c 16 Apr 2003 02:43:35 -0000 @@ -1326,6 +1326,10 @@ int dummy; # endif n_tests = 0; + +#if defined(__APPLE__) && defined(__MACH__) + GC_INIT(); +#endif # if defined(DJGPP) /* No good way to determine stack base from library; do it */ @@ -1625,6 +1629,10 @@ (void)GC_printf0("pthread_default_stacksize_np failed.\n"); } # endif /* GC_HPUX_THREADS */ +# if defined(__APPLE__) && defined(__MACH__) + GC_INIT(); +# endif + pthread_attr_init(&attr); # if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS) pthread_attr_setstacksize(&attr, 1000000); Index: tests/test_cpp.cc =================================================================== RCS file: /cvsroot/gcc/gcc/boehm-gc/tests/test_cpp.cc,v retrieving revision 1.2 diff -u -r1.2 test_cpp.cc --- tests/test_cpp.cc 17 Aug 2001 18:30:51 -0000 1.2 +++ tests/test_cpp.cc 16 Apr 2003 02:43:36 -0000 @@ -189,6 +189,8 @@ # endif #endif + GC_init(); + # if defined(MACOS) // MacOS char* argv_[] = {"test_cpp", "10"}; // doesn't argv = argv_; // have a