Skip to content

Commit 5906d0d

Browse files
qinsoonJavad Amiri
and
Javad Amiri
authored
Change sft from pointers to static refs (#303)
Co-authored-by: Javad Amiri <[email protected]>
1 parent 45c6a9b commit 5906d0d

File tree

2 files changed

+19
-31
lines changed

2 files changed

+19
-31
lines changed

src/mmtk.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ lazy_static! {
2626
// TODO: We should refactor this when we know more about how multiple MMTK instances work.
2727
pub static ref VM_MAP: VMMap = VMMap::new();
2828
pub static ref MMAPPER: Mmapper = Mmapper::new();
29-
pub static ref SFT_MAP: SFTMap = SFTMap::new();
29+
pub static ref SFT_MAP: SFTMap<'static> = SFTMap::new();
3030
}
3131

3232
/// An MMTk instance. MMTk allows mutiple instances to run independently, and each instance gives users a separate heap.
@@ -35,7 +35,7 @@ pub struct MMTK<VM: VMBinding> {
3535
pub plan: Box<dyn Plan<VM = VM>>,
3636
pub vm_map: &'static VMMap,
3737
pub mmapper: &'static Mmapper,
38-
pub sftmap: &'static SFTMap,
38+
pub sftmap: &'static SFTMap<'static>,
3939
pub reference_processors: ReferenceProcessors,
4040
pub finalizable_processor: Mutex<FinalizableProcessor>,
4141
pub options: Arc<UnsafeOptionsWrapper>,

src/policy/space.rs

+17-29
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,16 @@ impl SFT for EmptySpaceSFT {
100100
}
101101

102102
#[derive(Default)]
103-
pub struct SFTMap {
104-
sft: Vec<*const (dyn SFT + Sync)>,
103+
pub struct SFTMap<'a> {
104+
sft: Vec<&'a (dyn SFT + Sync + 'static)>,
105105
}
106106

107107
// TODO: MMTK<VM> holds a reference to SFTMap. We should have a safe implementation rather than use raw pointers for dyn SFT.
108-
unsafe impl Sync for SFTMap {}
108+
unsafe impl<'a> Sync for SFTMap<'a> {}
109109

110110
static EMPTY_SPACE_SFT: EmptySpaceSFT = EmptySpaceSFT {};
111111

112-
impl SFTMap {
112+
impl<'a> SFTMap<'a> {
113113
pub fn new() -> Self {
114114
SFTMap {
115115
sft: vec![&EMPTY_SPACE_SFT; MAX_CHUNKS],
@@ -124,28 +124,23 @@ impl SFTMap {
124124
&mut *(self as *const _ as *mut _)
125125
}
126126

127-
pub fn get(&self, address: Address) -> &'static dyn SFT {
127+
pub fn get(&self, address: Address) -> &'a dyn SFT {
128128
let res = self.sft[address.chunk_index()];
129129
if DEBUG_SFT {
130130
trace!(
131131
"Get SFT for {} #{} = {}",
132132
address,
133133
address.chunk_index(),
134-
unsafe { &(*res) }.name()
134+
res.name()
135135
);
136136
}
137-
unsafe { &(*res) }
137+
res
138138
}
139139

140-
fn log_update(&self, space: *const (dyn SFT + Sync), start: Address, chunks: usize) {
140+
fn log_update(&self, space: &(dyn SFT + Sync + 'static), start: Address, chunks: usize) {
141141
let first = start.chunk_index();
142142
let end = start + (chunks << LOG_BYTES_IN_CHUNK);
143-
debug!(
144-
"Update SFT for [{}, {}) as {}",
145-
start,
146-
end,
147-
unsafe { &(*space) }.name()
148-
);
143+
debug!("Update SFT for [{}, {}) as {}", start, end, space.name());
149144
let start_chunk = chunk_index_to_address(first);
150145
let end_chunk = chunk_index_to_address(first + chunks);
151146
debug!(
@@ -170,18 +165,15 @@ impl SFTMap {
170165
i + SPACE_PER_LINE
171166
};
172167
let chunks: Vec<usize> = (i..max).collect();
173-
let space_names: Vec<&str> = chunks
174-
.iter()
175-
.map(|&x| unsafe { &*self.sft[x] }.name())
176-
.collect();
168+
let space_names: Vec<&str> = chunks.iter().map(|&x| self.sft[x].name()).collect();
177169
trace!("Chunk {}: {}", i, space_names.join(","));
178170
}
179171
}
180172
}
181173

182174
/// Update SFT map for the given address range.
183175
/// It should be used in these cases: 1. when a space grows, 2. when initializing a contiguous space, 3. when ensure_mapped() is called on a space.
184-
pub fn update(&self, space: *const (dyn SFT + Sync), start: Address, chunks: usize) {
176+
pub fn update(&self, space: &(dyn SFT + Sync + 'static), start: Address, chunks: usize) {
185177
if DEBUG_SFT {
186178
self.log_update(space, start, chunks);
187179
}
@@ -198,7 +190,7 @@ impl SFTMap {
198190
self.set(chunk_idx, &EMPTY_SPACE_SFT);
199191
}
200192

201-
fn set(&self, chunk: usize, sft: *const (dyn SFT + Sync)) {
193+
fn set(&self, chunk: usize, sft: &(dyn SFT + Sync + 'static)) {
202194
/*
203195
* This is safe (only) because a) this is only called during the
204196
* allocation and deallocation of chunks, which happens under a global
@@ -208,11 +200,11 @@ impl SFTMap {
208200
* which are reasonable), and in the other case it would either see the
209201
* old (valid) space or an empty space, both of which are valid.
210202
*/
211-
let self_mut: &mut Self = unsafe { self.mut_self() };
203+
let self_mut = unsafe { self.mut_self() };
212204
// It is okay to set empty to valid, or set valid to empty. It is wrong if we overwrite a valid value with another valid value.
213205
if cfg!(debug_assertions) {
214-
let old = unsafe { self_mut.sft[chunk].as_ref() }.unwrap().name();
215-
let new = unsafe { sft.as_ref() }.unwrap().name();
206+
let old = self_mut.sft[chunk].name();
207+
let new = sft.name();
216208
// Allow overwriting the same SFT pointer. E.g., if we have set SFT map for a space, then ensure_mapped() is called on the same,
217209
// in which case, we still set SFT map again.
218210
debug_assert!(
@@ -342,7 +334,7 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
342334
);
343335
if new_chunk {
344336
let chunks = conversions::bytes_to_chunks_up(bytes);
345-
SFT_MAP.update(self.as_sft() as *const (dyn SFT + Sync), start, chunks);
337+
SFT_MAP.update(self.as_sft(), start, chunks);
346338
}
347339
}
348340

@@ -361,11 +353,7 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
361353
// TODO(Javad): handle meta space allocation failure
362354
panic!("failed to mmap meta memory");
363355
}
364-
SFT_MAP.update(
365-
self.as_sft() as *const (dyn SFT + Sync),
366-
self.common().start,
367-
chunks,
368-
);
356+
SFT_MAP.update(self.as_sft(), self.common().start, chunks);
369357
use crate::util::heap::layout::mmapper::Mmapper;
370358
self.common()
371359
.mmapper

0 commit comments

Comments
 (0)