1 |
721 |
jeremybenn |
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
|
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.
|