Skip to content

Commit 70896de

Browse files
committed
Rename macro with a mmtk prefix. Move macro impl to a separate module.
1 parent 74a71de commit 70896de

File tree

13 files changed

+148
-142
lines changed

13 files changed

+148
-142
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ crate-type = ["rlib"]
1818
doctest = false
1919

2020
[dependencies]
21-
macro-trace-object = { path = "macros/trace_object"}
21+
# MMTk macros
22+
mmtk-macro-trace-object = { path = "macros/trace_object"}
2223

2324
custom_derive = "0.1"
2425
enum_derive = "0.1"

macros/trace_object/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "macro-trace-object"
2+
name = "mmtk-macro-trace-object"
33
version = "0.1.0"
44
edition = "2021"
55

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use quote::quote;
2+
use syn::{Field, TypeGenerics};
3+
use proc_macro2::TokenStream as TokenStream2;
4+
5+
use crate::util;
6+
7+
pub fn generate_trace_object<'a>(
8+
space_fields: &[&'a Field],
9+
parent_field: &Option<&'a Field>,
10+
ty_generics: &TypeGenerics,
11+
) -> TokenStream2 {
12+
// Generate a check with early return for each space
13+
let space_field_handler = space_fields.iter().map(|f| {
14+
let f_ident = f.ident.as_ref().unwrap();
15+
let ref f_ty = f.ty;
16+
17+
// Figure out copy
18+
let trace_attr = util::get_field_attribute(f, "trace").unwrap();
19+
let copy = if !trace_attr.tokens.is_empty() {
20+
use syn::Token;
21+
use syn::NestedMeta;
22+
use syn::punctuated::Punctuated;
23+
24+
let args = trace_attr.parse_args_with(Punctuated::<NestedMeta, Token![,]>::parse_terminated).unwrap();
25+
// CopySemantics::X is a path.
26+
if let Some(NestedMeta::Meta(syn::Meta::Path(p))) = args.first() {
27+
quote!{ Some(#p) }
28+
} else {
29+
quote!{ None }
30+
}
31+
} else {
32+
quote!{ None }
33+
};
34+
35+
quote! {
36+
if self.#f_ident.in_space(__mmtk_objref) {
37+
return <#f_ty as PolicyTraceObject #ty_generics>::trace_object::<T, KIND>(&self.#f_ident, __mmtk_trace, __mmtk_objref, #copy, __mmtk_worker);
38+
}
39+
}
40+
});
41+
42+
// Generate a fallback to the parent plan
43+
let parent_field_delegator = if let Some(f) = parent_field {
44+
let f_ident = f.ident.as_ref().unwrap();
45+
let ref f_ty = f.ty;
46+
quote! {
47+
<#f_ty as PlanTraceObject #ty_generics>::trace_object::<T, KIND>(&self.#f_ident, __mmtk_trace, __mmtk_objref, __mmtk_worker)
48+
}
49+
} else {
50+
quote! {
51+
panic!("No more spaces to try")
52+
}
53+
};
54+
55+
quote! {
56+
fn trace_object<T: crate::plan::TransitiveClosure, const KIND: crate::policy::gc_work::TraceKind>(&self, __mmtk_trace: &mut T, __mmtk_objref: crate::util::ObjectReference, __mmtk_worker: &mut crate::scheduler::GCWorker<VM>) -> crate::util::ObjectReference {
57+
use crate::policy::space::Space;
58+
use crate::policy::gc_work::PolicyTraceObject;
59+
use crate::plan::transitive_closure::PlanTraceObject;
60+
#(#space_field_handler)*
61+
#parent_field_delegator
62+
}
63+
}
64+
}
65+
66+
pub fn generate_scan_object<'a>(
67+
scan_object_fields: &[&'a Field],
68+
ty_generics: &TypeGenerics,
69+
) -> TokenStream2 {
70+
let scan_field_handler = scan_object_fields.iter().map(|f| {
71+
let f_ident = f.ident.as_ref().unwrap();
72+
let ref f_ty = f.ty;
73+
74+
quote! {
75+
if self.#f_ident.in_space(__mmtk_objref) {
76+
use crate::policy::gc_work::PolicyTraceObject;
77+
<#f_ty as PolicyTraceObject #ty_generics>::scan_object::<EV>(&self.#f_ident, __mmtk_worker_tls, __mmtk_objref, __mmtk_ev);
78+
return;
79+
}
80+
}
81+
});
82+
83+
quote! {
84+
fn scan_object<EV: crate::vm::EdgeVisitor>(&self, __mmtk_worker_tls: crate::util::opaque_pointer::VMWorkerThread, __mmtk_objref: crate::util::ObjectReference, __mmtk_ev: &mut EV) {
85+
use crate::vm::Scanning;
86+
87+
// Plan specific
88+
#(#scan_field_handler)*
89+
90+
// Default
91+
VM::VMScanning::scan_object(__mmtk_worker_tls, __mmtk_objref, __mmtk_ev);
92+
}
93+
}
94+
}
95+
96+
// The generated function needs to be inlined and constant folded. Otherwise, there will be a huge
97+
// performance penalty.
98+
pub fn generate_may_move_objects<'a>(
99+
space_fields: &[&'a Field],
100+
parent_field: &Option<&'a Field>,
101+
ty_generics: &TypeGenerics,
102+
) -> TokenStream2 {
103+
// If any space or the parent may move objects, the plan may move objects
104+
let space_handlers = space_fields.iter().map(|f| {
105+
let ref f_ty = f.ty;
106+
107+
quote! {
108+
|| <#f_ty as PolicyTraceObject #ty_generics>::may_move_objects::<KIND>()
109+
}
110+
});
111+
112+
let parent_handler = if let Some(p) = parent_field {
113+
let ref p_ty = p.ty;
114+
115+
quote! {
116+
|| <#p_ty as PlanTraceObject #ty_generics>::may_move_objects::<KIND>()
117+
}
118+
} else {
119+
TokenStream2::new()
120+
};
121+
122+
quote! {
123+
fn may_move_objects<const KIND: crate::policy::gc_work::TraceKind>() -> bool {
124+
use crate::policy::gc_work::PolicyTraceObject;
125+
use crate::plan::transitive_closure::PlanTraceObject;
126+
127+
false #(#space_handlers)* #parent_handler
128+
}
129+
}
130+
}

