Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master

Fix the mask for the top part of the dtable on MIPS.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/libobjc2/trunk@37491 72102866-910b-0410-8b05-ffd578937521
latest commit 43e81c1bf9
theraven authored December 23, 2013
Octocat-spinner-32 CMake Added a test that the C++ runtime is really useable (i.e. exports the… June 21, 2013
Octocat-spinner-32 Test Add test for associated objects. December 13, 2013
Octocat-spinner-32 objc Added support for tracing message sends to the runtime. June 29, 2013
Octocat-spinner-32 opts Fix the build with LLVM 3.3 and enable building the optimisation pass… May 16, 2013
Octocat-spinner-32 ANNOUNCE Added support for tracing message sends to the runtime. June 29, 2013
Octocat-spinner-32 ANNOUNCE.1.0 Added 1.1 announcement. Committed some work-in-progress clang-specifi… January 10, 2011
Octocat-spinner-32 ANNOUNCE.1.1 Added 1.1 announcement. Committed some work-in-progress clang-specifi… January 10, 2011
Octocat-spinner-32 ANNOUNCE.1.2 Added 1.2 release announcement. February 21, 2011
Octocat-spinner-32 ANNOUNCE.1.3 Added note about aliases to release announcement. April 14, 2011
Octocat-spinner-32 ANNOUNCE.1.4 Created 1.4 release announcement. May 06, 2011
Octocat-spinner-32 ANNOUNCE.1.5 s/fifth/sixth July 23, 2011
Octocat-spinner-32 ANNOUNCE.1.6 1.6 release announcement. November 23, 2011
Octocat-spinner-32 ANNOUNCE.1.6.1 Archive 1.6.1 release announcement. September 04, 2012
Octocat-spinner-32 ANNOUNCE.1.7 Fixed svn URL for 1.7 release announcement. May 16, 2013
Octocat-spinner-32 API Added property_getName(). Added non-portable API documentation. September 21, 2010
Octocat-spinner-32 CMakeLists.txt Only emit section directives on ELF platforms. December 13, 2013
Octocat-spinner-32 COPYING Removed last bits of legacy code from libobjc2. Added new exception h… June 29, 2010
Octocat-spinner-32 GNUmakefile Restored r35794 changes (that were removed in r35893) but applied the… January 11, 2013
Octocat-spinner-32 INSTALL add assembler flags needed for cmake July 10, 2013
Octocat-spinner-32 Makefile Add deprecation warning to the Makefile build. May 16, 2013
Octocat-spinner-32 NSBlocks.m Blocks cleanups. August 07, 2011
Octocat-spinner-32 Protocol2.m Accidentally deleted class declaration for Protocol2. Add it back. July 11, 2011
Octocat-spinner-32 README Updated README to give some more information about ARC. July 06, 2011
Octocat-spinner-32 abi_version.c Small object + ARC tweaks. July 26, 2011
Octocat-spinner-32 alias.h Implement a hook that allows the compiler to register the aliases use… March 25, 2011
Octocat-spinner-32 alias_table.c Remove indirection from alias table. June 29, 2011
Octocat-spinner-32 arc.m Fix some bugs in protocol property introspection and remove a redunda… July 17, 2013
Octocat-spinner-32 associate.m Don't crash when trying to synchronize on nil (but don't do anything … July 18, 2013
Octocat-spinner-32 block_to_imp.c Expose asprintf() with glibc. May 28, 2013
Octocat-spinner-32 block_trampolines.S Only emit section directives on ELF platforms. December 13, 2013
Octocat-spinner-32 blocks_runtime.h Add objc/blocks_private.h header to expose some internals of the bloc… March 11, 2012
Octocat-spinner-32 blocks_runtime.m Fix double-free when making C++ objects __block April 03, 2012
Octocat-spinner-32 buffer.h Fix off-by-one error in buffer.h July 04, 2011
Octocat-spinner-32 caps.c Added support for tracing message sends to the runtime. June 29, 2013
Octocat-spinner-32 category.h Finished rewriting the loader. It's now cleanly separated into logica… June 02, 2010
Octocat-spinner-32 category_loader.c Remove FIXME that was fixed in last commit. April 19, 2011
Octocat-spinner-32 class.h Fix typo in class header. November 09, 2011
Octocat-spinner-32 class_table.c Cleaner version of the last fix. January 14, 2013
Octocat-spinner-32 cmake_uninstall.cmake.in Add uninstall target to CMake. December 22, 2012
Octocat-spinner-32 common.S Only use .type on ELF targets. July 09, 2013
Octocat-spinner-32 constant_string.h Stop treating NSObject as magic and do what OS X does with regard to … February 23, 2011
Octocat-spinner-32 dtable.c Fix missing unlock. December 13, 2013
Octocat-spinner-32 dtable.h Dtable cleanup cleanups. April 19, 2011
Octocat-spinner-32 dwarf_eh.h Implemented the new exception ABI, and a load of tests for it. This i… January 12, 2013
Octocat-spinner-32 eh_personality.c Implemented the new exception ABI, and a load of tests for it. This i… January 12, 2013
Octocat-spinner-32 encoding2.c fix function to get type qualifiers March 09, 2013
Octocat-spinner-32 gc_boehm.c Fix malloc() / free() imbalance. July 31, 2011
Octocat-spinner-32 gc_none.c Fix the build with GC enabled, export the GC symbols in all build con… August 14, 2013
Octocat-spinner-32 gc_ops.h Fix malloc() / free() imbalance. July 31, 2011
Octocat-spinner-32 hash_table.c If we're linking against Boehm GC, then we may as well allow it to co… May 27, 2011
Octocat-spinner-32 hash_table.h Move the selector table to being protected by a mutex for reads so th… January 14, 2013
Octocat-spinner-32 hooks.c Added support for tracing message sends to the runtime. June 29, 2013
Octocat-spinner-32 ivar.c Remove ivar offset fudging code, as it appears to break a lot of things. July 21, 2013
Octocat-spinner-32 ivar.h Change [1] to [] for variable length structure elements (C99 - silenc… July 12, 2011
Octocat-spinner-32 legacy_malloc.c libobjc2: tweaks to build on Windows September 03, 2010
Octocat-spinner-32 loader.c When linking libdispatch, register to create / destroy autorelease po… April 15, 2013
Octocat-spinner-32 loader.h First pass at implementing Apple-compatible GC using Boehm. Still nee… May 22, 2011
Octocat-spinner-32 lock.h Add explicit cast for pthread lock initialiser. May 28, 2013
Octocat-spinner-32 method_list.h Change [1] to [] for variable length structure elements (C99 - silenc… July 12, 2011
Octocat-spinner-32 module.h Change [1] to [] for variable length structure elements (C99 - silenc… July 12, 2011
Octocat-spinner-32 mutation.m Fix enumeration mutation function prototype to match what clang expec… February 12, 2011
Octocat-spinner-32 nsobject.h Added support for associative references. Modified sync code to use t… April 15, 2011
Octocat-spinner-32 objc_msgSend.S Only emit section directives on ELF platforms. December 13, 2013
Octocat-spinner-32 objc_msgSend.arm.S Fixes to ARM objc_msgSend(). December 13, 2013
Octocat-spinner-32 objc_msgSend.mips.S Fix the mask for the top part of the dtable on MIPS. December 23, 2013
Octocat-spinner-32 objc_msgSend.x86-32.S libobjc2: some changes needed to build on OS X. CDECL macro to prefix… July 08, 2013
Octocat-spinner-32 objc_msgSend.x86-64.S libobjc2: some changes needed to build on OS X. CDECL macro to prefix… July 08, 2013
Octocat-spinner-32 objcxx_eh.cc Fix the build with GC enabled, export the GC symbols in all build con… August 14, 2013
Octocat-spinner-32 objcxx_eh.h Implemented the new exception ABI, and a load of tests for it. This i… January 12, 2013
Octocat-spinner-32 pool.h Print some memory usage statistics on exit if LIBOBJC_MEMORY_PROFILE is January 15, 2013
Octocat-spinner-32 properties.h Add header changes too... February 28, 2013
Octocat-spinner-32 properties.m Fixed a great many property introspection bugs and added test case. February 28, 2013
Octocat-spinner-32 protocol.c Fix protocol_copyProtocolList() to return the correct count value. December 20, 2013
Octocat-spinner-32 protocol.h Change [1] to [] for variable length structure elements (C99 - silenc… July 12, 2011
Octocat-spinner-32 runtime.c Handle the case where the alignment of a new ivar is 0. June 21, 2013
Octocat-spinner-32 sarray2.c Print some memory usage statistics on exit if LIBOBJC_MEMORY_PROFILE is January 15, 2013
Octocat-spinner-32 sarray2.h Print some memory usage statistics on exit if LIBOBJC_MEMORY_PROFILE is January 15, 2013
Octocat-spinner-32 selector.h Tidy up low memory profile to use slots directly. April 28, 2011
Octocat-spinner-32 selector_table.c Print some memory usage statistics on exit if LIBOBJC_MEMORY_PROFILE is January 15, 2013
Octocat-spinner-32 sendmsg2.c Add better handling of messages returning floating point values sent … June 09, 2012
Octocat-spinner-32 slot_pool.h Tidy up low memory profile to use slots directly. April 28, 2011
Octocat-spinner-32 spinlock.h Added helper function for C++ non-POD type atomic properties. December 17, 2012
Octocat-spinner-32 statics_loader.c Add visibility attributes on all internal functions so that we aren't… April 14, 2011
Octocat-spinner-32 string_hash.h Implemented support for __weak with ARC. June 29, 2011
Octocat-spinner-32 toydispatch.c Move toydispatch into libobjc2. October 26, 2010
Octocat-spinner-32 type_encoding_cases.h Fix type encoding of blocks. August 22, 2011
Octocat-spinner-32 unistd.h Added a custom unistd.h to work around glibc vs Clang conflict on __b… February 16, 2012
Octocat-spinner-32 unwind-arm.h Add _Unwind_Action to unwind-arm.h. This wasn't originally needed, bu… March 09, 2013
Octocat-spinner-32 unwind-itanium.h Implement ARM EH support, fix objc_msgSend() to work on ARM. November 09, 2011
Octocat-spinner-32 unwind.h Implement ARM EH support, fix objc_msgSend() to work on ARM. November 09, 2011
Octocat-spinner-32 visibility.h First pass at implementing Apple-compatible GC using Boehm. Still nee… May 22, 2011
README
GNUstep Objective-C Runtime
===========================

The GNUstep Objective-C runtime is designed as a drop-in replacement for the
GCC runtime.  It supports both a legacy and a modern ABI, allowing code
compiled with old versions of GCC to be supported without requiring
recompilation.  The modern ABI adds the following features:

- Non-fragile instance variables.
- Protocol uniquing.
- Object planes support.
- Declared property introspection.

Both ABIs support the following feature above and beyond the GCC runtime:

- The modern Objective-C runtime APIs, introduced with OS X 10.5.
- Blocks (closures).
- Low memory profile for platforms where memory usage is more important than
  speed.
- Synthesised property accessors.
- Efficient support for @synchronized()
- Type-dependent dispatch, eliminating stack corruption from mismatched
  selectors.
- Support for the associated reference APIs introduced with Mac OS X 10.6.
- Support for the automatic reference counting APIs introduced with Mac OS X
  10.7

History
-------

Early work on the GNUstep runtime combined code from the GCC Objective-C
runtime, the Étoilé Objective-C runtime, Remy Demarest's blocks runtime for OS
X 10.5, and the Étoilé Objective-C 2 API compatibility framework.  All of these
aside from the GCC runtime were MIT licensed, although the GPL'd code present
in the GCC runtime meant that the combined work had to remain under the GPL.

Since then, all of the GCC code has been removed, leaving the remaining files
all MIT licensed, and allowing the entire work to be MIT licensed.  

The exception handling code uses a header file implementing the generic parts
of the Itanium EH ABI.  This file comes from PathScale's libcxxrt.  PathScale
kindly allowed it to be MIT licensed for inclusion here.

Non-Fragile Instance Variables
------------------------------

When a class is compiled to support non-fragile instance variables, the
instance_size field in the class is set to 0 - the size of the instance
variables declared on that class (excluding those inherited.  For example, an
NSObject subclass declaring an int ivar would have its instance_size set to 0 -
sizeof(int)).  The offsets of each instance variable in the class's ivar_list
field are then set to the offset from the start of the superclass's ivars.

When the class is loaded, the runtime library uses the size of the superclass
to calculate the correct size for this new class and the correct offsets.  Each
instance variable should have two other variables exported as global symbols.
Consider the following class:

@interface NewClass : SuperClass {
	int anIvar;
}
@end

This would have its instance_size initialized to 0-sizeof(int), and anIvar's
offset initialized to 0.  It should also export the following two symbols:

int __objc_ivar_offset_value_NewClass.anIvar;
int *__objc_ivar_offset_NewClass.anIvar;

The latter should point to the former or to the ivar_offset field in the ivar
metadata.  The former should be pointed to by the only element in the
ivar_offsets array in the class structure.  

In other compilation units referring to this ivar, the latter symbol should be
exported as a weak symbol pointing to an internal symbol containing the
compiler's guess at the ivar offset.  The ivar will then work as a fragile ivar
when NewClass is compiled with the old ABI.  If NewClass is compiled with the
new ABI, then the linker will replace the weak symbol with the version in the
class's compilation unit and references which use this offset will function
correctly.

If the compiler can guarantee that NewClass is compiled with the new ABI, for
example if it is declared in the same compilation unit, by finding the symbol
during a link-time optimization phase, or as a result of a command-line
argument, then it may use the __objc_ivar_offset_value_NewClass.anIvar symbol
as the ivar offset.  This eliminates the need for one load for every ivar
access.  

Protocols
---------

The runtime now provides a __ObjC_Protocol_Holder_Ugly_Hack class.  All
protocols that are referenced but not defined should be registered as
categories on this class.  This ensures that every protocol is registered with
the runtime.  

In the near future, the runtime will ensure that protocols can be looked up by
name at run time and that empty protocol definitions have their fields updated
to match the defined version.

Protocols have been extended to provide space for introspection on properties
and optional methods.  These fields only exist on protocols compiled with a
compiler that supports Objective-C 2.  To differentiate the two, the isa
pointer for new protocols will be set to the Protocol2 class.

Blocks
------

The GNUstep runtime provides the run time support required for Apple's blocks
(closures) extension to C.  This follows the same ABI as OS X 10.6.

Fast Proxies and Cacheable Lookups
----------------------------------

The new runtime provides two mechanisms for faster lookup.  The older
Vobjc_msg_lookup() function, which returns an IMP, is still supported, however
it is no longer recommended.  The new lookup functions is:

Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender)

The receiver is passed by pointer, and so may be modified during the lookup
process.  The runtime itself will never modify the receiver.  The following
hook is provided to allow fast proxy support:

id (*objc_proxy_lookup)(id receiver, SEL op);

This function takes an object and selector as arguments and returns a new
objects.  The lookup will then be re-run and the final message should be sent to
the new object.

The returned Slot_t from the new lookup function is a pointer to a structure
which contains both an IMP and a version (among other things).  The version is
incremented every time the method is overridden, allowing this to be cached by
the caller.  User code wishing to perform IMP caching may use the old mechanism
if it can guarantee that the IMP will not change between calls, or the newer
mechanism.  Note that a modern compiler should insert caching automatically,
ideally with the aid of run-time profiling results.  To support this, a new hook
has been added:

Slot_t objc_msg_forward3(id receiver, SEL op);

This is identical to objc_msg_forward2(), but returns a pointer to a slot,
instead of an IMP.  The slot should have its version set to 0, to prevent
caching.

Object Planes
-------------

Object planes provide interception points for messages between groups of
related objects.  They can be thought of as similar to processes, with mediated
inter-plane communication.  A typical use-case for an object plane is to
automatically queue messages sent to a thread, or to record every message sent
to model objects.  Planes can dramatically reduce the number of proxy objects
required for this kind of activity.

The GNUstep runtime adds a flag to class objects indicating that their
instances are present in the global plane.  All constant strings, protocols,
and classes are in the global plane, and may therefore be sent and may receive
messages bypassing the normal plane interception mechanism.  

The runtime library does not provide direct support for planes, it merely
provides the core components required to implement support for planes in
another framework.  Two objects are regarded as being in the same plane when
they words immediately before their isa pointers are the same.  In this case,
the runtime's usual dispatch mechanisms will be used.  In all other cases, the
runtime will delegate message lookup to another library via the following hook:

Slot_t (*objc_plane_lookup)(id *receiver, SEL op, id sender);

From the perspective of the runtime, the plane identifier is opaque.  In
GNUstep, it is a pointer to an NSZone structure.

Threading
---------

The threading APIs from GCC libobjc are not present in this runtime.  They were
buggy, badly supported, inadequately tested, and irrelevant now that there are
well tested thread abstraction layers, such as the POSIX thread APIs and the
C1x thread functions.  The library always runs in thread-safe mode.  The same
functions for locking the runtime mutex are still supported, but their use any
mutex not exported by the runtime library is explicitly not supported.  The
(private) lock.h header is used to abstract the details of different threading
systems sufficiently for the runtime.  This provides mechanisms for locking,
unlocking, creating, and destroying mutex objects.  

Type-Dependent Dispatch
-----------------------

Traditionally, Objective-C method lookup is done entirely on the name of the
method.  This is problematic when the sender and receiver of the method
disagree on the types of a method.  

For example, consider a trivial case where you have two methods with the same
name, one taking an integer, the other taking a floating point value.  Both
will pass their argument in a register on most platforms, but not the same
register.  If the sender thinks it is calling one, but is really calling the
other, then the receiver will look in the wrong register and use a nonsense
value.  The compiler will often not warn about this.

This is a relatively benign example, but if the mismatch is between methods
taking or returning a structure and those only using scalar arguments and
return then the call frame layout will be so different that the result will be
stack corruption, possibly leading to security holes.

If you compile the GNUstep runtime with type-dependent dispatch enabled, then
sending a message with a typed selector will only ever invoke a method with the
same types.  Sending a message with an untyped selector will invoke any method
with a matching name, although the slot returned from the lookup function will
contain the types, allowing the caller to check them and construct a valid call
frame, if required.

If a lookup with a typed selector matches a method with the wrong types, the
runtime will call a handler.  This handler, by default, prints a helpful
message and exits.  LanguageKit provides an alternative version which
dynamically generates a new method performing the required boxing and calling
the original.

Exception ABI Changes
---------------------

The non-fragile ABI makes a small change to the exception structure.  The old
GCC ABI was very poorly designed.  It attempted to do things in a clever way,
avoiding the need to call functions on entering and exiting catch blocks, but
in doing so completely broke support for throwing foreign (e.g. C++) exceptions
through Objective-C stack frames containing an @finally or @catch(id) block.
It also could not differentiate between @catch(id) (catch any object type) and
@catch(...) (catch any exception and discard it).

The new ABI makes a small number of changes.  Most importantly, @catch(id) is
now indicated by using the string "@id" as the type ID, in the same way that
"Foo" is used for @catch(Foo*).  Catchalls remain identified by a NULL pointer
in this field, as with the GCC ABI.  The runtime will still deliver the
exception object to catchalls, for interoperability with old code and with the
old ABI, but this comes with all of the same problems that the old ABI had
(i.e. code using this ABI will break in exciting and spectacular ways when
mixed with C++).

The runtime provides a hook, _objc_class_for_boxing_foreign_exception(), which
takes an exception class (64-bit integer value) as an argument, and returns a
class for boxing exceptions using this ABI.  The returned class must implement
a +exceptionWithForeignException: method, taking a pointer to the ABI-defined
generic exception structure as the argument.  It should also implement a
-rethrow method, used for rethrowing the exception.  If this is omitted, then
the boxed version of the exception, rather than the original, will propagate
out from @finally blocks.

If a catch block exists that handles this class, then it will box foreign
exceptions and allow them to propagate through any @finally directives.  Boxed
exceptions will only match explicit catch statements.  To fully understand the
semantics, we'll take a look at some examples.  These all use GNUstep's
`CXXException` class, which boxes C++ exceptions, and this simple C++ function:

	extern "C" void throwcxx()
	{
		throw 1;
	}

This exception will be caught, boxed, and then silently discarded by a catchall:

	@try
	{
		throwcxx();
	}
	@catch(...)
	{
		// This will be reached, then the exception propagation stops.
	}

If an id catch block is encountered, it will be ignored, but @finally blocks
will still be called:

	@try
	{
		throwcxx();
	}
	@catch(id anyObject)
	{
		// Code here is not reached.
	}
	@finally
	{
		// This will be reached, then the exception propagation continues.
	}

The `CXXException` class is a subclass of `NSObject`, but catch statements for
the superclass will not be hit:

	@try
	{
		throwcxx();
	}
	@catch(NSObject *anyObject)
	{
		// Code here is not reached.
	}
	@catch(CXXException *boxedForeign)
	{
		// Code here is reached.
	}

As of version 1.3, the runtime also provides a unified exception model for
Objective-C++.  This allows C++ `catch` statements and Objective-C `@catch`
statements to catch Objective-C objects thrown with `@throw` or `throw`.

This required some small changes to the ABI.  Both `@try` and `try` must use
the same personality function in Objective-C++ code, because otherwise things
like nested blocks are not possible.  The unwind library must be able to map
from any instruction pointer value to a single personality function, and
without a unified personality function, it would not be able to in code like
this:

	@try
	{
		try
		{
			// What personality function should be used when unwinding from
			// here?
			objc_exception_throw(@"foo");
		}
		catch (int i) {}
	}
	catch (id foo) {}

If there is a single personality function, there must be a single format for
language-specific data.  The current C++ format is more expressive than the
Objective-C format, so we used it directly, with one extension.  C++ landing
pads are identified by a `std::type_info` subclass in the type info tables for
exception unwinding.  We provide two subclasses of this: 

	gnustep::libobjc::__objc_id_type_info;
	gnustep::libobjc::__objc_class_type_info;

The first is used for identifying `id`-typed throws and catches.  The second is
for identifying Objective-C classes.  All `id` throws use the singleton
instance of the first class, exported as `__objc_id_type_info` (with C
linkage).  Type info for classes should generate an instance of the second
class, with the name `__objc_eh_typeinfo_Foo` where `Foo` is the name of the
class (e.g. `NSObject` should generate `__objc_eh_typeinfo_NSObject`).  The
name field should be set to the name of the class, via a global variable named
`__objc_eh_typename_Foo`.  Both should have link-once ODR linkage, so that the
linker will ensure that they are unique and pointer comparison can be used to
test for equality (required by the C++ personality function).

In Objective-C++ code, the personality function is:

	__gnustep_objcxx_personality_v0()

This is a very thin wrapper around the C++ personality function.  If it is
called with an exception coming from Objective-C code, then it wraps it in a
__cxa_exception structure (defined by the C++ ABI spec).  For any other
exception type (including C++ exceptions), it passes it directly to the C++
personality function.

The Objective-C personality function was also modified slightly so that any
incoming C++ exception that was has type info indicating that it's an
Objective-C type is treated as an Objective-C object, for the purpose of
exception delivery.

Low Memory Profile
------------------

The dispatch tables for each class, in spite of using a more space-efficient
sparse array implementation than GCC libobjc, can still use quite a lot of
memory.  The NeXT runtime avoided this problem by not providing dispatch tables
at all.  Instead, it did a linear search of the method lists, caching a few
results.  Although this is O(n), it performed reasonably well.  Most message
sends are to a small number of methods.  For example, an NSMutableDictionary is
most often sent -objectForKey: and -setObject:forKey:.  If these two methods
are in the cache, then the O(n) algorithm is almost never used.

The GNUstep runtime's low memory profile stores the slots in a sorted array.
This means that the worst case performance is O(log(n)) in terms of the number
of methods, as the uncached lookup proceeds using a binary search.

If you compile the GNUstep runtime with the low memory profile, it uses a
similar strategy.  The caches use the same slot-caching mechanism described
above and can be combined with caching at the call site.  The runtime will not
create dispatch tables, which can save a few MB of RAM in projects with a lot
of classes, but can make message sending a lot slower in the worst case.

To enable the low memory profile, add low_memory=yes to your make command line.

Objective-C 2 Features
----------------------

The runtime now provides implementations of the functions required for the
@synchronized directive, for property accessors, and for fast enumeration.  The
public runtime function interfaces now match those of OS X.

Garbage Collection
------------------

As of version 1.5, the runtime support Apple-compatible garbage collection
semantics.  The `objc/objc-auto.h` header describes the interfaces to garbage
collection.  This contains some extensions to Apple's API, required to
implement parts of Cocoa that rely on private interfaces between Cocoa, Apple
libobjc, and Autozone.

Garbage collection is implemented using the Boehm-Demers-Weiser garbage
collector.  If built with boehm_gc=no, this support will not be compiled into
the runtime.  When built with GC support, the runtime will use garbage
collection for its internal tables, irrespective of whether linked Objective-C
code is using it.

Zeroing weak references are implemented by storing the bit-flipped version of
the value (making it invisible to the collector) at the designated address.
The read barrier reads the value while holding the collector lock.  This
ensures that reads of weak variables never point to finalised objects.

The runtime uses the objc_assign_global() write barrier to add static roots.
Currently, GNUstep crashes if the collector relies on every write of a pointer
to a static location being through this write barrier, so this requirement is
relaxed.  It will be enabled at some point in the future.

Several environment variables can be used for debugging programs

- LIBOBJC_DUMP_GC_STATUS_ON_EXIT.  I this is set, then the program will dump
  information about the garbage collector when it exits.
- LIBOBJC_DUMP_GC_STATUS_ON_SIGNAL.  This should be set to a signal number.
  The program will dump GC statistics when it receives the corresponding signal
  (SIGUSR2 if this environment variable is set to something that is not a
  number).
- LIBOBJC_LOG_ALLOCATIONS.  This may be set to the name of a file.  The runtime
  will dump a stack trace on every allocation and finalisation to the named
  file.  This can be used to implement tools like Apple's malloc_history().
  Note: Enabling this causes a significant speed decrease.
- LIBOBJC_CANARIES.  If this environment variable is set, then every allocation
  of garbage-collected memory will have a canary value appended to it.  On
  finalisation, the runtime will check that this value has not been modified,
  and abort if it has.  This can help to catch heap buffer overflows.  It is
  most useful when debugging.

Automatic Reference Counting
----------------------------

As of version 1.5, the runtime provides support for automatic reference
counting (ARC).  This uses the same runtime interface as documented by the ABI
supplement here:

http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime

The runtime implements the following optimisations:

- Classes that have ARC-compliant retain, release, and autorelease methods will
  never see them called from ARC code.  Instead, equivalent code will be run
  directly.
- If an object is autoreleased, returned, and retained, it is just stored in
  thread-local storage temporarily, not actually autoreleased.
- Moving weak references skips the retain / release step.

ARC requires the ability to interoperate perfectly with manual retain / release
code, including the ability for non-ARC code to implement custom reference
counting behaviour.  If an object implements -_ARCCompliantRetainRelease, then
it is advertising that its retain, release, and autorelease implementations are
ARC-compatible.  These methods may be called explicitly in non-ARC code, but
will not be called from ARC.

ARC moves autorelease pools into the runtime.  If NSAutoreleasePool exists and
does not implement a -_ARCCompatibleAutoreleasePool method, then it will be
used directly.  If it does not exist, ARC will implement its own autorelease
pools.  If it exists and does implement -_ARCCompatibleAutoreleasePool then it
must call objc_autoreleasePoolPush() and objc_autoreleasePoolPop() to manage
autoreleased object storage and call objc_autorelease() in its -addObject:
method.
Something went wrong with that request. Please try again.