| 1 | 6.5 update:
|
|---|
| 2 | I disabled incremental GC on Darwin in this version, since I couldn't
|
|---|
| 3 | get gctest to pass when the GC was built as a dynamic library. Building
|
|---|
| 4 | with -DMPROTECT_VDB (and threads) on the command line should get you
|
|---|
| 5 | back to the old state. - HB
|
|---|
| 6 |
|
|---|
| 7 | ./configure --enable-cplusplus results in a "make check" failure, probably
|
|---|
| 8 | because the ::delete override ends up in a separate dl, and Darwin dynamic
|
|---|
| 9 | loader semantics appear to be such that this is not really visible to the
|
|---|
| 10 | main program, unlike on ELF systems. Someone who understands dynamic
|
|---|
| 11 | loading needs to lookat this. For now, gc_cpp.o needs to be linked
|
|---|
| 12 | statically, if needed. - HB
|
|---|
| 13 |
|
|---|
| 14 | Darwin/MacOSX Support - December 16, 2003
|
|---|
| 15 | =========================================
|
|---|
| 16 |
|
|---|
| 17 | Important Usage Notes
|
|---|
| 18 | =====================
|
|---|
| 19 |
|
|---|
| 20 | GC_init() MUST be called before calling any other GC functions. This
|
|---|
| 21 | is necessary to properly register segments in dynamic libraries. This
|
|---|
| 22 | call is required even if you code does not use dynamic libraries as the
|
|---|
| 23 | dyld code handles registering all data segments.
|
|---|
| 24 |
|
|---|
| 25 | When your use of the garbage collector is confined to dylibs and you
|
|---|
| 26 | cannot call GC_init() before your libraries' static initializers have
|
|---|
| 27 | run and perhaps called GC_malloc(), create an initialization routine
|
|---|
| 28 | for each library to call GC_init():
|
|---|
| 29 |
|
|---|
| 30 | #include <gc/gc.h>
|
|---|
| 31 | extern "C" void my_library_init() { GC_init(); }
|
|---|
| 32 |
|
|---|
| 33 | Compile this code into a my_library_init.o, and link it into your
|
|---|
| 34 | dylib. When you link the dylib, pass the -init argument with
|
|---|
| 35 | _my_library_init (e.g. gcc -dynamiclib -o my_library.dylib a.o b.o c.o
|
|---|
| 36 | my_library_init.o -init _my_library_init). This causes
|
|---|
| 37 | my_library_init() to be called before any static initializers, and
|
|---|
| 38 | will initialize the garbage collector properly.
|
|---|
| 39 |
|
|---|
| 40 | Note: It doesn't hurt to call GC_init() more than once, so it's best,
|
|---|
| 41 | if you have an application or set of libraries that all use the
|
|---|
| 42 | garbage collector, to create an initialization routine for each of
|
|---|
| 43 | them that calls GC_init(). Better safe than sorry.
|
|---|
| 44 |
|
|---|
| 45 | The incremental collector is still a bit flaky on darwin. It seems to
|
|---|
| 46 | work reliably with workarounds for a few possible bugs in place however
|
|---|
| 47 | these workaround may not work correctly in all cases. There may also
|
|---|
| 48 | be additional problems that I have not found.
|
|---|
| 49 |
|
|---|
| 50 | Thread-local GC allocation will not work with threads that are not
|
|---|
| 51 | created using the GC-provided override of pthread_create(). Threads
|
|---|
| 52 | created without the GC-provided pthread_create() do not have the
|
|---|
| 53 | necessary data structures in the GC to store this data.
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 | Implementation Information
|
|---|
| 57 | ==========================
|
|---|
| 58 | Darwin/MacOSX support is nearly complete. Thread support is reliable on
|
|---|
| 59 | Darwin 6.x (MacOSX 10.2) and there have been reports of success on older
|
|---|
| 60 | Darwin versions (MacOSX 10.1). Shared library support had also been
|
|---|
| 61 | added and the gc can be run from a shared library. There is currently only
|
|---|
| 62 | support for Darwin/PPC although adding x86 support should be trivial.
|
|---|
| 63 |
|
|---|
| 64 | Thread support is implemented in terms of mach thread_suspend and
|
|---|
| 65 | thread_resume calls. These provide a very clean interface to thread
|
|---|
| 66 | suspension. This implementation doesn't rely on pthread_kill so the
|
|---|
| 67 | code works on Darwin < 6.0 (MacOSX 10.1). All the code to stop and
|
|---|
| 68 | start the world is located in darwin_stop_world.c.
|
|---|
| 69 |
|
|---|
| 70 | Since not all uses of the GC enable clients to override pthread_create()
|
|---|
| 71 | before threads have been created, the code for stopping the world has
|
|---|
| 72 | been rewritten to look for threads using Mach kernel calls. Each
|
|---|
| 73 | thread identified in this way is suspended and resumed as above. In
|
|---|
| 74 | addition, since Mach kernel threads do not contain pointers to their
|
|---|
| 75 | stacks, a stack-walking function has been written to find the stack
|
|---|
| 76 | limits. Given an initial stack pointer (for the current thread, a
|
|---|
| 77 | pointer to a stack-allocated local variable will do; for a non-active
|
|---|
| 78 | thread, we grab the value of register 1 (on PowerPC)), it
|
|---|
| 79 | will walk the PPC Mach-O-ABI compliant stack chain until it reaches the
|
|---|
| 80 | top of the stack. This appears to work correctly for GCC-compiled C,
|
|---|
| 81 | C++, Objective-C, and Objective-C++ code, as well as for Java
|
|---|
| 82 | programs that use JNI. If you run code that does not follow the stack
|
|---|
| 83 | layout or stack pointer conventions laid out in the PPC Mach-O ABI,
|
|---|
| 84 | then this will likely crash the garbage collector.
|
|---|
| 85 |
|
|---|
| 86 | The original incremental collector support unfortunatelly no longer works
|
|---|
| 87 | on recent Darwin versions. It also relied on some undocumented kernel
|
|---|
| 88 | structures. Mach, however, does have a very clean interface to exception
|
|---|
| 89 | handing. The current implementation uses Mach's exception handling.
|
|---|
| 90 |
|
|---|
| 91 | Much thanks goes to Andrew Stone, Dietmar Planitzer, Andrew Begel,
|
|---|
| 92 | Jeff Sturm, and Jesse Rosenstock for all their work on the
|
|---|
| 93 | Darwin/OS X port.
|
|---|
| 94 |
|
|---|
| 95 | -Brian Alliet
|
|---|
| 96 | brian@brianweb.net
|
|---|
| 97 |
|
|---|
| 98 |
|
|---|
| 99 | Older Information (Most of this no longer applies to the current code)
|
|---|
| 100 | ======================================================================
|
|---|
| 101 |
|
|---|
| 102 | While the GC should work on MacOS X Server, MacOS X and Darwin, I only tested
|
|---|
| 103 | it on MacOS X Server.
|
|---|
| 104 | I've added a PPC assembly version of GC_push_regs(), thus the setjmp() hack is
|
|---|
| 105 | no longer necessary. Incremental collection is supported via mprotect/signal.
|
|---|
| 106 | The current solution isn't really optimal because the signal handler must decode
|
|---|
| 107 | the faulting PPC machine instruction in order to find the correct heap address.
|
|---|
| 108 | Further, it must poke around in the register state which the kernel saved away
|
|---|
| 109 | in some obscure register state structure before it calls the signal handler -
|
|---|
| 110 | needless to say the layout of this structure is no where documented.
|
|---|
| 111 | Threads and dynamic libraries are not yet supported (adding dynamic library
|
|---|
| 112 | support via the low-level dyld API shouldn't be that hard).
|
|---|
| 113 |
|
|---|
| 114 | The original MacOS X port was brought to you by Andrew Stone.
|
|---|
| 115 |
|
|---|
| 116 |
|
|---|
| 117 | June, 1 2000
|
|---|
| 118 |
|
|---|
| 119 | Dietmar Planitzer
|
|---|
| 120 | dave.pl@ping.at
|
|---|
| 121 |
|
|---|
| 122 | Note from Andrew Begel:
|
|---|
| 123 |
|
|---|
| 124 | One more fix to enable gc.a to link successfully into a shared library for
|
|---|
| 125 | MacOS X. You have to add -fno-common to the CFLAGS in the Makefile. MacOSX
|
|---|
| 126 | disallows common symbols in anything that eventually finds its way into a
|
|---|
| 127 | shared library. (I don't completely understand why, but -fno-common seems to
|
|---|
| 128 | work and doesn't mess up the garbage collector's functionality).
|
|---|
| 129 |
|
|---|
| 130 | Feb 26, 2003
|
|---|
| 131 |
|
|---|
| 132 | Jeff Sturm and Jesse Rosenstock provided a patch that adds thread support.
|
|---|
| 133 | GC_MACOSX_THREADS should be defined in the build and in clients. Real
|
|---|
| 134 | dynamic library support is still missing, i.e. dynamic library data segments
|
|---|
| 135 | are still not scanned. Code that stores pointers to the garbage collected
|
|---|
| 136 | heap in statically allocated variables should not reside in a dynamic
|
|---|
| 137 | library. This still doesn't appear to be 100% reliable.
|
|---|
| 138 |
|
|---|
| 139 | Mar 10, 2003
|
|---|
| 140 | Brian Alliet contributed dynamic library support for MacOSX. It could also
|
|---|
| 141 | use more testing.
|
|---|