* OS2_MAKEFILE: Fix a typo in comment ("it is there").
* README.md: Fix typos ("is not", "gc_inline.h", "bytes from",
"processed").
* doc/README.OS2: Fix typos ("how", "linking").
* doc/README.amiga: Fix typos ("GC", "e.g.", "GC_*_typed", "i.e.",
"SMakefile.amiga", "communications").
* doc/README.cmake: Fix a typo ("go to").
* doc/README.ews4800: Fix a typo ("a unique").
* doc/README.solaris2: Fix a typo ("toolchain").
* doc/finalization.md: Fix incorrect number of markup '#' symbols to
denote H2 header.
* doc/overview.md: Likewise.
* doc/gcdescr.md: Fix typos ("collects", "then advances", "is not",
"treated by").
* doc/gcinterface.md: Fix typos ("Build it", "Allocates",
"deallocates", "forces", "Causes", "Replaces", "Registers",
"traceable_alloc", "single_client_traceable_alloc").
* doc/leak.md: Fix typos ("there is", "provides").
* doc/overview.md (Further reading): Replace "&" with "and".
* doc/porting.md: Add missing ")" symbol; add missing comma; fix typos
("region_start", "region_end", "collector's", "are needed",
"GC_save_callers").
* include/private/gc_priv.h: Fix a typo in comment ("gc_inline.h").
* os_dep.c [GWW_VDB] (detect_GetWriteWatch, GC_gww_read_dirty): Fix
abbreviation ("Win2K") in a comment.
* os_dep.c [MSWIN32] (GC_wnt): Likewise.
* os_dep.c [GWW_VDB] (GC_gww_read_dirty): Fix a typo in comment
("behavior").
$(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h
## ERASE THE LIB FIRST - if it is already there then this command will fail
-## (make sure its there or erase will fail!)
+## (make sure it is there or erase will fail!)
gc.lib: $(OBJS)
echo . > gc.lib
erase gc.lib
There are a number of routines which modify the pointer recognition
algorithm. `GC_register_displacement` allows certain interior pointers
-to be recognized even if `ALL_INTERIOR_POINTERS` is nor defined.
+to be recognized even if `ALL_INTERIOR_POINTERS` is not defined.
`GC_malloc_ignore_off_page` allows some pointers into the middle of
large objects to be disregarded, greatly reducing the probability of
accidental retention of large objects. For most purposes it seems
#define malloc(n) GC_malloc(n)
#define calloc(m,n) GC_malloc((m)*(n))
-For small pieces of VERY allocation intensive code, gc_inl.h includes
+For small pieces of VERY allocation intensive code, gc_inline.h includes
some allocation macros that may be used in place of `GC_malloc` and
friends.
defined, then all these macros will instead be defined to their nondebugging
equivalents. (`GC_REGISTER_FINALIZER` is necessary, since pointers to
objects with debugging information are really pointers to a displacement
-of 16 bytes form the object beginning, and some translation is necessary
+of 16 bytes from the object beginning, and some translation is necessary
when finalization routines are invoked. For details, about what's stored
in the header, see the definition of the type oh in dbg_mlc.c file.)
is enabled.
(On 2007 vintage machines, GC times may be on the order of 5 ms
-per MB of accessible memory that needs to be scanned and processor.
+per MB of accessible memory that needs to be scanned and processed.
Your mileage may vary.) The incremental/generational collection facility
may help in some cases.
* Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved.
* Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
* Copyright (c) 1999-2011 by Hewlett-Packard Development Company.
- * Copyright (c) 2008-2018 Ivan Maidanski
+ * Copyright (c) 2008-2019 Ivan Maidanski
The files pthread_stop_world.c, pthread_support.c and some others are also
not been ported. The cord test program has. The supplied OS2_MAKEFILE
assumes the IBM C Set/2 environment, but the code shouldn't.
-Since we haven't figured out hoe to do perform partial links or to build static
+Since we haven't figured out how to do partial linking or to build static
libraries, clients currently need to link against a long list of executables.
WHATS NEW:
1.
- Made a pretty big effort in preventing GCs allocating-functions from returning
- chip-mem.
+ Made a pretty big effort in preventing GC allocating-functions from
+ returning chip-mem.
The lower part of the new file AmigaOS.c does this in various ways, mainly by
wrapping GC_malloc, GC_malloc_atomic, GC_malloc_uncollectable,
GC_malloc_atomic_uncollectable, GC_malloc_ignore_off_page
and GC_malloc_atomic_ignore_off_page. GC_realloc is also wrapped, but
doesn't do the same effort in preventing to return chip-mem.
- Other allocating-functions (f.ex. GC_*_typed_) can probably be
+ Other allocating-functions (e.g., GC_*_typed) can probably be
used without any problems, but beware that the warn hook will not be called.
In case of problems, don't define GC_AMIGA_FASTALLOC.
GC_AMIGA_FASTALLOC by letting the function go thru the new
GC_amiga_allocwrapper_do function-pointer (see gc.h). Means that
sending function-pointers, such as GC_malloc, GC_malloc_atomic, etc.,
- for later to be called like f.ex this, (*GC_malloc_function_pointer)(size),
+ for later to be called, e.g., like this, (*GC_malloc_function_pointer)(size),
will not wrap the function. This is normally not a big problem, unless
all allocation function is called like this, which will cause the
atexit un-allocating function never to be called. Then you either
There are probably better ways this problem could be handled, unfortunately,
I didn't find any without rewriting or replacing a lot of the GC-code, which
I really didn't want to. (Making new GC_malloc_* functions, and just
- define f.ex GC_malloc as GC_amiga_malloc should work too).
+ defining, e.g., GC_malloc as GC_amiga_malloc should work too).
New Amiga-specific function:
void GC_amiga_set_toany(void (*func)(void));
'func' is a function that will be called right before gc has to change
- allocation-method from MEMF_FAST to MEMF_ANY. Ie. when it is likely
+ allocation-method from MEMF_FAST to MEMF_ANY. I.e., when it is likely
it will return chip-mem.
2. A few small compiler-specific additions to make it compile with SAS/C again.
-3. Updated and rewritten the smakefile, so that it works again and that
+3. Updated and rewritten the SMakefile.amiga, so that it works again and that
the "unnecessary" 'SCOPTIONS' files could be removed. Also included
the cord-smakefile stuff in the main smakefile, so that the cord smakefile
could be removed too. By writing smake -f Smakefile.smk, both gc.lib and
In keeping with the porting philosophy outlined above, this port
will not behave well with Amiga specific code. Especially not inter-
-process comms via messages, and setting up public structures like
+process communications via messages, and setting up public structures like
Intuition objects or anything else in the system lists. For the
time being the use of this library is limited to single threaded
-ANSI/POSIX compliant or near-compliant code. (ie. Stick to stdio
+ANSI/POSIX compliant or near-compliant code. (i.e., stick to stdio
for now). Given this limitation there is currently no mechanism for
allocating "CHIP" or "PUBLIC" memory under the garbage collector.
I'll add this after giving it considerable thought. The major
-----
The main input to cmake are the CMakeLists.txt files in each directory. For
-help, goto cmake.org.
+help, go to cmake.org.
*** Caution: The following information is empirical. ***
32-bit:
- ELF file has an unique format. (See a.out(4) and end(3C).)
+ ELF file has a unique format. (See a.out(4) and end(3C).)
&_start
: text segment
I encountered "symbol <unknown>: offset .... is non-aligned" errors. These
appear to be traceable to the use of the GNU assembler with the Sun linker.
The former appears to generate a relocation not understood by the latter.
-The fix appears to be to use a consistent tool chain. (As a non-Solaris-expert
+The fix appears to be to use a consistent toolchain. (As a non-Solaris-expert
my solution involved hacking the libtool script, but I'm sure you can
do something less ugly.)
actions, which are then explicitly run during an explicit call by the user's
program.
-# Topologically Ordered Finalization
+## Topologically ordered finalization
Our _conservative garbage collector_ supports a form of finalization (with
`GC_register_finalizer`) in which objects are finalized in topological order.
Cycles involving one or more finalizable objects are never finalized.
-# Why topological ordering?
+## Why topological ordering?
It is important to keep in mind that the choice of finalization ordering
matters only in relatively rare cases. In spite of the fact that it has
reachable from another finalizer via a pointer chain is presumed to be
accessible by the finalizer, and thus should not be finalized.
-# Programming with topological finalization
+## Programming with topological finalization
Experience with Cedar has shown that cycles or long chains of finalizable
objects are typically not a problem. Finalizable objects are typically rare.
references are still left at process exit, they can be explicitly deallocated
then.
-# Getting around topological finalization ordering
+## Getting around topological finalization ordering
There are certain situations in which cycles between finalizable objects are
genuinely unavoidable. Most notably, C++ compilers introduce self-cycles
* Programs with a large root set size and little live heap memory will
expand the heap to amortize the cost of scanning the roots.
- * GC actually collect more frequently in non-incremental mode. The large
+ * GC actually collects more frequently in non-incremental mode. The large
block allocator usually refuses to split large heap blocks once the garbage
collection threshold is reached. This often has the effect of collecting
well before the heap fills up, thus reducing fragmentation and working set
objects, roots, and then mark everything reachable from them. `scan_ptr`
is advanced through the heap until all uncollectible objects are pushed, and
objects reachable from them are marked. At that point, the next call
- to `GC_mark_some` calls `GC_push_roots` to push the roots. It the advances
- the mark state to
+ to `GC_mark_some` calls `GC_push_roots` to push the roots. It, then,
+ advances the mark state to
3. `MS_ROOTS_PUSHED` asserting that once the mark stack is empty, all
reachable objects are marked. Once in this state, we work only on emptying
the mark stack. Once this is completed, the state changes to
the page is not part of the garbage collected heap, a small integer _n_,
indicating that the page is part of large object, starting at least _n_
pages back, or a pointer to a descriptor for the page. In the first case,
- the candidate pointer `i` not a true pointer and can be safely ignored.
+ the candidate pointer is not a true pointer and can be safely ignored.
In the last two cases, we can obtain a descriptor for the page containing
the beginning of the object.
* The starting address of the referenced object is computed. The page
linked using the first word in the object. In most cases this means they
require considerably less time.
-Local free lists are treated buy most of the rest of the collector as though
+Local free lists are treated by most of the rest of the collector as though
they were in-use reachable data. This requires some care, since pointer-free
objects are not normally traced, and hence a special tracing procedure
is required to mark all objects on pointer-free and gcj local free lists.
# C/C++ Interface
On many platforms, a single-threaded garbage collector library can be built
-to act as a plug-in `malloc` replacement. (Build with
+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
does not appear to be reachable. (Objects allocated in this way are
effectively treated as roots by the collector.)
-**void * `GC_REALLOC`(void * _old_, size_t _new_size_)** - Allocate a new
+**void * `GC_REALLOC`(void * _old_, size_t _new_size_)** - Allocates a new
object of the indicated size and copy (a prefix of) the old object 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 * _dead_)** - Explicitly deallocate an object. Typically
-not useful for small collectible objects.
+**void `GC_FREE`(void * _dead_)** - Explicitly deallocates an object.
+Typically not useful for small collectible objects.
**void * `GC_MALLOC_IGNORE_OFF_PAGE`(size_t _nbytes_)** and
**void * `GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE`(size_t _nbytes_)** - Analogous
code, though we try to ensure that it expands to a no-op on as many platforms
as possible.
-**void `GC_gcollect`(void)** - Explicitly force a garbage collection.
+**void `GC_gcollect`(void)** - Explicitly forces a garbage collection.
-**void `GC_enable_incremental`(void)** - Cause the garbage collector
+**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
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)** - Replace the default procedure
+**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`(...)** - Register a function to be called when
+**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
This defines SGI-style allocators
- * `alloc`
- * `single_client_alloc`
+ * `traceable_alloc`
+ * `single_client_traceable_alloc`
* `gc_alloc`
* `single_client_gc_alloc`
primary function of the collector is to report objects that were allocated
(typically with `GC_MALLOC`), not deallocated (normally with `GC_FREE`), but
are no longer accessible. Since the object is no longer accessible, there
-in normally no way to deallocate the object at a later time; thus it can
+is normally no way to deallocate the object at a later time; thus it can
safely be assumed that the object has been "leaked".
This is substantially different from counting leak detectors, which simply
exit time, a potentially useless activity that often triggers large amounts
of paging.
-The garbage collector provide leak detection support. This includes the
+The garbage collector provides leak detection support. This includes the
following features:
1. Leak detection mode can be initiated at run-time by setting
compensated for by decreased copying etc. if programs are written and tuned
for garbage collection.
-# Further Reading:
+## Further reading
**The beginnings of a frequently asked questions list for this collector are
[here](http://www.hboehm.info/gc/faq.html)**.
Boehm, H., and [M. Weiser](http://www.ubiq.com/hypertext/weiser/weiser.html),
[Garbage Collection in an Uncooperative Environment](http://www.hboehm.info/spe_gc_paper/),
-_Software Practice & Experience_, September 1988, pp. 807-820.
+_Software Practice and Experience_, September 1988, pp. 807-820.
Boehm, H., A. Demers, and S. Shenker,
[Mostly Parallel Garbage Collection](http://www.hboehm.info/gc/papers/pldi91.ps.Z),
Slides for Hans Boehm's
[Allocation and GC Myths](http://www.hboehm.info/gc/myths.ps) talk.
-# Current users:
+## Current users
Known current users of some variant of this collector include:
[Asymptote LaTeX-compatible vector graphics language](http://asymptote.sf.net/).
-# More information on the BDWGC primary site
+## Information provided on the BDWGC site
[A simple illustration of how to build and use the collector](simple_example.md).
files of all garbage collector releases. It duplicates
[Download](https://github.com/ivmai/bdwgc/wiki/Download) page on GitHub.
-# More background information
+## More background information
[An attempt to establish a bound on space usage of conservative garbage collectors](http://www.hboehm.info/gc/bounds.html).
[Related papers](http://www.hboehm.info/gc/papers/).
-# Contacts and new release announcements
+## Contacts and new release announcements
GitHub and Stack Overflow are the major two places for communication.
RISC variants.) On GNU-based systems, `cpp -dM empty_source_file.c` seems
to generate a set of predefined macros. On some other systems, the "verbose"
compiler option may do so, or the manual page may list them.
+
2. A section that defines a small number of platform-specific macros, which
are then used directly by the collector. For simple ports, this is where
most of the effort is required. We describe the macros below. This section
trace all memory between `DATASTART` and `DATAEND` for root pointers.
On some platforms, this can be defined to a constant address, though
experience has shown that to be risky. Ideally the linker will define
- a symbol (e.g. `_data` whose address is the beginning of the data segment.
+ a symbol (e.g. `_data`) whose address is the beginning of the data segment.
Sometimes the value can be computed using the `GC_SysVGetDataStart`
function. Not used if either the next macro is defined, or if dynamic
loading is supported, and the dynamic loading support defines a function
three macros is defined, client code must explicitly set `GC_stackbottom`
to an appropriate value before calling `GC_INIT` or any other `GC_` routine.
* `LINUX_STACKBOTTOM` - May be defined instead of `STACKBOTTOM`. If defined,
- then the cold end of the stack will be determined Currently we usually read
- it from `/proc`.
+ then the cold end of the stack will be determined, we usually read it from
+ `/proc`.
* `HEURISTIC1` - May be defined instead of `STACKBOTTOM`. `STACK_GRAN`
should generally also be redefined. The cold end of the stack is determined
by taking an address inside `GC_init`s frame, and rounding it up to the next
If your platform supports `getcontext` then defining the macro
`UNIX_LIKE` for your OS in `gcconfig.h` (if it is not defined there yet)
-is likely to solve the problem. otherwise, if you are using gcc,
+is likely to solve the problem. Otherwise, if you are using gcc,
`_builtin_unwind_init` will be used, and should work fine. If that is not
applicable either, the implementation will try to use `setjmp`. This will work
if your `setjmp` implementation saves all possibly pointer-valued registers
`gcconfig.h`.
* An appropriate versions of the functions `GC_register_dynamic_libraries`
should be defined in `dyn_load.c`. This function should invoke
- `GC_cond_add_roots(_region_start, region_end_, TRUE)` on each dynamic
+ `GC_cond_add_roots(region_start, region_end, TRUE)` on each dynamic
library data section.
Implementations that scan for writable data segments are error prone,
For incremental and generational collection to work, `os_dep.c` must contain
a suitable _virtual dirty bit_ implementation, which allows the collector
-to track which heap pages (assumed to be a multiple of the collectors block
+to track which heap pages (assumed to be a multiple of the collector's block
size) have been written during a certain time interval. The collector provides
several implementations, which might be adapted. The default (`DEFAULT_VDB`)
is a placeholder which treats all pages as having been written. This ensures
## Stack traces for debug support
-If stack traces in objects are need for debug support, `GC_dave_callers` and
+If stack traces in objects are needed for debug support, `GC_save_callers` and
`GC_print_callers` must be implemented.
## Disclaimer
/* be pointers are also put here. */
/* The main fields should precede any */
/* conditionally included fields, so that */
-/* gc_inl.h will work even if a different set */
-/* of macros is defined when the client is */
+/* gc_inline.h will work even if a different */
+/* set of macros is defined when the client is */
/* compiled. */
struct _GC_arrays {
GC_ULONG_PTR count = 16;
DWORD page_size;
/* Check that it actually works. In spite of some */
- /* documentation it actually seems to exist on W2K. */
+ /* documentation it actually seems to exist on Win2K. */
/* This test may be unnecessary, but ... */
if (GetWriteWatch_func(WRITE_WATCH_FLAG_RESET,
page, GC_page_size,
/* assembly code to do that right. */
GC_INNER GC_bool GC_wnt = FALSE;
- /* This is a Windows NT derivative, i.e. NT, W2K, XP or later. */
+ /* This is a Windows NT derivative, i.e. NT, Win2K, XP or later. */
GC_INNER void GC_init_win32(void)
{
count = GC_GWW_BUF_LEN;
/* GetWriteWatch is documented as returning non-zero when it */
/* fails, but the documentation doesn't explicitly say why it */
- /* would fail or what its behaviour will be if it fails. */
- /* It does appear to fail, at least on recent W2K instances, if */
+ /* would fail or what its behavior will be if it fails. It */
+ /* does appear to fail, at least on recent Win2K instances, if */
/* the underlying memory was not allocated with the appropriate */
/* flag. This is common if GC_enable_incremental is called */
/* shortly after GC initialization. To avoid modifying the */