@@ -257,95 +257,12 @@ impl<'tcx> AllocExtra<'tcx> {
257257 }
258258}
259259
260- /// We designate an `init`` field in all synchronization objects.
261- /// If `init` is set to this, we consider the object initialized.
262- pub const LAZY_INIT_COOKIE : u32 = 0xcafe_affe ;
263-
264260// Public interface to synchronization objects. Please note that in most
265261// cases, the function calls are infallible and it is the client's (shim
266262// implementation's) responsibility to detect and deal with erroneous
267263// situations.
268264impl < ' tcx > EvalContextExt < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
269265pub trait EvalContextExt < ' tcx > : crate :: MiriInterpCxExt < ' tcx > {
270- /// Helper for lazily initialized `alloc_extra.sync` data:
271- /// this forces an immediate init.
272- /// Return a reference to the data in the machine state.
273- fn lazy_sync_init < ' a , T : SyncObj > (
274- & ' a mut self ,
275- obj : & MPlaceTy < ' tcx > ,
276- init_offset : Size ,
277- data : T ,
278- ) -> InterpResult < ' tcx , & ' a T >
279- where
280- ' tcx : ' a ,
281- {
282- let this = self . eval_context_mut ( ) ;
283-
284- let ( alloc, offset, _) = this. ptr_get_alloc_id ( obj. ptr ( ) , 0 ) ?;
285- // Mark this as "initialized".
286- let init_cookie = Scalar :: from_u32 ( LAZY_INIT_COOKIE ) ;
287- assert ! ( init_offset + init_cookie. size( ) <= obj. layout. size) ;
288- let init_field = obj. offset ( init_offset, this. machine . layouts . u32 , this) ?;
289- this. write_scalar_atomic ( init_cookie, & init_field, AtomicWriteOrd :: Relaxed ) ?;
290- // Insert sync obj, and return reference to it.
291- let ( alloc_extra, _machine) = this. get_alloc_extra_mut ( alloc) ?;
292- alloc_extra. sync_objs . insert ( offset, Box :: new ( data) ) ;
293- interp_ok ( this. get_alloc_extra ( alloc) ?. get_sync :: < T > ( offset) . unwrap ( ) )
294- }
295-
296- /// Helper for lazily initialized `alloc_extra.sync` data:
297- /// Checks if the synchronization object is initialized:
298- /// - If yes, fetches the data from `alloc_extra.sync`, or calls `missing_data` if that fails
299- /// and stores that in `alloc_extra.sync`.
300- /// - Otherwise, calls `new_data` to initialize the object.
301- ///
302- /// Return a reference to the data in the machine state.
303- fn lazy_sync_get_data < ' a , T : SyncObj > (
304- & ' a mut self ,
305- obj : & MPlaceTy < ' tcx > ,
306- init_offset : Size ,
307- missing_data : impl FnOnce ( ) -> InterpResult < ' tcx , T > ,
308- new_data : impl FnOnce ( & mut MiriInterpCx < ' tcx > ) -> InterpResult < ' tcx , T > ,
309- ) -> InterpResult < ' tcx , & ' a T >
310- where
311- ' tcx : ' a ,
312- {
313- let this = self . eval_context_mut ( ) ;
314-
315- // Check if this is already initialized. Needs to be atomic because we can race with another
316- // thread initializing. Needs to be an RMW operation to ensure we read the *latest* value.
317- // So we just try to replace MUTEX_INIT_COOKIE with itself.
318- let init_cookie = Scalar :: from_u32 ( LAZY_INIT_COOKIE ) ;
319- assert ! ( init_offset + init_cookie. size( ) <= obj. layout. size) ;
320- let init_field = obj. offset ( init_offset, this. machine . layouts . u32 , this) ?;
321- let ( _init, success) = this
322- . atomic_compare_exchange_scalar (
323- & init_field,
324- & ImmTy :: from_scalar ( init_cookie, this. machine . layouts . u32 ) ,
325- init_cookie,
326- AtomicRwOrd :: Relaxed ,
327- AtomicReadOrd :: Relaxed ,
328- /* can_fail_spuriously */ false ,
329- ) ?
330- . to_scalar_pair ( ) ;
331-
332- if success. to_bool ( ) ? {
333- // If it is initialized, it must be found in the "sync obj" table,
334- // or else it has been moved illegally.
335- let ( alloc, offset, _) = this. ptr_get_alloc_id ( obj. ptr ( ) , 0 ) ?;
336- let ( alloc_extra, _machine) = this. get_alloc_extra_mut ( alloc) ?;
337- // Due to borrow checker reasons, we have to do the lookup twice.
338- if alloc_extra. get_sync :: < T > ( offset) . is_none ( ) {
339- let data = missing_data ( ) ?;
340- alloc_extra. sync_objs . insert ( offset, Box :: new ( data) ) ;
341- }
342- interp_ok ( alloc_extra. get_sync :: < T > ( offset) . unwrap ( ) )
343- } else {
344- let data = new_data ( this) ?;
345- this. lazy_sync_init ( obj, init_offset, data)
346- }
347- }
348-
349266 /// Get the synchronization object associated with the given pointer,
350267 /// or initialize a new one.
351268 ///
0 commit comments