macros/trace_object/src/lib.rs

Lines changed: 6 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use proc_macro_error::proc_macro_error;
88
use syn::{parse_macro_input};
99
use proc_macro_error::abort_call_site;
1010
use quote::quote;
11-
use syn::{DeriveInput, Field, TypeGenerics};
12-
use syn::__private::TokenStream2;
11+
use syn::DeriveInput;
1312

1413
mod util;
14+
mod derive_impl;
1515

1616
/// Generally a plan needs to add these attributes in order for the macro to work:
1717
/// * add `#[derive(PlanTraceObject)]` to the plan struct.
@@ -23,7 +23,7 @@ mod util;
2323
/// * add `#[policy_scan]` to any space field that has some policy-specific scan_object(). For objects in those spaces,
2424
/// `scan_object()` in the policy will be called. For other objects, directly call `VM::VMScanning::scan_object()`.
2525
#[proc_macro_error]
26-
#[proc_macro_derive(PlanTraceObject, attributes(trace, policy_scan, copy, fallback_trace))]
26+
#[proc_macro_derive(PlanTraceObject, attributes(trace, policy_scan, fallback_trace))]
2727
pub fn derive_plan_trace_object(input: TokenStream) -> TokenStream {
2828
let input = parse_macro_input!(input as DeriveInput);
2929
let ident = input.ident;
@@ -37,9 +37,9 @@ pub fn derive_plan_trace_object(input: TokenStream) -> TokenStream {
3737
let scan_spaces = util::get_fields_with_attribute(fields, "policy_scan");
3838
let fallback = util::get_unique_field_with_attribute(fields, "fallback_trace");
3939

40-
let trace_object_function = generate_trace_object(&spaces, &fallback, &ty_generics);
41-
let scan_object_function = generate_scan_object(&scan_spaces, &ty_generics);
42-
let may_move_objects_function = generate_may_move_objects(&spaces, &fallback, &ty_generics);
40+
let trace_object_function = derive_impl::generate_trace_object(&spaces, &fallback, &ty_generics);
41+
let scan_object_function = derive_impl::generate_scan_object(&scan_spaces, &ty_generics);
42+
let may_move_objects_function = derive_impl::generate_may_move_objects(&spaces, &fallback, &ty_generics);
4343
quote!{
4444
impl #impl_generics crate::plan::transitive_closure::PlanTraceObject #ty_generics for #ident #ty_generics #where_clause {
4545
#[inline(always)]
@@ -61,128 +61,3 @@ pub fn derive_plan_trace_object(input: TokenStream) -> TokenStream {
6161

6262
output.into()
6363
}
64-
65-
fn generate_trace_object<'a>(
66-
space_fields: &[&'a Field],
67-
parent_field: &Option<&'a Field>,
68-
ty_generics: &TypeGenerics,
69-
) -> TokenStream2 {
70-
// Generate a check with early return for each space
71-
let space_field_handler = space_fields.iter().map(|f| {
72-
let f_ident = f.ident.as_ref().unwrap();
73-
let ref f_ty = f.ty;
74-
75-
// Figure out copy
76-
let trace_attr = util::get_field_attribute(f, "trace").unwrap();
77-
let copy = if !trace_attr.tokens.is_empty() {
78-
use syn::Token;
79-
use syn::NestedMeta;
80-
use syn::punctuated::Punctuated;
81-
82-
let args = trace_attr.parse_args_with(Punctuated::<NestedMeta, Token![,]>::parse_terminated).unwrap();
83-
// CopySemantics::X is a path.
84-
if let Some(NestedMeta::Meta(syn::Meta::Path(p))) = args.first() {
85-
quote!{ Some(#p) }
86-
} else {
87-
quote!{ None }
88-
}
89-
} else {
90-
quote!{ None }
91-
};
92-
93-
quote! {
94-
if self.#f_ident.in_space(__mmtk_objref) {
95-
return <#f_ty as PolicyTraceObject #ty_generics>::trace_object::<T, KIND>(&self.#f_ident, __mmtk_trace, __mmtk_objref, #copy, __mmtk_worker);
96-
}
97-
}
98-
});
99-
100-
// Generate a fallback to the parent plan
101-
let parent_field_delegator = if let Some(f) = parent_field {
102-
let f_ident = f.ident.as_ref().unwrap();
103-
let ref f_ty = f.ty;
104-
quote! {
105-
<#f_ty as PlanTraceObject #ty_generics>::trace_object::<T, KIND>(&self.#f_ident, __mmtk_trace, __mmtk_objref, __mmtk_worker)
106-
}
107-
} else {
108-
quote! {
109-
panic!("No more spaces to try")
110-
}
111-
};
112-
113-
quote! {
114-
fn trace_object<T: crate::plan::TransitiveClosure, const KIND: crate::policy::gc_work::TraceKind>(&self, __mmtk_trace: &mut T, __mmtk_objref: crate::util::ObjectReference, __mmtk_worker: &mut crate::scheduler::GCWorker<VM>) -> crate::util::ObjectReference {
115-
use crate::policy::space::Space;
116-
use crate::policy::gc_work::PolicyTraceObject;
117-
use crate::plan::transitive_closure::PlanTraceObject;
118-
#(#space_field_handler)*
119-
#parent_field_delegator
120-
}
121-
}
122-
}
123-
124-
fn generate_scan_object<'a>(
125-
scan_object_fields: &[&'a Field],
126-
ty_generics: &TypeGenerics,
127-
) -> TokenStream2 {
128-
let scan_field_handler = scan_object_fields.iter().map(|f| {
129-
let f_ident = f.ident.as_ref().unwrap();
130-
let ref f_ty = f.ty;
131-
132-
quote! {
133-
if self.#f_ident.in_space(__mmtk_objref) {
134-
use crate::policy::gc_work::PolicyTraceObject;
135-
<#f_ty as PolicyTraceObject #ty_generics>::scan_object::<EV>(&self.#f_ident, __mmtk_worker_tls, __mmtk_objref, __mmtk_ev);
136-
return;
137-
}
138-
}
139-
});
140-
141-
quote! {
142-
fn scan_object<EV: crate::vm::EdgeVisitor>(&self, __mmtk_worker_tls: crate::util::opaque_pointer::VMWorkerThread, __mmtk_objref: crate::util::ObjectReference, __mmtk_ev: &mut EV) {
143-
use crate::vm::Scanning;
144-
145-
// Plan specific
146-
#(#scan_field_handler)*
147-
148-
// Default
149-
VM::VMScanning::scan_object(__mmtk_worker_tls, __mmtk_objref, __mmtk_ev);
150-
}
151-
}
152-
}
153-
154-
// The generated function needs to be inlined and constant folded. Otherwise, there will be a huge
155-
// performance penalty.
156-
fn generate_may_move_objects<'a>(
157-
space_fields: &[&'a Field],
158-
parent_field: &Option<&'a Field>,
159-
ty_generics: &TypeGenerics,
160-
) -> TokenStream2 {
161-
// If any space or the parent may move objects, the plan may move objects
162-
let space_handlers = space_fields.iter().map(|f| {
163-
let ref f_ty = f.ty;
164-
165-
quote! {
166-
|| <#f_ty as PolicyTraceObject #ty_generics>::may_move_objects::<KIND>()
167-
}
168-
});
169-
170-
let parent_handler = if let Some(p) = parent_field {
171-
let ref p_ty = p.ty;
172-
173-
quote! {
174-
|| <#p_ty as PlanTraceObject #ty_generics>::may_move_objects::<KIND>()
175-
}
176-
} else {
177-
TokenStream2::new()
178-
};
179-
180-
quote! {
181-
fn may_move_objects<const KIND: crate::policy::gc_work::TraceKind>() -> bool {
182-
use crate::policy::gc_work::PolicyTraceObject;
183-
use crate::plan::transitive_closure::PlanTraceObject;
184-
185-
false #(#space_handlers)* #parent_handler
186-
}
187-
}
188-
}

src/plan/generational/copying/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use enum_map::EnumMap;
2626
use std::sync::atomic::{AtomicBool, Ordering};
2727
use std::sync::Arc;
2828

29-
use macro_trace_object::PlanTraceObject;
29+
use mmtk_macro_trace_object::PlanTraceObject;
3030

3131
#[derive(PlanTraceObject)]
3232
pub struct GenCopy<VM: VMBinding> {

src/plan/generational/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::sync::atomic::AtomicBool;
2121
use std::sync::atomic::Ordering;
2222
use std::sync::Arc;
2323

24-
use macro_trace_object::PlanTraceObject;
24+
use mmtk_macro_trace_object::PlanTraceObject;
2525

2626
/// Common implementation for generational plans. Each generational plan
2727
/// should include this type, and forward calls to it where possible.

src/plan/generational/immix/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::sync::atomic::AtomicBool;
2626
use std::sync::atomic::Ordering;
2727
use std::sync::Arc;
2828

29-
use macro_trace_object::PlanTraceObject;
29+
use mmtk_macro_trace_object::PlanTraceObject;
3030

3131
/// Generational immix. This implements the functionality of a two-generation copying
3232
/// collector where the higher generation is an immix space.

src/plan/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use enum_map::EnumMap;
3333
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
3434
use std::sync::{Arc, Mutex};
3535

36-
use macro_trace_object::PlanTraceObject;
36+
use mmtk_macro_trace_object::PlanTraceObject;
3737

3838
pub fn create_mutator<VM: VMBinding>(
3939
tls: VMMutatorThread,

src/plan/immix/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::sync::Arc;
2626
use atomic::Ordering;
2727
use enum_map::EnumMap;
2828

29-
use macro_trace_object::PlanTraceObject;
29+
use mmtk_macro_trace_object::PlanTraceObject;
3030

3131
#[derive(PlanTraceObject)]
3232
pub struct Immix<VM: VMBinding> {

src/plan/markcompact/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::vm::VMBinding;
3131
use enum_map::EnumMap;
3232
use std::sync::Arc;
3333

34-
use macro_trace_object::PlanTraceObject;
34+
use mmtk_macro_trace_object::PlanTraceObject;
3535

3636
#[derive(PlanTraceObject)]
3737
pub struct MarkCompact<VM: VMBinding> {

0 commit comments

Comments
 (0)