• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

Makefile.inH A D24-Oct-202123.2 KiB663594

READMEH A D24-Oct-202111 KiB267208

alloc_cache.cH A D24-Oct-20217.7 KiB281197

backtrace.cH A D24-Oct-20214.3 KiB159121

block_cache.cH A D24-Oct-202116.6 KiB522447

check-sdep.rktH A D24-Oct-20211.8 KiB4441

commongc_internal.hH A D24-Oct-20211.7 KiB7352

fnls.cH A D24-Oct-20215.1 KiB204152

gc.hH A D24-Oct-202138 41

gc2.cH A D24-Oct-2021276 1811

gc2.hH A D24-Oct-202123.8 KiB671212

gc2_dump.hH A D24-Oct-20211.9 KiB4835

gc2_obj.hH A D24-Oct-20211.1 KiB3825

gclist.hH A D24-Oct-20214.4 KiB184144

immobile_boxes.cH A D24-Oct-20211.8 KiB5848

mem_account.cH A D24-Oct-202125.8 KiB922730

msgprint.cH A D24-Oct-20213.6 KiB221180

my_qsort.cH A D24-Oct-20212.4 KiB9768

newgc.cH A D24-Oct-2021196.3 KiB6,4974,980

newgc.hH A D24-Oct-202113 KiB419323

page_range.cH A D24-Oct-20214 KiB181141

places_gc.cH A D24-Oct-202116.1 KiB547427

platforms.hH A D24-Oct-2021970 3520

precomp.cH A D24-Oct-202129 31

rlimit_heapsize.cH A D24-Oct-2021394 2316

roots.cH A D24-Oct-20212.2 KiB9565

sighand.cH A D24-Oct-20218.3 KiB309242

stack_comp.cH A D24-Oct-2021198 86

testing.cH A D24-Oct-20213 KiB8478

var_stack.cH A D24-Oct-20211.5 KiB8972

vm.cH A D24-Oct-20219.2 KiB305238

vm_memalign.cH A D24-Oct-20211.2 KiB5935

vm_mmap.cH A D24-Oct-20211.2 KiB6240

vm_osk.cH A D24-Oct-2021660 3620

vm_osx.cH A D24-Oct-202117.4 KiB558441

vm_win.cH A D24-Oct-20211.5 KiB6244

weak.cH A D24-Oct-202119.7 KiB741558

xform-mod.rktH A D24-Oct-20212.7 KiB8977

README

