mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Rename "whippet" collector to "mmc": mostly marking collector
This commit is contained in:
parent
cf129f10de
commit
44a7240e16
10 changed files with 133 additions and 124 deletions
50
Makefile
50
Makefile
|
@ -5,21 +5,21 @@ COLLECTORS = \
|
|||
scc \
|
||||
pcc \
|
||||
\
|
||||
whippet \
|
||||
stack-conservative-whippet \
|
||||
heap-conservative-whippet \
|
||||
mmc \
|
||||
stack-conservative-mmc \
|
||||
heap-conservative-mmc \
|
||||
\
|
||||
parallel-whippet \
|
||||
stack-conservative-parallel-whippet \
|
||||
heap-conservative-parallel-whippet \
|
||||
parallel-mmc \
|
||||
stack-conservative-parallel-mmc \
|
||||
heap-conservative-parallel-mmc \
|
||||
\
|
||||
generational-whippet \
|
||||
stack-conservative-generational-whippet \
|
||||
heap-conservative-generational-whippet \
|
||||
generational-mmc \
|
||||
stack-conservative-generational-mmc \
|
||||
heap-conservative-generational-mmc \
|
||||
\
|
||||
parallel-generational-whippet \
|
||||
stack-conservative-parallel-generational-whippet \
|
||||
heap-conservative-parallel-generational-whippet
|
||||
parallel-generational-mmc \
|
||||
stack-conservative-parallel-generational-mmc \
|
||||
heap-conservative-parallel-generational-mmc
|
||||
|
||||
DEFAULT_BUILD := opt
|
||||
|
||||
|
@ -70,28 +70,28 @@ GC_CFLAGS_scc = -DGC_PRECISE_ROOTS=1
|
|||
GC_STEM_pcc = pcc
|
||||
GC_CFLAGS_pcc = -DGC_PRECISE_ROOTS=1 -DGC_PARALLEL=1
|
||||
|
||||
define whippet_variant
|
||||
GC_STEM_$(1) = whippet
|
||||
define mmc_variant
|
||||
GC_STEM_$(1) = mmc
|
||||
GC_CFLAGS_$(1) = $(2)
|
||||
endef
|
||||
|
||||
define generational_whippet_variants
|
||||
$(call whippet_variant,$(1)whippet,$(2))
|
||||
$(call whippet_variant,$(1)generational_whippet,$(2) -DGC_GENERATIONAL=1)
|
||||
define generational_mmc_variants
|
||||
$(call mmc_variant,$(1)mmc,$(2))
|
||||
$(call mmc_variant,$(1)generational_mmc,$(2) -DGC_GENERATIONAL=1)
|
||||
endef
|
||||
|
||||
define parallel_whippet_variants
|
||||
$(call generational_whippet_variants,$(1),$(2))
|
||||
$(call generational_whippet_variants,$(1)parallel_,$(2) -DGC_PARALLEL=1)
|
||||
define parallel_mmc_variants
|
||||
$(call generational_mmc_variants,$(1),$(2))
|
||||
$(call generational_mmc_variants,$(1)parallel_,$(2) -DGC_PARALLEL=1)
|
||||
endef
|
||||
|
||||
define trace_whippet_variants
|
||||
$(call parallel_whippet_variants,,-DGC_PRECISE_ROOTS=1)
|
||||
$(call parallel_whippet_variants,stack_conservative_,-DGC_CONSERVATIVE_ROOTS=1)
|
||||
$(call parallel_whippet_variants,heap_conservative_,-DGC_CONSERVATIVE_ROOTS=1 -DGC_CONSERVATIVE_TRACE=1)
|
||||
define trace_mmc_variants
|
||||
$(call parallel_mmc_variants,,-DGC_PRECISE_ROOTS=1)
|
||||
$(call parallel_mmc_variants,stack_conservative_,-DGC_CONSERVATIVE_ROOTS=1)
|
||||
$(call parallel_mmc_variants,heap_conservative_,-DGC_CONSERVATIVE_ROOTS=1 -DGC_CONSERVATIVE_TRACE=1)
|
||||
endef
|
||||
|
||||
$(eval $(call trace_whippet_variants))
|
||||
$(eval $(call trace_mmc_variants))
|
||||
|
||||
# $(1) is the benchmark, $(2) is the collector configuration
|
||||
make_gc_var = $$($(1)$(subst -,_,$(2)))
|
||||
|
|
57
README.md
57
README.md
|
@ -12,50 +12,59 @@ allocation, and provides a number of implementations of that API.
|
|||
|
||||
See the [documentation](./doc/README.md).
|
||||
|
||||
## Features
|
||||
|
||||
- Per-object pinning (with `mmc` collectors)
|
||||
- Finalization (supporting resuscitation)
|
||||
- Ephemerons (except on `bdw`, which has a polyfill)
|
||||
- Conservative roots (optionally with `mmc` or always with `bdw`)
|
||||
- Precise roots (optionally with `mmc` or always with `semi` / `pcc` /
|
||||
`scc`)
|
||||
- Precise embedder-parameterized heap tracing (except with `bdw`)
|
||||
- Conservative heap tracing (optionally with `mmc`, always with `bdw`)
|
||||
- Parallel tracing (except `semi` and `scc`)
|
||||
- Parallel mutators (except `semi`)
|
||||
- Inline allocation / write barrier fast paths (supporting JIT)
|
||||
- One unified API with no-overhead abstraction: switch collectors when
|
||||
you like
|
||||
|
||||
## Source repository structure
|
||||
|
||||
* [api/](./api/): The user-facing API. Also, the "embedder API"; see
|
||||
the [manual](./doc/manual.md) for more.
|
||||
* [doc/](./doc/): Documentation, such as it is.
|
||||
* [src/](./src/): The actual GC implementation. The specific
|
||||
implementations of the Whippet API are [`semi.c`](./src/semi.c), a
|
||||
semi-space collector; [`bdw.c`](./src/bdw.c), the third-party
|
||||
[BDW-GC](https://github.com/ivmai/bdwgc) conservative parallel
|
||||
stop-the-world mark-sweep segregated-fits collector with lazy
|
||||
sweeping; and [`whippet.c`](./src/whippet.c), the whippet collector.
|
||||
* [src/](./src/): The actual GC implementation, containing a number of
|
||||
collector implementations. The embedder chooses which collector to
|
||||
use at compile-time. See the [documentation](./doc/collectors.md)
|
||||
for more on the different collectors (`semi`, `bdw`, `scc`, `pcc`,
|
||||
and the different flavors of `mmc`).
|
||||
* [benchmarks/](./benchmarks/): Benchmarks. A work in progress.
|
||||
* [test/](./test/): A dusty attic of minimal testing.
|
||||
|
||||
## To do
|
||||
## Status and roadmap
|
||||
|
||||
### Missing features before Guile can use Whippet
|
||||
As of September 2024, Whippet is almost feature-complete. The main
|
||||
missing feature is dynamic heap growth and shrinkage
|
||||
(https://github.com/wingo/whippet/issues/5), which should land soon.
|
||||
|
||||
- [X] Pinning
|
||||
- [X] Conservative stacks
|
||||
- [X] Conservative data segments
|
||||
- [ ] Heap growth/shrinking
|
||||
- [ ] Debugging/tracing
|
||||
- [X] Finalizers
|
||||
- [X] Weak references / weak maps
|
||||
After that, the next phase on the roadmap is support for tracing, and
|
||||
some performance noodling.
|
||||
|
||||
### Features that would improve Whippet performance
|
||||
|
||||
- [X] Immix-style opportunistic evacuation
|
||||
- ~~[ ] Overflow allocation~~ (should just evacuate instead)
|
||||
- [X] Generational GC via sticky mark bits
|
||||
- [ ] Generational GC with semi-space nursery
|
||||
- [ ] Concurrent marking with SATB barrier
|
||||
Once that is done, the big task is integrating Whippet into the [Guile
|
||||
Scheme](https://gnu.org/s/guile) language run-time, replacing BDW-GC.
|
||||
Fingers crossed!
|
||||
|
||||
## About the name
|
||||
|
||||
It sounds better than WIP (work-in-progress) garbage collector, doesn't
|
||||
it? Also apparently a whippet is a kind of dog that is fast for its
|
||||
size. It would be nice if whippet-gc turns out to have this property.
|
||||
size. It would be nice if the Whippet collectors turn out to have this
|
||||
property.
|
||||
|
||||
## License
|
||||
|
||||
```
|
||||
Copyright (c) 2022-2023 Andy Wingo
|
||||
Copyright (c) 2022-2024 Andy Wingo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef WHIPPET_ATTRS_H
|
||||
#define WHIPPET_ATTRS_H
|
||||
#ifndef MMC_ATTRS_H
|
||||
#define MMC_ATTRS_H
|
||||
|
||||
#include "gc-config.h"
|
||||
#include "gc-assert.h"
|
||||
|
@ -61,4 +61,4 @@ static inline enum gc_safepoint_mechanism gc_safepoint_mechanism(void) {
|
|||
return GC_SAFEPOINT_MECHANISM_COOPERATIVE;
|
||||
}
|
||||
|
||||
#endif // WHIPPET_ATTRS_H
|
||||
#endif // MMC_ATTRS_H
|
|
@ -7,14 +7,14 @@
|
|||
threads. We analytically compute the peak amount of live data and
|
||||
then size the GC heap as a multiplier of that size. It has a peak
|
||||
heap consumption of 10 MB or so per mutator thread: not very large.
|
||||
At a 2x heap multiplier, it causes about 30 collections for the
|
||||
whippet collector, and runs somewhere around 200-400 milliseconds in
|
||||
At a 2x heap multiplier, it causes about 30 collections for the `mmc`
|
||||
collector, and runs somewhere around 200-400 milliseconds in
|
||||
single-threaded mode, on the machines I have in 2022. For low thread
|
||||
counts, the GCBench benchmark is small; but then again many Guile
|
||||
processes also are quite short-lived, so perhaps it is useful to
|
||||
ensure that small heaps remain lightweight.
|
||||
|
||||
To stress Whippet's handling of fragmentation, we modified this
|
||||
To stress `mmc`'s handling of fragmentation, we modified this
|
||||
benchmark to intersperse pseudorandomly-sized holes between tree
|
||||
nodes.
|
||||
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
# Whippet collector
|
||||
# Mostly-copying collector
|
||||
|
||||
One collector implementation in the Whippet garbage collection library
|
||||
is also called Whippet. Naming-wise this is a somewhat confusing
|
||||
situation; perhaps it will change.
|
||||
|
||||
Anyway, the `whippet` collector is mainly a mark-region collector,
|
||||
inspired by
|
||||
The `mmc` collector is mainly a mark-region collector, inspired by
|
||||
[Immix](http://users.cecs.anu.edu.au/~steveb/pubs/papers/immix-pldi-2008.pdf).
|
||||
To a first approximation, Whippet is a whole-heap Immix collector with a
|
||||
To a first approximation, `mmc` is a whole-heap Immix collector with a
|
||||
large object space on the side.
|
||||
|
||||
When tracing, `whippet` mostly marks objects in place. If the heap is
|
||||
When tracing, `mmc` mostly marks objects in place. If the heap is
|
||||
too fragmented, it can compact the heap by choosing to evacuate
|
||||
sparsely-populated heap blocks instead of marking in place. However
|
||||
evacuation is strictly optional, which means that `whippet` is also
|
||||
evacuation is strictly optional, which means that `mmc` is also
|
||||
compatible with conservative root-finding, making it a good replacement
|
||||
for embedders that currently use the [Boehm-Demers-Weiser
|
||||
collector](./collector-bdw.md).
|
||||
|
@ -33,7 +28,7 @@ recycled block from the global block store, it allocates into those
|
|||
holes. For an exposition of Immix, see the lovely detailed [Rust
|
||||
implementation](http://users.cecs.anu.edu.au/~steveb/pubs/papers/rust-ismm-2016.pdf).
|
||||
|
||||
The essential difference of `whippet` from Immix stems from a simple
|
||||
The essential difference of `mmc` from Immix stems from a simple
|
||||
observation: Immix needs a side table of line mark bytes and also a mark
|
||||
bit or bits in each object (or in a side table). But if instead you
|
||||
choose to store mark bytes instead of bits (for concurrency reasons) in
|
||||
|
@ -54,13 +49,13 @@ just read the mark table and can avoid looking at object memory.
|
|||
|
||||
## Optional features
|
||||
|
||||
The `whippet` collector has a few feature flags that can be turned on or
|
||||
The `mmc` collector has a few feature flags that can be turned on or
|
||||
off. If you use the [standard embedder makefile include](../embed.mk),
|
||||
then there is a name for each combination of features: `whippet` has no
|
||||
additional features, `parallel-whippet` enables parallel marking,
|
||||
`parallel-generational-whippet` enables generations,
|
||||
`stack-conservative-parallel-generational-whippet` uses conservative
|
||||
root-finding, and `heap-conservative-parallel-generational-whippet`
|
||||
then there is a name for each combination of features: `mmc` has no
|
||||
additional features, `parallel-mmc` enables parallel marking,
|
||||
`parallel-generational-mmc` enables generations,
|
||||
`stack-conservative-parallel-generational-mmc` uses conservative
|
||||
root-finding, and `heap-conservative-parallel-generational-mmc`
|
||||
additionally traces the heap conservatively. You can leave off
|
||||
components of the name to get a collector without those features.
|
||||
Underneath this corresponds to some pre-processor definitions passed to
|
||||
|
@ -68,7 +63,7 @@ the compiler on the command line.
|
|||
|
||||
### Generations
|
||||
|
||||
Whippet supports generational tracing via the [sticky mark-bit
|
||||
`mmc` supports generational tracing via the [sticky mark-bit
|
||||
algorithm](https://wingolog.org/archives/2022/10/22/the-sticky-mark-bit-algorithm).
|
||||
This requires that the embedder emit [write
|
||||
barriers](https://github.com/wingo/whippet/blob/main/doc/manual.md#write-barriers);
|
||||
|
@ -84,7 +79,7 @@ two-megabyte aligned slabs.
|
|||
|
||||
### Parallel tracing
|
||||
|
||||
You almost certainly want this on! `parallel-whippet` uses a the
|
||||
You almost certainly want this on! `parallel-mmc` uses a the
|
||||
[fine-grained work-stealing parallel tracer](../src/parallel-tracer.h).
|
||||
Each trace worker maintains a [local queue of objects that need
|
||||
tracing](../src/local-worklist.h), which currently has a capacity of
|
||||
|
@ -96,17 +91,17 @@ then will try to steal from other workers.
|
|||
|
||||
The memory used for the external worklist is dynamically allocated from
|
||||
the OS and is not currently counted as contributing to the heap size.
|
||||
If you absolutely need to avoid dynamic allocation during GC, `whippet`
|
||||
(even serial whippet) would need some work for your use case, to
|
||||
allocate a fixed-size space for a marking queue and to gracefully handle
|
||||
mark queue overflow.
|
||||
If you absolutely need to avoid dynamic allocation during GC, `mmc`
|
||||
(even `serial-mmc`) would need some work for your use case, to allocate
|
||||
a fixed-size space for a marking queue and to gracefully handle mark
|
||||
queue overflow.
|
||||
|
||||
### Conservative stack scanning
|
||||
|
||||
With `semi` and `pcc`, embedders must precisely enumerate the set of
|
||||
*roots*: the edges into the heap from outside. Commonly, roots include
|
||||
global variables, as well as working variables from each mutator's
|
||||
stack. Whippet can optionally mark mutator stacks *conservatively*:
|
||||
stack. `mmc` can optionally mark mutator stacks *conservatively*:
|
||||
treating each word on the stack as if it may be an object reference, and
|
||||
marking any object at that address.
|
||||
|
||||
|
@ -124,7 +119,7 @@ place roots in traceable locations published to the garbage collector.
|
|||
And the [performance question is still
|
||||
open](https://dl.acm.org/doi/10.1145/2660193.2660198).
|
||||
|
||||
Anyway. Whippet can scan roots conservatively. Those roots are pinned
|
||||
Anyway. `mmc` can scan roots conservatively. Those roots are pinned
|
||||
for the collection; even if the collection will compact via evacuation,
|
||||
referents of conservative roots won't be moved. Objects not directly
|
||||
referenced by roots can be evacuated, however.
|
||||
|
@ -133,14 +128,14 @@ referenced by roots can be evacuated, however.
|
|||
|
||||
In addition to stack and global references, the Boehm-Demers-Weiser
|
||||
collector scans heap objects conservatively as well, treating each word
|
||||
of each heap object as if it were a reference. Whippet can do that, if
|
||||
of each heap object as if it were a reference. `mmc` can do that, if
|
||||
the embedder is unable to provide a `gc_trace_object` implementation.
|
||||
However this is generally a performance lose, and it prevents
|
||||
evacuation.
|
||||
|
||||
## Other implementation tidbits
|
||||
|
||||
`whippet` does lazy sweeping: as a mutator grabs a fresh block, it
|
||||
`mmc` does lazy sweeping: as a mutator grabs a fresh block, it
|
||||
reclaims memory that was unmarked in the previous collection before
|
||||
making the memory available for allocation. This makes sweeping
|
||||
naturally cache-friendly and parallel.
|
|
@ -7,7 +7,7 @@ Whippet has five collectors currently:
|
|||
but with support for multiple mutator threads.
|
||||
- [Parallel copying collector (`pcc`)](./collector-pcc.md): Like `scc`,
|
||||
but with support for multiple tracing threads.
|
||||
- [Whippet collector (`whippet`)](./collector-whippet.md):
|
||||
- [Mostly marking collector (`mmc`)](./collector-mmc.md):
|
||||
Immix-inspired collector. Optionally parallel, conservative (stack
|
||||
and/or heap), and/or generational.
|
||||
- [Boehm-Demers-Weiser collector (`bdw`)](./collector-bdw.md):
|
||||
|
@ -17,11 +17,11 @@ Whippet has five collectors currently:
|
|||
## How to choose?
|
||||
|
||||
If you are migrating an embedder off BDW-GC, then it could be reasonable
|
||||
to first go to `bdw`, then `stack-conservative-parallel-whippet`.
|
||||
to first go to `bdw`, then `stack-conservative-parallel-mmc`.
|
||||
|
||||
If you have an embedder with precise roots, use `pcc`. That will shake
|
||||
out mutator/embedder bugs. Then if memory is tight, switch to
|
||||
`parallel-whippet`, possibly `parallel-generational-whippet`.
|
||||
`parallel-mmc`, possibly `parallel-generational-mmc`.
|
||||
|
||||
If you are aiming for maximum simplicity and minimal code size (ten
|
||||
kilobytes or so), use `semi`.
|
||||
|
@ -30,17 +30,16 @@ Only use `scc` if you are investigating GC internals.
|
|||
|
||||
If you are writing a new project, you have a choice as to whether to pay
|
||||
the development cost of precise roots or not. If you choose to not have
|
||||
precise roots, then go for `stack-conservative-parallel-whippet`
|
||||
directly.
|
||||
precise roots, then go for `stack-conservative-parallel-mmc` directly.
|
||||
|
||||
## More collectors
|
||||
|
||||
It would be nice to have a classic generational GC, perhaps using
|
||||
parallel-whippet for the old generation but a pcc-style copying nursery.
|
||||
`parallel-mmc` for the old generation but a pcc-style copying nursery.
|
||||
|
||||
Support for concurrent marking in `whippet` would be good as well,
|
||||
perhaps with a SATB barrier. (Or, if you are the sort of person to bet
|
||||
on conservative stack scanning, perhaps a retreating-wavefront barrier
|
||||
Support for concurrent marking in `mmc` would be good as well, perhaps
|
||||
with a SATB barrier. (Or, if you are the sort of person to bet on
|
||||
conservative stack scanning, perhaps a retreating-wavefront barrier
|
||||
would be more appropriate.)
|
||||
|
||||
Contributions are welcome, provided they have no more dependencies!
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Whippet and Guile
|
||||
|
||||
If the Whippet collector works out, it could replace Guile's garbage
|
||||
If the `mmc` collector works out, it could replace Guile's garbage
|
||||
collector. Guile currently uses BDW-GC. Guile has a widely used C API
|
||||
and implements part of its run-time in C. For this reason it may be
|
||||
infeasible to require precise enumeration of GC roots -- we may need to
|
||||
|
|
|
@ -21,7 +21,7 @@ for full details, but for a cheat sheet, you might do something like
|
|||
this to copy Whippet into the `whippet/` directory of your project root:
|
||||
|
||||
```
|
||||
git remote add whippet https://github.com/wingo/whippet-gc
|
||||
git remote add whippet https://github.com/wingo/whippet
|
||||
git fetch whippet
|
||||
git merge -s ours --no-commit --allow-unrelated-histories whippet/main
|
||||
git read-tree --prefix=whippet/ -u whippet/main
|
||||
|
@ -92,7 +92,7 @@ that all "large" or potentially large objects have a flag bit reserved
|
|||
for use of the garbage collector. A large object is one whose size
|
||||
exceeds the `gc_allocator_large_threshold()` (see
|
||||
[`gc-attrs.h`](../api/gc-attrs.h)), which is a collector-specific value.
|
||||
Currently the only generational collector is the in-place Whippet
|
||||
Currently the only generational collector is the in-place `mmc`
|
||||
collector, whose large object threshold is 4096 bytes. The
|
||||
`gc_object_set_remembered`, `gc_object_is_remembered_nonatomic`, and
|
||||
`gc_object_clear_remembered_nonatomic` embedder functions manage the
|
||||
|
@ -187,15 +187,10 @@ implementations of that API: `semi`, a simple semi-space collector;
|
|||
`pcc`, a parallel copying collector (like semi but multithreaded);
|
||||
`bdw`, an implementation via the third-party
|
||||
[Boehm-Demers-Weiser](https://github.com/ivmai/bdwgc) conservative
|
||||
collector; and `whippet`, an Immix-like collector.
|
||||
|
||||
There is a bit of name overloading between the Whippet abstract API, the
|
||||
collection of GC implementations, and the specific Whippet collector;
|
||||
our apologies. It's just like that, and we hope to make the usage
|
||||
obvious from context.
|
||||
collector; and `mmc`, a mostly-marking collector inspired by Immix.
|
||||
|
||||
The program that embeds Whippet selects the collector implementation at
|
||||
build-time. In the case of the specific Whippet collector, the program
|
||||
build-time. In the case of the `mmc` collector, the program
|
||||
also configures a specific collector mode, again at build-time:
|
||||
generational or not, parallel or not, stack-conservative or not, and
|
||||
heap-conservative or not. It may be nice in the future to be able to
|
||||
|
@ -353,15 +348,26 @@ $(COMPILE) -DGC_CONSERVATIVE_ROOTS=1 -DGC_CONSERVATIVE_TRACE=1 \
|
|||
-include foo-embedder.h -o gc.o -c bdw.c
|
||||
```
|
||||
|
||||
#### Building `whippet`
|
||||
#### Building `pcc`
|
||||
|
||||
Finally, there is the whippet collector. It can collect roots precisely
|
||||
or conservatively, trace precisely or conservatively, be parallel or
|
||||
not, and be generational or not.
|
||||
The parallel copying collector is like `semi` but better in every way:
|
||||
it supports multiple mutator threads, and evacuates in parallel if
|
||||
multiple threads are available.
|
||||
|
||||
```
|
||||
$(COMPILE) -DGC_PARALLEL=1 -DGC_PRECISE_ROOTS=1 \
|
||||
-include foo-embedder.h -o gc.o -c pcc.c
|
||||
```
|
||||
|
||||
#### Building `mmc`
|
||||
|
||||
Finally, there is the mostly-marking collector. It can collect roots
|
||||
precisely or conservatively, trace precisely or conservatively, be
|
||||
parallel or not, and be generational or not.
|
||||
|
||||
```
|
||||
$(COMPILE) -DGC_PARALLEL=1 -DGC_GENERATIONAL=1 -DGC_PRECISE_ROOTS=1 \
|
||||
-include foo-embedder.h -o gc.o -c whippet.c
|
||||
-include foo-embedder.h -o gc.o -c mvv.c
|
||||
```
|
||||
|
||||
### Compiling your program
|
||||
|
@ -370,12 +376,12 @@ Any compilation unit that uses the GC API should have the same set of
|
|||
compile-time options defined as when compiling the collector.
|
||||
Additionally those compilation units should include the "attributes"
|
||||
header for the collector in question, namely `semi-attrs.h`,
|
||||
`bdw-attrs.h`, or `whippet-attrs.h`. For example, for parallel
|
||||
generational whippet, you might have:
|
||||
`bdw-attrs.h`, `pcc-attrs.h`, or `mmc-attrs.h`. For example, for
|
||||
parallel generational mmc, you might have:
|
||||
|
||||
```
|
||||
$(COMPILE) -DGC_PARALLEL=1 -DGC_GENERATIONAL=1 -DGC_PRECISE_ROOTS=1 \
|
||||
-include whippet-attrs.h -o my-program.o -c my-program.c
|
||||
-include mmc-attrs.h -o my-program.o -c my-program.c
|
||||
```
|
||||
|
||||
### Linking the collector into your program
|
||||
|
@ -462,7 +468,7 @@ defined for all collectors:
|
|||
|
||||
You can set these options via `gc_option_set_int` and so on; see
|
||||
[`gc-options.h`](../api/gc-options.h). Or, you can parse options from
|
||||
strings: `heap-size-policy`, `heap-size`, `maximum-heap-size`, and so
|
||||
trings: `heap-size-policy`, `heap-size`, `maximum-heap-size`, and so
|
||||
on. Use `gc_option_from_string` to determine if a string is really an
|
||||
option. Use `gc_option_parse_and_set` to parse a value for an option.
|
||||
Use `gc_options_parse_and_set_many` to parse a number of comma-delimited
|
||||
|
|
26
embed.mk
26
embed.mk
|
@ -48,28 +48,28 @@ GC_CFLAGS_scc = -DGC_PRECISE_ROOTS=1
|
|||
GC_STEM_pcc = pcc
|
||||
GC_CFLAGS_pcc = -DGC_PRECISE_ROOTS=1 -DGC_PARALLEL=1
|
||||
|
||||
define whippet_variant
|
||||
GC_STEM_$(1) = whippet
|
||||
define mmc_variant
|
||||
GC_STEM_$(1) = mmc
|
||||
GC_CFLAGS_$(1) = $(2)
|
||||
endef
|
||||
|
||||
define generational_whippet_variants
|
||||
$(call whippet_variant,$(1)whippet,$(2))
|
||||
$(call whippet_variant,$(1)generational_whippet,$(2) -DGC_GENERATIONAL=1)
|
||||
define generational_mmc_variants
|
||||
$(call mmc_variant,$(1)mmc,$(2))
|
||||
$(call mmc_variant,$(1)generational_mmc,$(2) -DGC_GENERATIONAL=1)
|
||||
endef
|
||||
|
||||
define parallel_whippet_variants
|
||||
$(call generational_whippet_variants,$(1),$(2))
|
||||
$(call generational_whippet_variants,$(1)parallel_,$(2) -DGC_PARALLEL=1)
|
||||
define parallel_mmc_variants
|
||||
$(call generational_mmc_variants,$(1),$(2))
|
||||
$(call generational_mmc_variants,$(1)parallel_,$(2) -DGC_PARALLEL=1)
|
||||
endef
|
||||
|
||||
define trace_whippet_variants
|
||||
$(call parallel_whippet_variants,,-DGC_PRECISE_ROOTS=1)
|
||||
$(call parallel_whippet_variants,stack_conservative_,-DGC_CONSERVATIVE_ROOTS=1)
|
||||
$(call parallel_whippet_variants,heap_conservative_,-DGC_CONSERVATIVE_ROOTS=1 -DGC_CONSERVATIVE_TRACE=1)
|
||||
define trace_mmc_variants
|
||||
$(call parallel_mmc_variants,,-DGC_PRECISE_ROOTS=1)
|
||||
$(call parallel_mmc_variants,stack_conservative_,-DGC_CONSERVATIVE_ROOTS=1)
|
||||
$(call parallel_mmc_variants,heap_conservative_,-DGC_CONSERVATIVE_ROOTS=1 -DGC_CONSERVATIVE_TRACE=1)
|
||||
endef
|
||||
|
||||
$(eval $(call trace_whippet_variants))
|
||||
$(eval $(call trace_mmc_variants))
|
||||
|
||||
gc_var = $($(1)$(subst -,_,$(2)))
|
||||
gc_impl = $(call gc_var,GC_STEM_,$(1)).c
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "serial-tracer.h"
|
||||
#endif
|
||||
#include "spin.h"
|
||||
#include "whippet-attrs.h"
|
||||
#include "mmc-attrs.h"
|
||||
|
||||
#define LARGE_OBJECT_THRESHOLD 8192
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue