@@ -63,6 +63,8 @@ pub struct MultiUseSandbox {
6363 dispatch_ptr : RawPtr ,
6464 #[ cfg( gdb) ]
6565 dbg_mem_access_fn : DbgMemAccessHandlerWrapper ,
66+ /// If the current state of the sandbox has been captured in a snapshot,
67+ /// that snapshot is stored here.
6668 snapshot : Option < Snapshot > ,
6769}
6870
@@ -117,15 +119,19 @@ impl MultiUseSandbox {
117119 /// ```
118120 #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) ) ]
119121 pub fn snapshot ( & mut self ) -> Result < Snapshot > {
122+ if let Some ( snapshot) = & self . snapshot {
123+ return Ok ( snapshot. clone ( ) ) ;
124+ }
120125 let mapped_regions_iter = self . vm . get_mapped_regions ( ) ;
121126 let mapped_regions_vec: Vec < MemoryRegion > = mapped_regions_iter. cloned ( ) . collect ( ) ;
122127 let memory_snapshot = self
123128 . mem_mgr
124129 . unwrap_mgr_mut ( )
125130 . snapshot ( self . id , mapped_regions_vec) ?;
126- Ok ( Snapshot {
127- inner : Arc :: new ( memory_snapshot) ,
128- } )
131+ let inner = Arc :: new ( memory_snapshot) ;
132+ let snapshot = Snapshot { inner } ;
133+ self . snapshot = Some ( snapshot. clone ( ) ) ;
134+ Ok ( snapshot)
129135 }
130136
131137 /// Restores the sandbox's memory to a previously captured snapshot state.
@@ -161,6 +167,13 @@ impl MultiUseSandbox {
161167 /// ```
162168 #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) ) ]
163169 pub fn restore ( & mut self , snapshot : & Snapshot ) -> Result < ( ) > {
170+ if let Some ( snap) = & self . snapshot {
171+ if Arc :: ptr_eq ( & snap. inner , & snapshot. inner ) {
172+ // If the snapshot is already the current one, no need to restore
173+ return Ok ( ( ) ) ;
174+ }
175+ }
176+
164177 if self . id != snapshot. inner . sandbox_id ( ) {
165178 return Err ( SnapshotSandboxMismatch ) ;
166179 }
@@ -231,10 +244,7 @@ impl MultiUseSandbox {
231244 func_name : & str ,
232245 args : impl ParameterTuple ,
233246 ) -> Result < Output > {
234- let snapshot = match & self . snapshot {
235- Some ( snapshot) => snapshot. clone ( ) ,
236- None => self . snapshot ( ) ?,
237- } ;
247+ let snapshot = self . snapshot ( ) ?;
238248 let res = self . run ( func_name, args) ;
239249 self . restore ( & snapshot) ?;
240250 res
@@ -312,6 +322,8 @@ impl MultiUseSandbox {
312322 // writes can be rolled back when necessary.
313323 log_then_return ! ( "TODO: Writable mappings not yet supported" ) ;
314324 }
325+ // Reset snapshot since we are mutating the sandbox state
326+ self . snapshot = None ;
315327 unsafe { self . vm . map_region ( rgn) } ?;
316328 self . mem_mgr . unwrap_mgr_mut ( ) . mapped_rgns += 1 ;
317329 Ok ( ( ) )
0 commit comments