@@ -100,16 +100,16 @@ impl SFT for EmptySpaceSFT {
100
100
}
101
101
102
102
#[ 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 ) > ,
105
105
}
106
106
107
107
// 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 > { }
109
109
110
110
static EMPTY_SPACE_SFT : EmptySpaceSFT = EmptySpaceSFT { } ;
111
111
112
- impl SFTMap {
112
+ impl < ' a > SFTMap < ' a > {
113
113
pub fn new ( ) -> Self {
114
114
SFTMap {
115
115
sft : vec ! [ & EMPTY_SPACE_SFT ; MAX_CHUNKS ] ,
@@ -124,28 +124,23 @@ impl SFTMap {
124
124
& mut * ( self as * const _ as * mut _ )
125
125
}
126
126
127
- pub fn get ( & self , address : Address ) -> & ' static dyn SFT {
127
+ pub fn get ( & self , address : Address ) -> & ' a dyn SFT {
128
128
let res = self . sft [ address. chunk_index ( ) ] ;
129
129
if DEBUG_SFT {
130
130
trace ! (
131
131
"Get SFT for {} #{} = {}" ,
132
132
address,
133
133
address. chunk_index( ) ,
134
- unsafe { & ( * res) } . name( )
134
+ res. name( )
135
135
) ;
136
136
}
137
- unsafe { & ( * res) }
137
+ res
138
138
}
139
139
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 ) {
141
141
let first = start. chunk_index ( ) ;
142
142
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( ) ) ;
149
144
let start_chunk = chunk_index_to_address ( first) ;
150
145
let end_chunk = chunk_index_to_address ( first + chunks) ;
151
146
debug ! (
@@ -170,18 +165,15 @@ impl SFTMap {
170
165
i + SPACE_PER_LINE
171
166
} ;
172
167
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 ( ) ;
177
169
trace ! ( "Chunk {}: {}" , i, space_names. join( "," ) ) ;
178
170
}
179
171
}
180
172
}
181
173
182
174
/// Update SFT map for the given address range.
183
175
/// 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 ) {
185
177
if DEBUG_SFT {
186
178
self . log_update ( space, start, chunks) ;
187
179
}
@@ -198,7 +190,7 @@ impl SFTMap {
198
190
self . set ( chunk_idx, & EMPTY_SPACE_SFT ) ;
199
191
}
200
192
201
- fn set ( & self , chunk : usize , sft : * const ( dyn SFT + Sync ) ) {
193
+ fn set ( & self , chunk : usize , sft : & ( dyn SFT + Sync + ' static ) ) {
202
194
/*
203
195
* This is safe (only) because a) this is only called during the
204
196
* allocation and deallocation of chunks, which happens under a global
@@ -208,11 +200,11 @@ impl SFTMap {
208
200
* which are reasonable), and in the other case it would either see the
209
201
* old (valid) space or an empty space, both of which are valid.
210
202
*/
211
- let self_mut: & mut Self = unsafe { self . mut_self ( ) } ;
203
+ let self_mut = unsafe { self . mut_self ( ) } ;
212
204
// 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.
213
205
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 ( ) ;
216
208
// 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,
217
209
// in which case, we still set SFT map again.
218
210
debug_assert ! (
@@ -342,7 +334,7 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
342
334
) ;
343
335
if new_chunk {
344
336
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) ;
346
338
}
347
339
}
348
340
@@ -361,11 +353,7 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
361
353
// TODO(Javad): handle meta space allocation failure
362
354
panic ! ( "failed to mmap meta memory" ) ;
363
355
}
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) ;
369
357
use crate :: util:: heap:: layout:: mmapper:: Mmapper ;
370
358
self . common ( )
371
359
. mmapper
0 commit comments