1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use TokenStream;
use proc_macro_error;
use parse_macro_input;
use DeriveInput;
const DEBUG_MACRO_OUTPUT: bool = false;
/// This macro will generate an implementation of `HasSpaces` for a plan or any structs that
/// contain spaces, including `Gen`, `CommonPlan` and `BasePlan`.
///
/// The `HasSpaces` trait is responsible for enumerating spaces in a struct. When using this
/// derive macro, the user should do the following.
///
/// * Make sure the struct has a generic type parameter named `VM` which requires `VMBinding`.
/// For example, `struct MyPlan<VM: VMBinding>` will work.
/// * Add `#[space]` for each space field in the struct.
/// * Add `#[parent]` to the field that contain more space fields. This attribute is usually
/// added to `Gen`, `CommonPlan` or `BasePlan` fields. There can be at most one parent in
/// a struct.
/// The macro will generate an implementation of `PlanTraceObject` for the plan. With
/// `PlanTraceObject`, the plan will be able to use `PlanTrace` for GC tracing.
///
/// The user should add `#[space]` and `#[parent]` attributes to fields as specified by the
/// `HasSpaces` trait. When using this derive macro, all spaces must implement the
/// `PolicyTraceObject` trait. The generated `trace_object` method will check for spaces in the
/// current plan and, if the object is not in any of them, check for plans in the parent struct.
/// The parent struct must also implement the `PlanTraceObject` trait.
///
/// In addition, the user can add the following attributes to fields in order to control the
/// behavior of the generated `trace_object` method.
///
/// * Add `#[copy_semantics(CopySemantics::X)]` to a space field to specify that when tracing
/// objects in that space, `Some(CopySemantics::X)` will be passed to the `Space::trace_object`
/// method as the `copy` argument.
/// * Add `#[post_scan]` to any space field that has some policy-specific `post_scan_object()`. For
/// objects in those spaces, `post_scan_object()` in the policy will be called after
/// `VM::VMScanning::scan_object()`.