| 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. | 
|---|