]>
Commit | Line | Data |
---|---|---|
54f28c21 BM |
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 | ||
aa7a966b BM |
14 | Darwin/MacOSX Support - December 16, 2003 |
15 | ========================================= | |
6991c6c9 JS |
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> | |
aa7a966b | 31 | extern "C" void my_library_init() { GC_init(); } |
6991c6c9 JS |
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 | ||
aa7a966b BM |
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 | ||
6991c6c9 JS |
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 | ||
aa7a966b | 64 | Thread support is implemented in terms of mach thread_suspend and |
6991c6c9 JS |
65 | thread_resume calls. These provide a very clean interface to thread |
66 | suspension. This implementation doesn't rely on pthread_kill so the | |
aa7a966b BM |
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. | |
6991c6c9 JS |
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. |