@@ -63,6 +63,8 @@ pub struct MultiUseSandbox {
63
63
dispatch_ptr : RawPtr ,
64
64
#[ cfg( gdb) ]
65
65
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.
66
68
snapshot : Option < Snapshot > ,
67
69
}
68
70
@@ -117,15 +119,19 @@ impl MultiUseSandbox {
117
119
/// ```
118
120
#[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) ) ]
119
121
pub fn snapshot ( & mut self ) -> Result < Snapshot > {
122
+ if let Some ( snapshot) = & self . snapshot {
123
+ return Ok ( snapshot. clone ( ) ) ;
124
+ }
120
125
let mapped_regions_iter = self . vm . get_mapped_regions ( ) ;
121
126
let mapped_regions_vec: Vec < MemoryRegion > = mapped_regions_iter. cloned ( ) . collect ( ) ;
122
127
let memory_snapshot = self
123
128
. mem_mgr
124
129
. unwrap_mgr_mut ( )
125
130
. 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)
129
135
}
130
136
131
137
/// Restores the sandbox's memory to a previously captured snapshot state.
@@ -161,6 +167,13 @@ impl MultiUseSandbox {
161
167
/// ```
162
168
#[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) ) ]
163
169
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
+
164
177
if self . id != snapshot. inner . sandbox_id ( ) {
165
178
return Err ( SnapshotSandboxMismatch ) ;
166
179
}
@@ -231,10 +244,7 @@ impl MultiUseSandbox {
231
244
func_name : & str ,
232
245
args : impl ParameterTuple ,
233
246
) -> Result < Output > {
234
- let snapshot = match & self . snapshot {
235
- Some ( snapshot) => snapshot. clone ( ) ,
236
- None => self . snapshot ( ) ?,
237
- } ;
247
+ let snapshot = self . snapshot ( ) ?;
238
248
let res = self . run ( func_name, args) ;
239
249
self . restore ( & snapshot) ?;
240
250
res
@@ -312,6 +322,8 @@ impl MultiUseSandbox {
312
322
// writes can be rolled back when necessary.
313
323
log_then_return ! ( "TODO: Writable mappings not yet supported" ) ;
314
324
}
325
+ // Reset snapshot since we are mutating the sandbox state
326
+ self . snapshot = None ;
315
327
unsafe { self . vm . map_region ( rgn) } ?;
316
328
self . mem_mgr . unwrap_mgr_mut ( ) . mapped_rgns += 1 ;
317
329
Ok ( ( ) )
0 commit comments