@@ -321,14 +321,20 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
321321
322322/// Allocation accessors
323323impl < ' a , ' mir , ' tcx , M : Machine < ' a , ' mir , ' tcx > > Memory < ' a , ' mir , ' tcx , M > {
324- /// Helper function to obtain the global (tcx) allocation for a static
324+ /// Helper function to obtain the global (tcx) allocation for a static.
325+ /// This attempts to return a reference to an existing allocation if
326+ /// one can be found in `tcx`. That, however, is only possible if `tcx` and
327+ /// this machine use the same pointer tag, so it is indirected through
328+ /// `M::static_with_default_tag`.
325329 fn get_static_alloc (
326330 tcx : TyCtxtAt < ' a , ' tcx , ' tcx > ,
327331 id : AllocId ,
328332 ) -> EvalResult < ' tcx , Cow < ' tcx , Allocation < M :: PointerTag > > > {
329333 let alloc = tcx. alloc_map . lock ( ) . get ( id) ;
330334 let def_id = match alloc {
331335 Some ( AllocType :: Memory ( mem) ) => {
336+ // We got tcx memory. Let the machine figure out whether and how to
337+ // turn that into memory with the right pointer tag.
332338 return Ok ( M :: static_with_default_tag ( mem) )
333339 }
334340 Some ( AllocType :: Function ( ..) ) => {
@@ -356,6 +362,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
356362 EvalErrorKind :: ReferencedConstant ( err) . into ( )
357363 } ) . map ( |const_val| {
358364 if let ConstValue :: ByRef ( _, allocation, _) = const_val. val {
365+ // We got tcx memory. Let the machine figure out whether and how to
366+ // turn that into memory with the right pointer tag.
359367 M :: static_with_default_tag ( allocation)
360368 } else {
361369 bug ! ( "Matching on non-ByRef static" )
@@ -372,7 +380,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
372380 let alloc = Self :: get_static_alloc ( self . tcx , id) . map_err ( Err ) ?;
373381 match alloc {
374382 Cow :: Borrowed ( alloc) => {
375- // We got a ref, cheaply return that as an "error"
383+ // We got a ref, cheaply return that as an "error" so that the
384+ // map does not get mutated.
376385 Err ( Ok ( alloc) )
377386 }
378387 Cow :: Owned ( alloc) => {
@@ -392,30 +401,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
392401 }
393402 }
394403
395- pub fn get_size_and_align ( & self , id : AllocId ) -> ( Size , Align ) {
396- if let Ok ( alloc) = self . get ( id) {
397- return ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ;
398- }
399- // Could also be a fn ptr or extern static
400- match self . tcx . alloc_map . lock ( ) . get ( id) {
401- Some ( AllocType :: Function ( ..) ) => ( Size :: ZERO , Align :: from_bytes ( 1 , 1 ) . unwrap ( ) ) ,
402- Some ( AllocType :: Static ( did) ) => {
403- // The only way `get` couldnÄt have worked here is if this is an extern static
404- assert ! ( self . tcx. is_foreign_item( did) ) ;
405- // Use size and align of the type
406- let ty = self . tcx . type_of ( did) ;
407- let layout = self . tcx . layout_of ( ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
408- ( layout. size , layout. align )
409- }
410- _ => {
411- // Must be a deallocated pointer
412- * self . dead_alloc_map . get ( & id) . expect (
413- "allocation missing in dead_alloc_map"
414- )
415- }
416- }
417- }
418-
419404 pub fn get_mut (
420405 & mut self ,
421406 id : AllocId ,
@@ -429,8 +414,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
429414 return err ! ( ModifiedConstantMemory ) ;
430415 }
431416 let kind = M :: STATIC_KIND . expect (
432- "I got an owned allocation that I have to copy but the machine does \
433- not expect that to happen"
417+ "An allocation is being mutated but the machine does not expect that to happen"
434418 ) ;
435419 Ok ( ( MemoryKind :: Machine ( kind) , alloc. into_owned ( ) ) )
436420 } ) ;
@@ -448,6 +432,30 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
448432 }
449433 }
450434
435+ pub fn get_size_and_align ( & self , id : AllocId ) -> ( Size , Align ) {
436+ if let Ok ( alloc) = self . get ( id) {
437+ return ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ;
438+ }
439+ // Could also be a fn ptr or extern static
440+ match self . tcx . alloc_map . lock ( ) . get ( id) {
441+ Some ( AllocType :: Function ( ..) ) => ( Size :: ZERO , Align :: from_bytes ( 1 , 1 ) . unwrap ( ) ) ,
442+ Some ( AllocType :: Static ( did) ) => {
443+ // The only way `get` couldn't have worked here is if this is an extern static
444+ assert ! ( self . tcx. is_foreign_item( did) ) ;
445+ // Use size and align of the type
446+ let ty = self . tcx . type_of ( did) ;
447+ let layout = self . tcx . layout_of ( ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
448+ ( layout. size , layout. align )
449+ }
450+ _ => {
451+ // Must be a deallocated pointer
452+ * self . dead_alloc_map . get ( & id) . expect (
453+ "allocation missing in dead_alloc_map"
454+ )
455+ }
456+ }
457+ }
458+
451459 pub fn get_fn ( & self , ptr : Pointer < M :: PointerTag > ) -> EvalResult < ' tcx , Instance < ' tcx > > {
452460 if ptr. offset . bytes ( ) != 0 {
453461 return err ! ( InvalidFunctionPointer ) ;
0 commit comments