diff options
Diffstat (limited to 'graphics/asymptote/gc/doc/gcinterface.md')
-rw-r--r-- | graphics/asymptote/gc/doc/gcinterface.md | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/graphics/asymptote/gc/doc/gcinterface.md b/graphics/asymptote/gc/doc/gcinterface.md new file mode 100644 index 0000000000..8247ba2264 --- /dev/null +++ b/graphics/asymptote/gc/doc/gcinterface.md @@ -0,0 +1,216 @@ +# C/C++ Interface + +On many platforms, a single-threaded garbage collector library can be built +to act as a plug-in `malloc` replacement. (Build it with +`-DREDIRECT_MALLOC=GC_malloc -DIGNORE_FREE`.) This is often the best way to +deal with third-party libraries which leak or prematurely free objects. +`-DREDIRECT_MALLOC=GC_malloc` is intended primarily as an easy way to adapt +old code, not for new development. + +New code should use the interface discussed below. + +Code must be linked against the GC library. On most UNIX platforms, depending +on how the collector is built, this will be `gc.a` or `libgc.{a,so}`. + +The following describes the standard C interface to the garbage collector. +It is not a complete definition of the interface. It describes only the most +commonly used functionality, approximately in decreasing order of frequency +of use. This somewhat duplicates the information in `gc.man` file. The full +interface is described in `gc.h` file. + +Clients should include `gc.h` (i.e., not `gc_config_macros.h`, +`gc_pthread_redirects.h`, `gc_version.h`). In the case of multi-threaded code, +`gc.h` should be included after the threads header file, and after defining +`GC_THREADS` macro. The header file `gc.h` must be included in files that use +either GC or threads primitives, since threads primitives will be redefined +to cooperate with the GC on many platforms. + +Thread users should also be aware that on many platforms objects reachable +only from thread-local variables may be prematurely reclaimed. Thus objects +pointed to by thread-local variables should also be pointed to by a globally +visible data area, e.g. thread's stack. (This behavior is viewed as a bug, but +as one that is exceedingly hard to fix without some `libc` hooks.) + +`void * GC_MALLOC(size_t _bytes_)` - Allocates and clears _bytes_ +of storage. Requires (amortized) time proportional to _bytes_. The resulting +object will be automatically deallocated when unreferenced. References from +objects allocated with the system malloc are usually not considered by the +collector. (See `GC_MALLOC_UNCOLLECTABLE`, however. Building the collector +with `-DREDIRECT_MALLOC=GC_malloc_uncollectable` is often a way around this.) +`GC_MALLOC` is a macro which invokes `GC_malloc` by default or, if `GC_DEBUG` +is defined before `gc.h` is included, a debugging version that checks +occasionally for overwrite errors, and the like. + +`void * GC_MALLOC_ATOMIC(size_t _bytes_)` - Allocates _bytes_ +of storage. Requires (amortized) time proportional to _bytes_. The resulting +object will be automatically deallocated when unreferenced. The client +promises that the resulting object will never contain any pointers. The memory +is not cleared. This is the preferred way to allocate strings, floating point +arrays, bitmaps, etc. More precise information about pointer locations can be +communicated to the collector using the interface in `gc_typed.h`. + +`void * GC_MALLOC_UNCOLLECTABLE(size_t _bytes_)` - Identical +to `GC_MALLOC`, except that the resulting object is not automatically +deallocated. Unlike the system-provided `malloc`, the collector does scan the +object for pointers to garbage-collectible memory, even if the block itself +does not appear to be reachable. (Objects allocated in this way are +effectively treated as roots by the collector.) + +`void * GC_REALLOC(void * _old_object_, size_t _new_bytes_)` - Allocates +a new object of the indicated size and copy the old object's content into the +new object. The old object is reused in place if convenient. If the original +object was allocated with `GC_MALLOC_ATOMIC`, the new object is subject to the +same constraints. If it was allocated as an uncollectible object, then the new +object is uncollectible, and the old object (if different) is deallocated. + +`void GC_FREE(void * _object_)` - Explicitly deallocates an _object_. +Typically not useful for small collectible objects. + +`void * GC_MALLOC_IGNORE_OFF_PAGE(size_t _bytes_)` and +`void * GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(size_t _bytes_)` - Analogous +to `GC_MALLOC` and `GC_MALLOC_ATOMIC`, respectively, except that the client +guarantees that as long as the resulting object is of use, a pointer +is maintained to someplace inside the first heap block (hblk) of the object. +This pointer should be declared volatile to avoid interference from compiler +optimizations. (Other nonvolatile pointers to the object may exist as well.) +This is the preferred way to allocate objects that are likely to be +more than 100 KB in size. It greatly reduces the risk that such objects will +be accidentally retained when they are no longer needed. Thus space usage may +be significantly reduced. Another way is `GC_set_all_interior_pointers(0)` +called at program start (this, however, is generally not suitable for C++ code +because of multiple inheritance). + +`void GC_INIT()` - On some platforms, it is necessary to invoke this _from +the main executable_, _not from a dynamic library_, before the initial +invocation of a GC routine. It is recommended that this be done in portable +code, though we try to ensure that it expands to a no-op on as many platforms +as possible. + +`void GC_gcollect(void)` - Explicitly forces a garbage collection. + +`void GC_enable_incremental(void)` - Causes the garbage collector +to perform a small amount of work every few invocations of `GC_MALLOC` or the +like, instead of performing an entire collection at once. This is likely +to increase total running time. It will improve response on a platform that +has suitable support in the garbage collector (Linux and most Unix versions, +Win32 if the collector was suitably built). On many platforms this interacts +poorly with system calls that write to the garbage collected heap. + +`void GC_set_warn_proc(GC_warn_proc)` - Replaces the default procedure +used by the collector to print warnings. The collector may otherwise +write to `stderr`, most commonly because `GC_malloc` was used in a situation +in which `GC_malloc_ignore_off_page` would have been more appropriate. See +`gc.h` for details. + +`void GC_REGISTER_FINALIZER(...)` - Registers a function to be called when +an object becomes inaccessible. This is often useful as a backup method for +releasing system resources (e.g. closing files) when the object referencing +them becomes inaccessible. It is not an acceptable method to perform actions +that must be performed in a timely fashion. See `gc.h` for details of the +interface. See also [here](finalization.md) for a more detailed discussion +of the design. Note that an object may become inaccessible before client code +is done operating on objects referenced by its fields. Suitable +synchronization is usually required. See +[here](http://portal.acm.org/citation.cfm?doid=604131.604153) or +[here](http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html) for details. + +If you are concerned with multiprocessor performance and scalability, you +should consider enabling and using thread local allocation. + +If your platform supports it, you should also build the collector with +parallel marking support (`-DPARALLEL_MARK`); configure has it on by default. + +If the collector is used in an environment in which pointer location +information for heap objects is easily available, this can be passed on to the +collector using the interfaces in either `gc_typed.h` or `gc_gcj.h`. + +The collector distribution also includes a **string package** that takes +advantage of the collector. For details see `cord.h` file. + +## C++ Interface + +The C++ interface is implemented as a thin layer on the C interface. +Unfortunately, this thin layer appears to be very sensitive to variations +in C++ implementations, particularly since it tries to replace the global +`::new` operator, something that appears to not be well-standardized. Your +platform may need minor adjustments in this layer (`gc_badalc.cc`, +`gc_cpp.cc`, `gc_cpp.h`, and possibly `gc_allocator.h`). Such changes do not +require understanding of collector internals, though they may require a good +understanding of your platform. (Patches enhancing portability are welcome. +But it is easy to break one platform by fixing another.) + +Usage of the collector from C++ is also complicated by the fact that there are +many _standard_ ways to allocate memory in C++. The default `::new` operator, +default `malloc`, and default STL allocators allocate memory that is not +garbage collected, and is not normally _traced_ by the collector. This means +that any pointers in memory allocated by these default allocators will not be +seen by the collector. Garbage-collectible memory referenced only by pointers +stored in such default-allocated objects is likely to be reclaimed prematurely +by the collector. + +It is the programmers responsibility to ensure that garbage-collectible memory +is referenced by pointers stored in one of + + * Program variables + * Garbage-collected objects + * Uncollected but _traceable_ objects + +Traceable objects are not necessarily reclaimed by the collector, but are +scanned for pointers to collectible objects. They are usually allocated +by `GC_MALLOC_UNCOLLECTABLE`, as described above, and through some interfaces +described below. + +On most platforms, the collector may not trace correctly from in-flight +exception objects. Thus objects thrown as exceptions should only point +to otherwise reachable memory. This is another bug whose proper repair +requires platform hooks. + +The easiest way to ensure that collectible objects are properly referenced +is to allocate only collectible objects. This requires that every allocation +go through one of the following interfaces, each one of which replaces +a standard C++ allocation mechanism. Note that this requires that all STL +containers be explicitly instantiated with `gc_allocator`. + +### STL allocators + +Recent versions of the collector include a hopefully standard-conforming +allocator implementation in `gc_allocator.h`. It defines `traceable_allocator` +and `gc_allocator` which may be used either directly to allocate memory or to +instantiate container templates. The former allocates uncollectible but traced +memory. The latter allocates garbage-collected memory. + +These should work with any fully standard-conforming C++ compiler. + +### Class inheritance based interface for new-based allocation + +Users may include `gc_cpp.h` and then cause members of classes to be allocated +in garbage collectible memory by having those classes inherit from class `gc`. +For details see `gc_cpp.h` file. + +Linking against `gccpp` in addition to the `gc` library overrides `::new` +(and friends) to allocate traceable but uncollectible memory, making +it safe to refer to collectible objects from the resulting memory. + +If the user includes `gc_cpp.h` but `::new` should not be overridden then +`gctba` (in addition to the `gc`) library should be linked with to provide +the definition of `GC_throw_bad_alloc` C++ function used by operator `new` of +class `gc`. Alternatively, the client may define `GC_NEW_ABORTS_ON_OOM` macro +before include of `gc_cpp.h` (this instructs `::new` to issue an abort instead +of throwing an exception), or may define `GC_INCLUDE_NEW` one before include +of `gc_cpp.h` (however, this might not compile or work as expected on some +platforms). + +## C interface + +It is also possible to use the C interface from `gc.h` directly. On platforms +which use `malloc` to implement `::new`, it should usually be possible to use +a version of the collector that has been compiled as a `malloc` replacement. +It is also possible to replace `::new` and other allocation functions +suitably, as is done by `gccpp`. + +Note that user-implemented small-block allocation often works poorly with +an underlying garbage-collected large block allocator, since the collector has +to view all objects accessible from the user's free list as reachable. This +is likely to cause problems if `GC_MALLOC` is used with something like the +original HP version of STL. This approach works well with the SGI versions +of the STL only if the `malloc_alloc` allocator is used. |