darling-libobjc2/GCKit/DESIGN
theraven 5b1911b4f4 Initial commit of GCKit (moved from Étoilé and the missing 90% mostly implemented). GCKit implements cycle detection on the heap and tracing on the stack and designated heap regions, with support for weak references. It is designed for implementing OS X 10.5-compatible GC semantics.
Although GCKit is mostly finished, it is still not well tested.  It contains bugs, and possibly dragons.  Do not use it.  If you disregard this advice, do not file any bug reports.  If you disregard this instruction, then I will point and laugh at you.
2010-02-02 23:36:38 +00:00

127 lines
5.1 KiB
Plaintext

GCKit
=====
GCKit is a garbage collection kit designed for Objective-C. It is a hybrid collector, using a combination of reference counting, cycle detection, and tracing. The design goals are:
- Easy interoperability with non-GC code using retain/release semantics.
- Easy interoperability with code designed for Apple's GC implementation.
- Support for assisted reference counting with no compiler support.
- Support for automatic garbage collection with compiler support.
- Low overheads.
- Performance in memory-constrained conditions, without causing undue swapping
Memory Types
------------
There are three types of memory in GCKit's model:
- Objects
- Traced regions
- Untraced regions
Objects have a fixed layout and may contain strong, weak, and traced pointers.
Traced regions include the stack, and any regions explicitly designated for
tracing. Stacks are traced synchronously, from the thread that owns them,
while other regions are not.
Untraced regions are opaque to GCKit. They may contain pointers to GC'd
objects only if the pointers are manually reference counted using GCRetain()
and GCRelease().
Object Types
------------
GCKit will allocate two kind of memory. Objective-C objects, and buffers.
Reference Types
---------------
There are four kinds of reference (pointer) in GCKit's memory model:
- Strong.
- Zeroing weak.
- Traced.
- Invisible.
Strong references use reference counting. When an object is strongly assigned
to a pointer, its reference count is incremented and the reference count of the
old object is decremented. Objects will never be deleted as long as they have
a strong reference count greater than 0 and their references can not all be
accounted for by cycles.
Zeroing weak references are also reference counted, however they do not prevent
an object from being finalized. Zeroing weak references follow similar
assignment semantics to strong references. When an object is only referenced
by zeroing weak references, it will be finalized, but not freed. Subsequent
reads of zeroing weak pointers to the object will decrement its reference count
and it will be freed once this reaches 0.
Traced pointers do not perform any reference counting. All pointers on the
stack are traced, as are pointers in memory buffers explicitly allocated for
tracing. Objects with a reference count of 0 will not be freed until tracing
these regions determines that there are no unseen references to them.
Copying traced pointers between stacks directly is not supported. If a thread
somehow gets a reference to another thread's stack and copies a pointer then
the compiler will not generate a write barrier. This means that, if the two
threads' stacks are not traced in the right order relative to each other (50%
chance) and there are no locatable heap references to the object then it may be
freed.
Invisible pointers are outside regions that the garbage collector knows about.
Objects pointed to by these may be deleted if their reference count hits 0.
Interior pointers are not supported. A pointer to the start of an object or
managed buffer must be maintained
Object Deletion
---------------
Objects marked as using CoreFoundation semantics are deleted as soon as their
reference counts hit 0.
All other objects are marked as potential garbage once their reference count
drops to a value that is equal to the number of references that the cycle
detector can find. If A and B both hold strong references to each other, then
they are marked as potential garbage once their reference count hits 1.
Interfaces
----------
Writing pointers into traced heap memory requires a write barrier. The
objc_assign_strongCast function generates this barrier for a single write
(another function, as yet unwritten, will generate it for multiple writes).
Assignments to instance variables or globals must increment the strong
reference count of the new value and decrement the value of the old one. The
objc_assignIvar() and objc_assignGlobal() functions perform this for you.
If you are storing pointers in memory that is not managed by GCKit then you
must call the CGRetain() function on the pointer to prevent it from being freed
and the GCRelease() function when you are finished with it.
Degenerate Cases
----------------
Objects using the Core Foundation or OpenStep models may set a flag indicating
that they do not contain cycles (or, more accurately, that the programmer takes
responsibility for freeing cycles). In this case, GCKit will trace the stack,
catching bugs where you might have used -release instead of -autorelease, but
aside from that will not provide any benefits.
Objects may also be marked as having CF semantics. In this case, they will be
checked for cycles (unless explicitly marked as acyclic), but will be finalised
when their reference count hits zero and subsequently destroyed when their weak
reference count hits zero.
Finally, you can use traced memory for everything. Don't do this. GCKit is
designed to be efficient when only a relatively small proportion of allocated
memory needs to be traced.
Outstanding Bugs
----------------
Lots. Seriously, don't use GCKit yet. Cycles in traced memory are not yet
detected. Lots of GCKit is completely untested.