1 --- boehm-gc/Makefile.direct Mon Feb 11 20:37:53 2002
2 +++ boehm-gc/Makefile.direct Mon Jun 16 01:19:56 2003
4 ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
5 ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
6 ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
7 - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
8 + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
9 # ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
10 # alpha_mach_dep.s assumes that pointers are not saved in fp registers.
11 # Gcc on a 21264 can spill pointers to fp registers. Oops.
13 ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs`
14 ./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`
15 ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
16 - ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
17 + ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
18 ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
19 ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
20 ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
21 diff -ur boehm-gc/Makefile.dist gcc-3.3+/boehm-gc/Makefile.dist
22 --- boehm-gc/Makefile.dist Fri Aug 17 11:30:44 2001
23 +++ boehm-gc/Makefile.dist Mon Jun 16 01:19:56 2003
25 ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
26 ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
27 ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
28 - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
29 + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
30 # ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
31 # alpha_mach_dep.s assumes that pointers are not saved in fp registers.
32 # Gcc on a 21264 can spill pointers to fp registers. Oops.
34 ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs`
35 ./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`
36 ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
37 - ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
38 + ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
39 ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
40 ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
41 ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
42 diff -ur boehm-gc/Makefile.dj gcc-3.3+/boehm-gc/Makefile.dj
43 --- boehm-gc/Makefile.dj Tue Oct 16 02:01:34 2001
44 +++ boehm-gc/Makefile.dj Mon Jun 16 01:19:56 2003
46 ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
47 ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
48 ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
49 - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
50 + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
51 ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
52 ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s
53 ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
54 diff -ur boehm-gc/configure gcc-3.3+/boehm-gc/configure
55 --- boehm-gc/configure Tue May 13 17:18:14 2003
56 +++ boehm-gc/configure Mon Jun 16 01:19:56 2003
57 @@ -2818,6 +2818,23 @@
62 + cat >> confdefs.h <<\EOF
63 +#define GC_DARWIN_THREADS 1
66 + cat >> confdefs.h <<\EOF
67 +#define THREAD_LOCAL_ALLOC 1
70 + if test "${enable_parallel_mark}" = yes; then
71 + cat >> confdefs.h <<\EOF
72 +#define PARALLEL_MARK 1
81 diff -ur boehm-gc/configure.in gcc-3.3+/boehm-gc/configure.in
82 --- boehm-gc/configure.in Mon Apr 28 13:55:07 2003
83 +++ boehm-gc/configure.in Mon Jun 16 01:19:56 2003
89 + AC_DEFINE(GC_DARWIN_THREADS)
90 + AC_DEFINE(THREAD_LOCAL_ALLOC)
91 + if test "${enable_parallel_mark}" = yes; then
92 + AC_DEFINE(PARALLEL_MARK)
103 -AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
107 + AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
110 AC_SUBST(EXTRA_TEST_LIBS)
112 target_all=libgcjgc.la
113 Only in boehm-gc: configure.in.orig
114 Only in boehm-gc: configure.orig
115 Only in boehm-gc: configure.rej
116 diff -ur boehm-gc/dyn_load.c gcc-3.3+/boehm-gc/dyn_load.c
117 --- boehm-gc/dyn_load.c Mon Mar 3 22:38:30 2003
118 +++ boehm-gc/dyn_load.c Mon Jun 16 01:19:56 2003
120 !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
121 !defined(RS6000) && !defined(SCO_ELF) && \
122 !(defined(FREEBSD) && defined(__ELF__)) && \
123 - !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD)
124 + !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
126 --> We only know how to find data segments of dynamic libraries for the
127 --> above. Additional SVR4 variants might not be too
129 @@ -1056,7 +1057,122 @@
135 +#warning FIXME __private_extern__ support in gcc
136 +#define __private_extern__
137 +#include <mach-o/dyld.h>
138 +#include <mach-o/getsect.h>
140 +/*#define DARWIN_DEBUG*/
142 +const static struct {
145 +} GC_dyld_sections[] = {
146 + { SEG_DATA, SECT_DATA },
147 + { SEG_DATA, SECT_BSS },
148 + { SEG_DATA, SECT_COMMON }
152 +static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) {
154 + c = _dyld_image_count();
155 + for(i=0;i<c;i++) if(_dyld_get_image_header(i) == hdr)
156 + return _dyld_get_image_name(i);
161 +/* This should never be called by a thread holding the lock */
162 +static void GC_dyld_image_add(struct mach_header* hdr, unsigned long slide) {
163 + unsigned long start,end,i;
164 + const struct section *sec;
165 + for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
166 + sec = getsectbynamefromheader(
167 + hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
168 + if(sec == NULL || sec->size == 0) continue;
169 + start = slide + sec->addr;
170 + end = start + sec->size;
171 +# ifdef DARWIN_DEBUG
172 + GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n",
173 + start,end,sec->size,GC_dyld_name_for_hdr(hdr));
175 + GC_add_roots((char*)start,(char*)end);
177 +# ifdef DARWIN_DEBUG
178 + GC_print_static_roots();
182 +/* This should never be called by a thread holding the lock */
183 +static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) {
184 + unsigned long start,end,i;
185 + const struct section *sec;
186 + for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
187 + sec = getsectbynamefromheader(
188 + hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
189 + if(sec == NULL || sec->size == 0) continue;
190 + start = slide + sec->addr;
191 + end = start + sec->size;
192 +# ifdef DARWIN_DEBUG
193 + GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n",
194 + start,end,sec->size,GC_dyld_name_for_hdr(hdr));
196 + GC_remove_roots((char*)start,(char*)end);
198 +# ifdef DARWIN_DEBUG
199 + GC_print_static_roots();
203 +void GC_register_dynamic_libraries() {
204 + /* Currently does nothing. The callbacks are setup by GC_init_dyld()
205 + The dyld library takes it from there. */
208 +/* The _dyld_* functions have an internal lock so no _dyld functions
209 + can be called while the world is stopped without the risk of a deadlock.
210 + Because of this we MUST setup callbacks BEFORE we ever stop the world.
211 + This should be called BEFORE any thread in created and WITHOUT the
212 + allocation lock held. */
214 +void GC_init_dyld() {
215 + static unsigned long dummy;
216 +# ifdef DARWIN_DEBUG
217 + GC_printf0("Forcing full bind of GC code...\n");
220 + if(!_dyld_bind_fully_image_containing_address(&dummy))
221 + GC_abort("_dyld_bind_fully_image_containing_addres failed");
223 +# ifdef DARWIN_DEBUG
224 + GC_printf0("Registering dyld callbacks...\n");
227 + /* Apple's Documentation:
228 + When you call _dyld_register_func_for_add_image, the dynamic linker runtime calls
229 + the specified callback (func) once for each of the images that is currently loaded
230 + into the program. When a new image is added to the program, your callback is called
231 + again with the mach_header for the new image, and the virtual memory slide amount
234 + This WILL properly register existing and all future libraries
237 + _dyld_register_func_for_add_image(GC_dyld_image_add);
238 + _dyld_register_func_for_remove_image(GC_dyld_image_remove);
241 +#define HAVE_REGISTER_MAIN_STATIC_DATA
242 +GC_bool GC_register_main_static_data()
244 + /* Already done through dyld callbacks */
250 #else /* !DYNAMIC_LOADING */
252 diff -ur boehm-gc/gc_dlopen.c gcc-3.3+/boehm-gc/gc_dlopen.c
253 --- boehm-gc/gc_dlopen.c Tue Oct 16 02:01:35 2001
254 +++ boehm-gc/gc_dlopen.c Mon Jun 16 01:19:56 2003
257 #include "private/gc_priv.h"
259 -# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)
260 +# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
261 + || defined(GC_SOLARIS_THREADS)
263 # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
264 /* To support various threads pkgs, gc.h interposes on dlopen by */
265 diff -ur boehm-gc/include/gc.h gcc-3.3+/boehm-gc/include/gc.h
266 --- boehm-gc/include/gc.h Mon Feb 11 20:37:56 2002
267 +++ boehm-gc/include/gc.h Mon Jun 16 01:19:56 2003
270 # if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
271 defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
272 - defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
273 + defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
274 + defined(GC_DARWIN_THREADS)
279 GC_API void GC_add_roots GC_PROTO((char * low_address,
280 char * high_address_plus_1));
282 +/* Remove a root segment. Wizards only. */
283 +GC_API void GC_remove_roots GC_PROTO((char * low_address,
284 + char * high_address_plus_1));
286 /* Add a displacement to the set of those considered valid by the */
287 /* collector. GC_register_displacement(n) means that if p was returned */
288 /* by GC_malloc, then (char *)p + n will be considered to be a valid */
291 # define GC_INIT() { GC_add_roots(DATASTART, DATAEND); }
294 +# if defined(__APPLE__) && defined(__MACH__)
295 +# define GC_INIT() { GC_init(); }
302 diff -ur boehm-gc/include/gc_pthread_redirects.h gcc-3.3+/boehm-gc/include/gc_pthread_redirects.h
303 --- boehm-gc/include/gc_pthread_redirects.h Tue Oct 16 21:55:28 2001
304 +++ boehm-gc/include/gc_pthread_redirects.h Mon Jun 16 01:19:56 2003
306 int GC_pthread_create(pthread_t *new_thread,
307 const pthread_attr_t *attr,
308 void *(*start_routine)(void *), void *arg);
309 +#ifndef GC_DARWIN_THREADS
310 int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
312 int GC_pthread_join(pthread_t thread, void **retval);
313 int GC_pthread_detach(pthread_t thread);
315 # define pthread_create GC_pthread_create
316 +#ifndef GC_DARWIN_THREADS
317 # define pthread_sigmask GC_pthread_sigmask
319 # define pthread_join GC_pthread_join
320 # define pthread_detach GC_pthread_detach
321 +#ifndef GC_DARWIN_THREADS
322 # define dlopen GC_dlopen
325 #endif /* GC_xxxxx_THREADS */
327 diff -ur boehm-gc/include/private/gc_locks.h gcc-3.3+/boehm-gc/include/private/gc_locks.h
328 --- boehm-gc/include/private/gc_locks.h Fri Sep 27 13:40:06 2002
329 +++ boehm-gc/include/private/gc_locks.h Mon Jun 16 01:19:56 2003
330 @@ -145,23 +145,24 @@
331 # if defined(POWERPC)
332 inline static int GC_test_and_set(volatile unsigned int *addr) {
334 - int temp = 1; // locked value
335 + int temp = 1; /* locked value */
337 __asm__ __volatile__(
338 - "1:\tlwarx %0,0,%3\n" // load and reserve
339 - "\tcmpwi %0, 0\n" // if load is
340 - "\tbne 2f\n" // non-zero, return already set
341 - "\tstwcx. %2,0,%1\n" // else store conditional
342 - "\tbne- 1b\n" // retry if lost reservation
343 - "2:\t\n" // oldval is zero if we set
344 + "1:\tlwarx %0,0,%3\n" /* load and reserve */
345 + "\tcmpwi %0, 0\n" /* if load is */
346 + "\tbne 2f\n" /* non-zero, return already set */
347 + "\tstwcx. %2,0,%1\n" /* else store conditional */
348 + "\tbne- 1b\n" /* retry if lost reservation */
349 + "\tsync\n" /* import barrier */
350 + "2:\t\n" /* oldval is zero if we set */
351 : "=&r"(oldval), "=p"(addr)
352 : "r"(temp), "1"(addr)
354 - return (int)oldval;
358 # define GC_TEST_AND_SET_DEFINED
359 inline static void GC_clear(volatile unsigned int *addr) {
360 - __asm__ __volatile__("eieio" ::: "memory");
361 + __asm__ __volatile__("eieio" : : : "memory");
364 # define GC_CLEAR_DEFINED
366 __asm__ __volatile__("" : : : "memory");
370 +# if defined(POWERPC)
371 +# if !defined(GENERIC_COMPARE_AND_SWAP)
372 + /* Returns TRUE if the comparison succeeded. */
373 + inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
374 + GC_word old, GC_word new_val)
377 + __asm__ __volatile__(
378 + "1:\tlwarx %0,0,%5\n"
381 + "\tstwcx. %3,0,%2\n"
388 + : "=&r" (dummy), "=r" (result), "=p" (addr)
389 + : "r" (new_val), "r" (old), "2"(addr)
391 + return (GC_bool) result;
393 +# endif /* !GENERIC_COMPARE_AND_SWAP */
394 + inline static void GC_memory_barrier()
396 + __asm__ __volatile__("sync" : : : "memory");
398 +# endif /* POWERPC */
401 # if !defined(GENERIC_COMPARE_AND_SWAP)
402 inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
403 Only in boehm-gc/include/private: gc_locks.h.orig
404 diff -ur boehm-gc/include/private/gc_priv.h gcc-3.3+/boehm-gc/include/private/gc_priv.h
405 --- boehm-gc/include/private/gc_priv.h Tue Mar 4 09:56:49 2003
406 +++ boehm-gc/include/private/gc_priv.h Mon Jun 16 01:19:56 2003
409 # define BCOPY_EXISTS
411 -# if defined(MACOSX)
412 +# if defined(DARWIN)
413 +# include <string.h>
414 # define BCOPY_EXISTS
421 -# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
422 +/* FIXME: Darwin mmap works properly in 6.2alpha4, backport the mmap code */
423 +# if defined(NEXT) || defined(DOS4GW) || defined(DARWIN) || \
424 (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
425 (defined(SUNOS5) && !defined(USE_MMAP))
426 # define GET_MEM(bytes) HBLKPTR((size_t) \
427 @@ -1452,6 +1454,7 @@
428 /* Set all mark bits associated with */
430 void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp));
431 +void GC_remove_roots_inner GC_PROTO((char * b, char * e));
432 GC_bool GC_is_static_root GC_PROTO((ptr_t p));
433 /* Is the address p in one of the registered static */
435 diff -ur boehm-gc/include/private/gcconfig.h gcc-3.3+/boehm-gc/include/private/gcconfig.h
436 --- boehm-gc/include/private/gcconfig.h Wed Apr 9 17:08:01 2003
437 +++ boehm-gc/include/private/gcconfig.h Mon Jun 16 01:19:56 2003
438 @@ -244,12 +244,12 @@
440 # if defined(macosx) || \
441 defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
445 # define mach_type_known
447 # if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
451 --> Not really supported, but at least we recognize it.
453 @@ -676,16 +676,34 @@
455 # define DATAEND (_end)
459 /* There are reasons to suspect this may not be reliable. */
461 -# define OS_TYPE "MACOSX"
462 +# define OS_TYPE "DARWIN"
463 +# define DYNAMIC_LOADING
464 + /* XXX: see get_end(3), get_etext() and get_end() should not be used */
465 # define DATASTART ((ptr_t) get_etext())
466 # define STACKBOTTOM ((ptr_t) 0xc0000000)
467 -# define DATAEND /* not needed */
468 -# undef MPROTECT_VDB
469 +# define DATAEND ((ptr_t) get_end())
472 +MMAP support in this version of the collector is broken. It works properly
473 +in 6.2alpha4. FIXME backport the MMAP changes.
475 +# define USE_MMAP_ANON
477 +/* # define MPROTECT_VDB -- There is some evidence that this breaks
478 + * on some minor versions of DARWIN, i.e. 10.2.3. In theory,
479 + * it should be OK */
481 # define GETPAGESIZE() getpagesize()
482 +# if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
483 + /* The performance impact of prefetches is untested */
484 +# define PREFETCH(x) \
485 + __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
486 +# define PREFETCH_FOR_WRITE(x) \
487 + __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
492 @@ -1743,7 +1761,7 @@
494 # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \
495 || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
496 - || defined(BSD) || defined(_AIX) || defined(MACOSX) || defined(OSF1)
497 + || defined(BSD) || defined(_AIX) || defined(DARWIN) || defined(OSF1)
498 # define UNIX_LIKE /* Basic Unix-like system calls work. */
501 @@ -1848,7 +1866,7 @@
505 -# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \
506 +# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \
507 || defined(LINT) || defined(MSWINCE) \
508 || (defined(I386) && defined(__LCC__))
509 /* Use setjmp based hack to mark from callee-save registers. */
510 Only in boehm-gc/include/private: gcconfig.h.orig
511 diff -ur boehm-gc/linux_threads.c gcc-3.3+/boehm-gc/linux_threads.c
512 --- boehm-gc/linux_threads.c Fri Mar 29 14:52:12 2002
513 +++ boehm-gc/linux_threads.c Mon Jun 16 01:19:56 2003
516 # include "private/gc_priv.h"
518 -# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
519 +# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_IFIC) \
520 && !defined(USE_HPUX_TLS)
521 # define USE_HPUX_TLS
524 +#if defined(GC_DARWIN_THREADS)
525 +# define USE_PTHREAD_SPECIFIC
528 # ifdef THREAD_LOCAL_ALLOC
529 # if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_HPUX_TLS)
530 # include "private/specific.h"
533 # include <sys/mman.h>
534 # include <sys/time.h>
535 -# include <semaphore.h>
537 # include <sys/types.h>
538 # include <sys/stat.h>
541 +#if !defined(GC_DARWIN_THREADS)
542 +/* We have our own simple semaphore implementation of darwin */
543 +# include <semaphore.h>
544 +#endif /* !GC_DARWIN_THREADS */
546 +#if defined(GC_DARWIN_THREADS)
547 +# include <sys/sysctl.h>
548 +# include <mach/mach_types.h>
549 +# include <mach/thread_act.h>
550 +#endif /* GC_DARWIN_THREADS */
555 @@ -104,11 +118,91 @@
556 # define WRAP_FUNC(f) GC_##f
557 # define REAL_FUNC(f) f
558 # undef pthread_create
559 +# if !defined(GC_DARWIN_THREADS)
560 # undef pthread_sigmask
563 # undef pthread_detach
566 +#if defined(GC_DARWIN_THREADS)
569 + This is a very simple semaphore implementation for darwin. It
570 + is implemented in terms of pthreads calls so it isn't async signal
571 + safe. This isn't a problem because signals aren't used in to
572 + suspend threads on darwin.
576 + pthread_mutex_t mutex;
577 + pthread_cond_t cond;
581 +static int sem_init(sem_t *sem, int pshared, int value) {
584 + GC_abort("sem_init with pshared set");
585 + sem->value = value;
587 + ret = pthread_mutex_init(&sem->mutex,NULL);
588 + if(ret < 0) return -1;
589 + ret = pthread_cond_init(&sem->cond,NULL);
590 + if(ret < 0) return -1;
594 +static int sem_post(sem_t *sem) {
595 + if(pthread_mutex_lock(&sem->mutex) < 0)
598 + if(pthread_cond_signal(&sem->cond) < 0) {
599 + pthread_mutex_unlock(&sem->mutex);
602 + if(pthread_mutex_unlock(&sem->mutex) < 0)
607 +static int sem_wait(sem_t *sem) {
608 + if(pthread_mutex_lock(&sem->mutex) < 0)
610 + while(sem->value == 0) {
611 + pthread_cond_wait(&sem->cond,&sem->mutex);
614 + if(pthread_mutex_unlock(&sem->mutex) < 0)
619 +static int sem_destroy(sem_t *sem) {
621 + ret = pthread_cond_destroy(&sem->cond);
622 + if(ret < 0) return -1;
623 + ret = pthread_mutex_destroy(&sem->mutex);
624 + if(ret < 0) return -1;
629 +/* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
631 + "The space beneath the stack pointer, where a new stack frame would normally
632 + be allocated, is called the red zone. This area as shown in Figure 3-2 may
633 + be used for any purpose as long as a new stack frame does not need to be
634 + added to the stack."
636 + Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then
637 + it must set up a stack frame just like routines that call other routines."
639 +#define DARWIN_PPC_RED_ZONE 224
642 +#endif /* !GC_DARWIN_THREADS */
648 /* guaranteed to be dead, but we may */
649 /* not yet have registered the join.) */
651 +#ifdef GC_DARWIN_THREADS
652 + mach_port_t mach_thread;
655 # define FINISHED 1 /* Thread has exited. */
656 # define DETACHED 2 /* Thread is intended to be detached. */
658 ptr_t backing_store_end;
659 ptr_t backing_store_ptr;
661 +#ifndef GC_DARWIN_THREADS
664 void * status; /* The value returned from the thread. */
665 /* Used only to avoid premature */
666 /* reclamation of any data it might */
668 * pointer(s) and acknowledge.
671 +#if !defined(GC_DARWIN_THREADS)
672 #ifndef SIG_THR_RESTART
673 # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
674 # define SIG_THR_RESTART _SIGRTMIN + 5
676 # define SIG_THR_RESTART SIGXCPU
681 +#if !defined(GC_DARWIN_THREADS)
682 sem_t GC_suspend_ack_sem;
683 +#endif /* !GC_DARWIN_THREADS */
689 #endif /* !PARALLEL_MARK */
691 +#if !defined(GC_DARWIN_THREADS)
692 void GC_suspend_handler(int sig)
696 GC_printf1("Continuing 0x%x\n", my_thread);
699 +#endif /* !GC_DARWIN_THREADS */
701 +#if !defined(GC_DARWIN_THREADS)
702 void GC_restart_handler(int sig)
706 GC_printf1("In GC_restart_handler for 0x%x\n", pthread_self());
709 +#endif /* !GC_DARWIN_THREADS */
711 /* Defining INSTALL_LOOPING_SEGV_HANDLER causes SIGSEGV and SIGBUS to */
712 /* result in an infinite loop in a signal handler. This can be very */
714 register GC_thread p;
715 register int n_live_threads = 0;
717 +# if defined(GC_DARWIN_THREADS)
718 + kern_return_t kern_result;
719 +# if defined(POWERPC)
720 + struct ppc_thread_state thread_state;
721 + thread_state_flavor_t flavor = PPC_THREAD_STATE;
722 + mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT;
724 +# error FIXME for non-ppc OS X
728 GC_stopping_thread = my_thread; /* debugging only. */
729 GC_stopping_pid = getpid(); /* debugging only. */
732 GC_printf1("Sending suspend signal to 0x%x\n", p -> id);
734 +# if defined(GC_DARWIN_THREADS)
735 + GC_ASSERT(p->mach_thread != 0 && p->id != 0);
736 + kern_result = thread_suspend(p->mach_thread);
737 + if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed");
738 + kern_result = thread_abort_safely(p->mach_thread);
739 + /* This shouldn't really be fatal, I don't think. The documentation is kind of unclear */
740 + if(kern_result != KERN_SUCCESS) GC_printf1("thread_abort_safely failed (%ul)",kern_result);
741 + kern_result = thread_get_state(p->mach_thread,flavor,(natural_t*)&thread_state,&thread_state_count);
742 + if(kern_result != KERN_SUCCESS) ABORT("thread_get_state failed");
743 +# if defined(POWERPC)
744 + /* The space just below the stack pointer can also be used.
745 + See the comment about the red zone at the top of the file */
746 + p->stack_ptr = (void*)(thread_state.r1 - DARWIN_PPC_RED_ZONE);
747 + /* Push all the general purpose registers, except the stack pointer. */
748 + GC_push_one(thread_state.r0);
749 + GC_push_one(thread_state.r2);
750 + GC_push_one(thread_state.r3);
751 + GC_push_one(thread_state.r4);
752 + GC_push_one(thread_state.r5);
753 + GC_push_one(thread_state.r6);
754 + GC_push_one(thread_state.r7);
755 + GC_push_one(thread_state.r8);
756 + GC_push_one(thread_state.r9);
757 + GC_push_one(thread_state.r10);
758 + GC_push_one(thread_state.r11);
759 + GC_push_one(thread_state.r12);
760 + GC_push_one(thread_state.r13);
761 + GC_push_one(thread_state.r14);
762 + GC_push_one(thread_state.r15);
763 + GC_push_one(thread_state.r16);
764 + GC_push_one(thread_state.r17);
765 + GC_push_one(thread_state.r18);
766 + GC_push_one(thread_state.r19);
767 + GC_push_one(thread_state.r20);
768 + GC_push_one(thread_state.r21);
769 + GC_push_one(thread_state.r22);
770 + GC_push_one(thread_state.r23);
771 + GC_push_one(thread_state.r24);
772 + GC_push_one(thread_state.r25);
773 + GC_push_one(thread_state.r26);
774 + GC_push_one(thread_state.r27);
775 + GC_push_one(thread_state.r28);
776 + GC_push_one(thread_state.r29);
777 + GC_push_one(thread_state.r30);
778 + GC_push_one(thread_state.r31);
780 +# error fixme for non ppc os x
783 +# else /* GC_DARWIN_THREADS */
784 result = pthread_kill(p -> id, SIG_SUSPEND);
787 @@ -839,13 +1006,16 @@
789 ABORT("pthread_kill failed");
791 +# endif /* !GC_DARWIN_THREADS */
795 +# if !defined(GC_DARWIN_THREADS)
796 for (i = 0; i < n_live_threads; i++) {
797 if (0 != sem_wait(&GC_suspend_ack_sem))
798 ABORT("sem_wait in handler failed");
800 +# endif /* GC_DARWIN_THREADS */
801 # ifdef PARALLEL_MARK
802 GC_release_mark_lock();
805 register GC_thread p;
806 register int n_live_threads = 0;
809 +# if defined(GC_DARWIN_THREADS)
810 + kern_return_t kern_result;
813 GC_printf0("World starting\n");
815 @@ -878,6 +1050,12 @@
817 GC_printf1("Sending restart signal to 0x%x\n", p -> id);
819 +# if defined(GC_DARWIN_THREADS)
821 + kern_result = thread_resume(p->mach_thread);
822 + if(kern_result != KERN_SUCCESS) ABORT("thread_resume failed");
824 +# else /* GC_DARWIN_THREADS */
825 result = pthread_kill(p -> id, SIG_THR_RESTART);
830 ABORT("pthread_kill failed");
832 +# endif /* !GC_DARWIN_THREADS */
836 @@ -1039,8 +1218,10 @@
837 if (GC_thr_initialized) return;
838 GC_thr_initialized = TRUE;
840 +# if !defined(GC_DARWIN_THREADS)
841 if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
842 ABORT("sem_init failed");
845 act.sa_flags = SA_RESTART;
846 if (sigfillset(&act.sa_mask) != 0) {
847 @@ -1055,6 +1236,7 @@
851 +# if !defined(GC_DARWIN_THREADS)
852 /* SIG_THR_RESTART is unmasked by the handler when necessary. */
853 act.sa_handler = GC_suspend_handler;
854 if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
855 @@ -1065,6 +1247,7 @@
856 if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) {
857 ABORT("Cannot set SIG_THR_RESTART handler");
859 +# endif /* !GC_DARWIN_THREADS */
860 # ifdef INSTALL_LOOPING_SEGV_HANDLER
861 act.sa_handler = GC_looping_handler;
862 if (sigaction(SIGSEGV, &act, NULL) != 0
863 @@ -1075,6 +1258,9 @@
865 /* Add the initial thread, so we can stop it. */
866 t = GC_new_thread(pthread_self());
867 +# ifdef GC_DARWIN_THREADS
868 + t -> mach_thread = mach_thread_self();
870 t -> stack_ptr = (ptr_t)(&dummy);
871 t -> flags = DETACHED | MAIN_THREAD;
873 @@ -1091,6 +1277,12 @@
874 # if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS)
877 +# if defined(GC_DARWIN_THREADS)
879 + size_t len = sizeof(ncpus);
880 + sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
883 # if defined(GC_LINUX_THREADS)
884 GC_nprocs = GC_get_nprocs();
886 @@ -1150,7 +1342,7 @@
891 +#if !defined(GC_DARWIN_THREADS)
892 int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
895 @@ -1162,6 +1354,7 @@
897 return(REAL_FUNC(pthread_sigmask)(how, set, oset));
899 +#endif /* !GC_DARWIN_THREADS */
901 /* Wrappers for functions that are likely to block for an appreciable */
902 /* length of time. Must be called in pairs, if at all. */
903 @@ -1331,6 +1524,9 @@
906 me = GC_new_thread(my_pthread);
907 +#ifdef GC_DARWIN_THREADS
908 + me -> mach_thread = mach_thread_self();
910 me -> flags = si -> flags;
912 /* me -> stack_end = GC_linux_stack_base(); -- currently (11/99) */
913 diff -ur boehm-gc/mark_rts.c gcc-3.3+/boehm-gc/mark_rts.c
914 --- boehm-gc/mark_rts.c Mon Mar 3 22:38:29 2003
915 +++ boehm-gc/mark_rts.c Mon Jun 16 01:19:56 2003
916 @@ -275,33 +275,72 @@
919 /* Internal use only; lock held. */
920 +static void GC_remove_root_at_pos(i)
923 + GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
924 + GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
925 + GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
926 + GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
930 +#if !defined(MSWIN32) && !defined(MSWINCE)
931 +static void GC_rebuild_root_index()
935 + for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
936 + for (i = 0; i < n_root_sets; i++)
937 + add_roots_to_index(GC_static_roots + i);
941 +/* Internal use only; lock held. */
942 void GC_remove_tmp_roots()
946 for (i = 0; i < n_root_sets; ) {
947 if (GC_static_roots[i].r_tmp) {
949 - (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
950 - GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
951 - GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
952 - GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
954 + GC_remove_root_at_pos(i);
959 -# if !defined(MSWIN32) && !defined(MSWINCE)
963 - for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
964 - for (i = 0; i < n_root_sets; i++)
965 - add_roots_to_index(GC_static_roots + i);
968 + #if !defined(MSWIN32) && !defined(MSWINCE)
969 + GC_rebuild_root_index();
973 +#if !defined(MSWIN32) && !defined(MSWINCE)
974 +void GC_remove_roots(b, e)
981 + GC_remove_roots_inner(b, e);
986 +/* Should only be called when the lock is held */
987 +void GC_remove_roots_inner(b,e)
991 + for (i = 0; i < n_root_sets; ) {
992 + if (GC_static_roots[i].r_start >= (ptr_t)b && GC_static_roots[i].r_end <= (ptr_t)e) {
993 + GC_remove_root_at_pos(i);
998 + GC_rebuild_root_index();
1000 +#endif /* !defined(MSWIN32) && !defined(MSWINCE) */
1002 #if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)
1003 /* Workaround for the OS mapping and unmapping behind our back: */
1004 diff -ur boehm-gc/misc.c gcc-3.3+/boehm-gc/misc.c
1005 --- boehm-gc/misc.c Mon Mar 3 22:38:30 2003
1006 +++ boehm-gc/misc.c Mon Jun 16 01:19:56 2003
1007 @@ -473,6 +473,14 @@
1010 # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
1011 +# if defined(DYNAMIC_LOADING) && defined(DARWIN)
1013 + /* This must be called WITHOUT the allocation lock held
1014 + and before any threads are created */
1015 + extern void GC_init_dyld();
1021 #if defined(MSWIN32) || defined(MSWINCE)
1022 diff -ur boehm-gc/os_dep.c gcc-3.3+/boehm-gc/os_dep.c
1023 --- boehm-gc/os_dep.c Fri Jul 19 01:54:43 2002
1024 +++ boehm-gc/os_dep.c Mon Jun 16 01:19:56 2003
1025 @@ -1087,7 +1087,7 @@
1026 void GC_register_data_segments()
1028 # if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \
1029 - && !defined(MACOSX)
1030 + && !defined(DARWIN)
1031 # if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
1032 /* As of Solaris 2.3, the Solaris threads implementation */
1033 /* allocates the data structure for the initial thread with */
1034 @@ -1104,7 +1104,7 @@
1038 -# if !defined(PCR) && (defined(NEXT) || defined(MACOSX))
1039 +# if !defined(PCR) && (defined(NEXT) || defined(DARWIN))
1040 GC_add_roots_inner(DATASTART, (char *) get_end(), FALSE);
1043 @@ -1829,7 +1829,7 @@
1044 typedef void (* SIG_PF)();
1046 #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
1047 - || defined(MACOSX) || defined(HURD)
1048 + || defined(DARWIN) || defined(HURD)
1050 typedef void (* SIG_PF)(int);
1052 @@ -1897,9 +1897,10 @@
1053 # endif /* !ALPHA */
1056 -# if defined(MACOSX) /* Should also test for PowerPC? */
1057 +# if defined(DARWIN)
1058 typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
1061 /* Decodes the machine instruction which was responsible for the sending of the
1062 SIGBUS signal. Sadly this is the only way to find the faulting address because
1063 the signal handler doesn't get it directly from the kernel (although it is
1064 @@ -2022,7 +2023,10 @@
1066 return (char *)addr;
1068 -#endif /* MACOSX */
1069 +#else /* non-ppc */
1070 +--> FIXME for non-ppc os x
1072 +#endif /* DARWIN */
1074 SIG_PF GC_old_bus_handler;
1075 SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
1076 @@ -2146,7 +2150,7 @@
1080 -# if defined(MACOSX)
1081 +# if defined(DARWIN)
1082 void GC_write_fault_handler(int sig, int code, struct sigcontext *scp)
1083 # define SIG_OK (sig == SIGBUS)
1084 # define CODE_OK (code == 0 /* experimentally determined */)
1085 @@ -2225,7 +2229,7 @@
1089 -# if defined(MACOSX)
1090 +# if defined(DARWIN)
1091 char * addr = get_fault_addr(scp);
1093 # if defined(MSWIN32) || defined(MSWINCE)
1094 @@ -2291,7 +2295,7 @@
1095 (*(REAL_SIG_PF)old_handler) (sig, code, scp);
1100 (*(REAL_SIG_PF)old_handler) (sig, code, scp);
1103 @@ -2389,7 +2393,7 @@
1104 (void)sigaddset(&act.sa_mask, SIG_SUSPEND);
1105 # endif /* SIG_SUSPEND */
1107 -# if defined(MACOSX)
1108 +# if defined(DARWIN)
1109 struct sigaction act, oldact;
1111 act.sa_flags = SA_RESTART;
1112 @@ -2458,7 +2462,7 @@
1116 -# if defined(MACOSX) || defined(HPUX) || defined(LINUX) || defined(HURD)
1117 +# if defined(DARWIN) || defined(HPUX) || defined(LINUX) || defined(HURD)
1118 sigaction(SIGBUS, &act, &oldact);
1119 GC_old_bus_handler = oldact.sa_handler;
1120 if (GC_old_bus_handler == SIG_IGN) {
1121 diff -ur boehm-gc/tests/test.c gcc-3.3+/boehm-gc/tests/test.c
1122 --- boehm-gc/tests/test.c Mon Feb 11 20:37:57 2002
1123 +++ boehm-gc/tests/test.c Mon Jun 16 01:19:56 2003
1124 @@ -1326,6 +1326,10 @@
1129 +#if defined(__APPLE__) && defined(__MACH__)
1134 /* No good way to determine stack base from library; do it */
1135 @@ -1625,6 +1629,10 @@
1136 (void)GC_printf0("pthread_default_stacksize_np failed.\n");
1138 # endif /* GC_HPUX_THREADS */
1139 +# if defined(__APPLE__) && defined(__MACH__)
1143 pthread_attr_init(&attr);
1144 # if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS)
1145 pthread_attr_setstacksize(&attr, 1000000);
1146 diff -ur boehm-gc/tests/test_cpp.cc gcc-3.3+/boehm-gc/tests/test_cpp.cc
1147 --- boehm-gc/tests/test_cpp.cc Fri Aug 17 11:30:51 2001
1148 +++ boehm-gc/tests/test_cpp.cc Mon Jun 16 01:19:56 2003
1155 # if defined(MACOS) // MacOS
1156 char* argv_[] = {"test_cpp", "10"}; // doesn't
1157 argv = argv_; // have a
1158 diff -ur boehm-gc/threadlibs.c gcc-3.3+/boehm-gc/threadlibs.c
1159 --- boehm-gc/threadlibs.c Mon Feb 11 20:37:53 2002
1160 +++ boehm-gc/threadlibs.c Mon Jun 16 01:19:56 2003
1162 "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n");
1164 # if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \
1165 - || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS)
1166 + || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) \
1167 + || defined(GC_DARWIN_THREADS)
1168 printf("-lpthread\n");
1170 # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
1171 --- gcc/unwind-dw2-fde-darwin.c Sun Sep 7 01:26:14 2003
1172 +++ gcc/unwind-dw2-fde-darwin.c Sun Sep 7 01:26:17 2003
1174 /* Locate the FDE entry for a given address, using Darwin's keymgr support. */
1176 #include "tconfig.h"
1177 +#include <stddef.h>