mmtk/util/erase_vm.rs
1//! MMTk uses [`crate::vm::VMBinding`], which allows us to call into bindings
2//! with little overhead. As a result, some types in MMTk are generic types with a type parameter `<VM>`.
3//! However, in some cases, using generic types is not allowed. For example, in an object-safe trait,
4//! the methods cannot be generic, thus the method's parameters cannot be generic types.
5//!
6//! This module defines macros that can be used to create a special ref type that erases the `<VM>` type parameter.
7//! For example, we create a type `TErasedRef` for `&T<VM>`. `TErasedRef` has no type parameter, and
8//! can be used in places where a type parameter is undesired. The type `TErasedRef` can be cast back to `&T<VM>`
9//! when we supply a type parameter `<VM>`. This works under the assumption that
10//! one MMTk process should only have one VM type. In such a case, when we cast from a `&T<VM>` to `TErasedRef`, and
11//! cast back to `&T<VM>`, the type parameter is guaranteed to be the same. Thus the casting is correct.
12//!
13//! `TErasedRef` has the same lifetime as `&T<VM>`.
14
15macro_rules! define_erased_vm_mut_ref {
16 ($new_type: ident = $orig_type: ty) => {
17 pub struct $new_type<'a>(usize, PhantomData<&'a ()>);
18 impl<'a> $new_type<'a> {
19 pub fn new<VM: VMBinding>(r: &'a mut $orig_type) -> Self {
20 let worker_as_usize: usize = (r as *mut $orig_type).expose_provenance();
21 Self(worker_as_usize, PhantomData)
22 }
23 pub fn into_mut<VM: VMBinding>(self) -> &'a mut $orig_type {
24 unsafe {
25 &mut *(std::ptr::with_exposed_provenance(self.0) as *const $orig_type
26 as *mut $orig_type)
27 }
28 }
29 }
30 };
31}
32
33pub(crate) use define_erased_vm_mut_ref;