@@ -5,6 +5,7 @@ use openvm_instructions::exe::SparseMemoryImage;
5
5
use openvm_stark_backend:: p3_field:: PrimeField32 ;
6
6
use serde:: { Deserialize , Serialize } ;
7
7
8
+ use super :: online:: GuestMemory ;
8
9
use crate :: arch:: MemoryConfig ;
9
10
10
11
/// (address_space, pointer)
@@ -71,6 +72,7 @@ impl<const PAGE_SIZE: usize> PagedVec<PAGE_SIZE> {
71
72
ptr:: copy_nonoverlapping ( page. as_ptr ( ) . add ( offset) , dst, len) ;
72
73
ptr:: copy_nonoverlapping ( new, page. as_mut_ptr ( ) . add ( offset) , len) ;
73
74
} else {
75
+ assert_eq ! ( start_page + 1 , end_page) ;
74
76
let offset = start % PAGE_SIZE ;
75
77
let first_part = PAGE_SIZE - offset;
76
78
{
@@ -119,11 +121,41 @@ impl<const PAGE_SIZE: usize> PagedVec<PAGE_SIZE> {
119
121
unsafe { result. assume_init ( ) }
120
122
}
121
123
124
+ /// # Panics
125
+ /// If `start..start + size_of<BLOCK>()` is out of bounds.
126
+ #[ inline( always) ]
127
+ pub fn set < BLOCK : Copy > ( & mut self , start : usize , values : & BLOCK ) {
128
+ let len = size_of :: < BLOCK > ( ) ;
129
+ let start_page = start / PAGE_SIZE ;
130
+ let end_page = ( start + len - 1 ) / PAGE_SIZE ;
131
+ let src = values as * const _ as * const u8 ;
132
+ unsafe {
133
+ if start_page == end_page {
134
+ let offset = start % PAGE_SIZE ;
135
+ let page = self . pages [ start_page] . get_or_insert_with ( || vec ! [ 0u8 ; PAGE_SIZE ] ) ;
136
+ ptr:: copy_nonoverlapping ( src, page. as_mut_ptr ( ) . add ( offset) , len) ;
137
+ } else {
138
+ assert_eq ! ( start_page + 1 , end_page) ;
139
+ let offset = start % PAGE_SIZE ;
140
+ let first_part = PAGE_SIZE - offset;
141
+ {
142
+ let page = self . pages [ start_page] . get_or_insert_with ( || vec ! [ 0u8 ; PAGE_SIZE ] ) ;
143
+ ptr:: copy_nonoverlapping ( src, page. as_mut_ptr ( ) . add ( offset) , first_part) ;
144
+ }
145
+ let second_part = len - first_part;
146
+ {
147
+ let page = self . pages [ end_page] . get_or_insert_with ( || vec ! [ 0u8 ; PAGE_SIZE ] ) ;
148
+ ptr:: copy_nonoverlapping ( src. add ( first_part) , page. as_mut_ptr ( ) , second_part) ;
149
+ }
150
+ }
151
+ }
152
+ }
153
+
122
154
/// memcpy of new `values` into pages, memcpy of old existing values into new returned value.
123
155
/// # Panics
124
156
/// If `from..from + size_of<BLOCK>()` is out of bounds.
125
157
#[ inline( always) ]
126
- pub fn set < BLOCK : Copy > ( & mut self , from : usize , values : & BLOCK ) -> BLOCK {
158
+ pub fn replace < BLOCK : Copy > ( & mut self , from : usize , values : & BLOCK ) -> BLOCK {
127
159
// Create an uninitialized array for old values.
128
160
let mut result: MaybeUninit < BLOCK > = MaybeUninit :: uninit ( ) ;
129
161
self . set_range_generic (
@@ -275,7 +307,7 @@ impl<const PAGE_SIZE: usize> AddressMap<PAGE_SIZE> {
275
307
) ;
276
308
self . paged_vecs
277
309
. get_unchecked_mut ( ( addr_space - self . as_offset ) as usize )
278
- . set ( ( ptr as usize ) * size_of :: < T > ( ) , & data)
310
+ . replace ( ( ptr as usize ) * size_of :: < T > ( ) , & data)
279
311
}
280
312
pub fn is_empty ( & self ) -> bool {
281
313
self . paged_vecs . iter ( ) . all ( |page| page. is_empty ( ) )
@@ -299,11 +331,12 @@ impl<const PAGE_SIZE: usize> AddressMap<PAGE_SIZE> {
299
331
}
300
332
}
301
333
302
- impl < const PAGE_SIZE : usize > AddressMap < PAGE_SIZE > {
303
- /// # Safety
304
- /// - `T` **must** be the correct type for a single memory cell for `addr_space`
305
- /// - Assumes `addr_space` is within the configured memory and not out of bounds
306
- pub unsafe fn get_range < T : Copy , const N : usize > ( & self , ( addr_space, ptr) : Address ) -> [ T ; N ] {
334
+ impl < const PAGE_SIZE : usize > GuestMemory for AddressMap < PAGE_SIZE > {
335
+ unsafe fn read < T : Copy , const BLOCK_SIZE : usize > (
336
+ & mut self ,
337
+ addr_space : u32 ,
338
+ ptr : u32 ,
339
+ ) -> [ T ; BLOCK_SIZE ] {
307
340
debug_assert_eq ! (
308
341
size_of:: <T >( ) ,
309
342
self . cell_size[ ( addr_space - self . as_offset) as usize ]
@@ -313,22 +346,20 @@ impl<const PAGE_SIZE: usize> AddressMap<PAGE_SIZE> {
313
346
. get ( ( ptr as usize ) * size_of :: < T > ( ) )
314
347
}
315
348
316
- /// # Safety
317
- /// - `T` **must** be the correct type for a single memory cell for `addr_space`
318
- /// - Assumes `addr_space` is within the configured memory and not out of bounds
319
- pub unsafe fn set_range < T : Copy , const N : usize > (
349
+ unsafe fn write < T : Copy , const BLOCK_SIZE : usize > (
320
350
& mut self ,
321
- ( addr_space, ptr) : Address ,
322
- values : & [ T ; N ] ,
323
- ) -> [ T ; N ] {
351
+ addr_space : u32 ,
352
+ ptr : u32 ,
353
+ values : & [ T ; BLOCK_SIZE ] ,
354
+ ) {
324
355
debug_assert_eq ! (
325
356
size_of:: <T >( ) ,
326
357
self . cell_size[ ( addr_space - self . as_offset) as usize ] ,
327
358
"addr_space={addr_space}"
328
359
) ;
329
360
self . paged_vecs
330
361
. get_unchecked_mut ( ( addr_space - self . as_offset ) as usize )
331
- . set ( ( ptr as usize ) * size_of :: < T > ( ) , values)
362
+ . set ( ( ptr as usize ) * size_of :: < T > ( ) , values) ;
332
363
}
333
364
}
334
365
0 commit comments