1This README provides an overview of the precise GC interface used by
2Racket. The header files "gc2.h" and "gc2_dump.h" provide additional
3API documentation.
4
5GC Interface
6------------
7
8The GC interface for Racket is designed to support precise collection
9with both moving and non-moving collectors. Generational and
10incremental collectors must rely on hardware-based memory protection
11for their implementation (to detect writes into old objects, etc.).
12
13As a general rule, all pointers to collectable objects reference the
14beginning of the object (i.e., the pointer is never into the interior
15of the object). The exception is that a pointer may reference the
16interior of an "Interior" object, but Racket allocates such objects
17infrequently, and only as relatively large objects.
18
19All allocated memory must be longword-aligned. For architectures where
20`double' values must be 8-byte aligned, the GC must provide 8-byte
21aligned memory in response to an allocation request for a memory size
22divisible by 8. Except for atomic memory, allocated objects must be
23completely initialized with 0s.
24
25Memory locations that hold pointers to collectable objects can also
26hold pointers to non-collectable memory. They may also contain a
27"fixnum" integer, where the lowest bit is set (so it could never be
28confused with a longword-aligned pointer). Thus, the collector must
29distinguish between longword-aligned pointers into collected memory
30regions and all other pointers.
31
32At any point when the allocator/collector is invoked, Racket will
33have set the GC_variable_stack variable to indicate a chain of local
34pointer variables on the stack (i.e., both the chain of record and the
35pointer variables themselves are on the stack). The GC_variable_stack
36global points to a value of the form
37
38     struct {
39        void *next_frame;
40        intptr_t frame_size;
41        void **pointers[...];
42     }
43
44where the size of `pointers' is indicated by `frame_size'. Each
45element of `pointers' is usually the address of a pointer of the
46stack. It can also be 0, in which case the next `pointers' element is
47an integer, and the following `pointers' element is a pointer to an
48array of the indicated size. (The three `pointers' slots contribute 3
49towards the value of `frame_size'.)
50
51The `next_frame' field in the structure gives the address of the next
52frame on the stack, and so on. The garbage collector should follow the
53chain of frames, adjusting pointers for copying collection, until it
54reaches a frame that is the same as the value returned by
55GC_get_thread_stack_base() (which is supplied by Racket).
56
57More generally, GC_mark_variable_stack() can be used to GC a stack
58that has been copied into the heap. See below for more details.
59
60Marking and Moving Objects
61--------------------------
62
63Cooperation between the garbage collector's movement of objects and
64Racket's view of object shapes (pointers versus non-pointers) is
65mediated by "mark" and "fixup" functions:
66
67 * The "mark" pass traverses objects in the heap, potentially moving
68   them and adjusting references.
69
70 * An optional extra "fixup" pass further adjusts references to moved
71   objects.
72
73The mark and fixup steps are exposed by gcMARK and gcFIXUP macros that
74are provided by the collector. In addition, the collector provides a
75GC_resolve operation, which converts an object's old address to a new
76one in the case that the object is being moved; given an object's new
77address GC_resolve returns the same address. A GC_is_marked operation
78reports whether an object at its old address has been marked; it works
79only on old addresses.
80
81Normally, the mark function for an object is called only when the
82object is first marked in a given GC pass. With generational
83collection, the mark function can be called for an old-generation
84object if it potentially changed since a previous collection; still,
85the mark function will be called only once during that collection, so
86it's as if the object were in the new generation. With incremental
87collection, however, a macro procedure can be called due to changes
88even if the object is already incrementally marked as an
89old-generaiton object. The GC_current_mode() function reports the
90current mode for a given call to the marking function.
91
92Memory Kinds
93------------
94
95Racket allocates the following kinds of memory objects:
96
97 * Tagged - The object starts with a `short' integer containing the
98   tag, but the tag will always be less than 256. After requesting
99   memory from the GC, Racket installs the tag before performing any
100   other memory operation. Racket provides three functions for each tag:
101
102    o an operation for obtaining the value's size in words (not
103      bytes!);
104
105    o an operation for marking pointers within the object; and
106
107    o an operation for another fixup pass.
108
109   The mark and fixup procedures use the gcMARK and gcFIXUP macros
110   provided by the collector. The mark and fixup operations also
111   return the size of the object, like the size procedure, unless
112   GC_NO_SIZE_NEEDED_FROM_PROCS is defined.
113
114 * Atomic - The allocated object contains no pointers to other
115   allocated objects.
116
117 * Atomic Tagged - Like a tagged object, but the mark and fixup
118   procedures are no-ops.
119
120 * Array - The allocated object is an array of pointers to other
121   allocated objects.
122
123 * Pair - specialization of Tagged to pairs.
124
125 * Interior Array - Like array objects, but pointers to the object can
126   reference its interior, rather than just the start of the object,
127   and the object never moves. Such pointers will always be
128   longword-aligned. Racket allocates interior objects infrequently,
129   and only as relatively large objects.
130
131 * Weak Box - The object has the following initial structure:
132
133     struct {
134       short tag;
135       short filler_used_for_hashing;
136       void *val;
137     }
138
139   Racket reads the `tag' and `val' fields, and both reads and
140   writes the `filler_used_for_hashing' field. Racket also provides
141   the value to be used for `tag', via GC_init_type_tags(). The reason
142   this structure is implemented by the collector is to handle the
143   special behavior of the weak link.
144
145   Racket can change `val' at any time; when a collection happens,
146   if the object in `val' is collectable and is collected, then `val'
147   is zeroed.  The `val' pointer must be updated by the collector if
148   the object it refers to is moved by the collector, but it does not
149   otherwise keep an object from being collected.
150
151   The interface for creating weak boxes is
152
153    void *GC_malloc_weak_box(void *p, void **secondary, int soffset);
154
155   If the `secondary' argument is not NULL, it points to an auxiliary
156   address that should be zeroed (by the collector) whenever `val' is
157   zeroed. To allow zeroing in the interior of an allocated pointer,
158   the zero-out address is determined by `secondary + soffset'. The
159   memory referenced by `secondary' is kept live as long as it isn't
160   zeroed by its registration in the weak box, but when the content of
161   `secondary + soffset' is zeroed, the `secondary' pointer in the
162   weak box should also be zeroed.
163
164 * Late Weak Box - A weak box that holds onto its reference until
165   level-2 finalizers are queued (see below). Late weak boxes are
166   created with GC_malloc_late_weak_box().
167
168 * Weak Array - The object has the following structure:
169
170     struct {
171       intptr_t gc_private[4];
172       intptr_t array[...];
173     }
174
175   The gc_private array contains collector-private values that are
176   neither read nor written by Racket. The array field is an array
177   of weak pointers to collectable objects. See GC_malloc_weak_array()
178   in gc2.h for more details.
179
180 * Ephemeron - The object has the following initial structure:
181
182     struct {
183       short tag;
184       short filler_used_for_hashing;
185       void *key;
186       void *val;
187     }
188
189   See "Weak Box" above. The difference for an ephemeron is that
190   the ephemeron must hold `val' strongly as long as the wealy-held
191   `key' is accessible --- where `val' itself isn't traced unless
192   both the ephemeron and `key' are reachable. (In particular,
193   a reference from `val' to `key' doesn't prevent collection of
194   `key'.)
195
196 * Immobile box - a longword-sized box that can contain a reference to
197   a collectable object, but it not itself collectable or movable. An
198   immobile box lets Racket refer to a collectable object (through
199   one indirection) from memory that is not traversed by the
200   collector.
201
202   The GC_malloc_immobile_box() function creates an immobile box with
203   an initial value:
204
205     void **GC_malloc_immobile_box(void *p);
206
207   Immobile boxes must be explicitly freed with the
208   GC_free_immobile_box() function:
209
210     void GC_free_immobile_box(void **b);
211
212Of course, an implementation of the collector may collapse any of
213these categories internally.
214
215Finalization
216------------
217
218The finalization interface is
219
220  void GC_set_finalizer(void *p, int tagged, int level,
221                        GC_finalization_proc f, void *data,
222                        GC_finalization_proc *oldf, void **olddata);
223
224This function installs a finalizer to be queued for invocation when
225`p' would otherwise be collected. All ready finalizers should be
226called at the end of a collection. (A finalization can trigger calls
227back to the collector, but such a collection will not run more
228finalizers.) The `p' argument must normally point to the beginning of
229a tagged (including atomic or pair) object; that is, `tagged' is
230currently required to be non-zero.
231
232The `level' argument refers to an ordering of finalizers. It can be 1,
2332, or 3. During a collection, level 1 finalizers are queued first,
234then all objects queued for finalization are marked as live and
235traversed. Next, level 2 finalizers are queued in the same way. Thus,
236if a level 1 object refers to a level 2 object, the level 1 object
237will be queued for finalization, and only sometime after the finalizer
238is run and the object is again no longer referenced can the level 2
239object be finalized. Finally, level 3 finalizers are queued.
240
241The `f' and `data' arguments define the finalizer closure to be called
242for `p'. If a finalizer is already installed for `p', it is replaced,
243and `oldf' and `olddata' are filled with the old closure. If `f' is
244NULL, any existing finalizer is removed and no new one is
245installed. The single-callback rule applies across level 1 and level
2462 finalizers (but scheme_register_finalizer(), etc., in "salloc.c" can
247merge them).
248
249The `p' object isn't actually collected when a finalizer is queued,
250since the finalizer will receive `p' as an argument. Weak references
251are cleared after level 1 fnalizers are queued, while "late weak box"
252references are cleared after level 2 finalizers are clear.
253
254Functions versus Macros
255-----------------------
256
257Any function in the defined interface can be implemented as a
258macro. Indeed, gcMARK() and gcFIXUP() are expected to be
259macros.
260
261Due to the way that the Racket and GRacket code is generated for
262precise collection, the header file gc2.h must allow multiple
263inclusion in two different phases. If the pre-processor symbol
264GC2_JUST_MACROS is defined, then the header should only define
265macros. If GC2_JUST_MACROS is not defined, then the header should
266define all typedefs, function proptypes, and macros.
267