@@ -197,9 +197,7 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
197
197
tcx : TyCtxt < ' tcx > ,
198
198
alloc_id : AllocId ,
199
199
) -> Result < ( ) , E :: Error > {
200
- let alloc: GlobalAlloc < ' tcx > =
201
- tcx. alloc_map . lock ( ) . get ( alloc_id) . expect ( "no value for given alloc ID" ) ;
202
- match alloc {
200
+ match tcx. get_global_alloc ( alloc_id) . expect ( "no value for given alloc ID" ) {
203
201
GlobalAlloc :: Memory ( alloc) => {
204
202
trace ! ( "encoding {:?} with {:#?}" , alloc_id, alloc) ;
205
203
AllocDiscriminant :: Alloc . encode ( encoder) ?;
@@ -294,7 +292,7 @@ impl<'s> AllocDecodingSession<'s> {
294
292
AllocDiscriminant :: Alloc => {
295
293
// If this is an allocation, we need to reserve an
296
294
// `AllocId` so we can decode cyclic graphs.
297
- let alloc_id = decoder. tcx ( ) . alloc_map . lock ( ) . reserve ( ) ;
295
+ let alloc_id = decoder. tcx ( ) . reserve_alloc_id ( ) ;
298
296
* entry =
299
297
State :: InProgress ( TinyList :: new_single ( self . session_id ) , alloc_id) ;
300
298
Some ( alloc_id)
@@ -338,23 +336,23 @@ impl<'s> AllocDecodingSession<'s> {
338
336
// We already have a reserved `AllocId`.
339
337
let alloc_id = alloc_id. unwrap ( ) ;
340
338
trace ! ( "decoded alloc {:?}: {:#?}" , alloc_id, alloc) ;
341
- decoder. tcx ( ) . alloc_map . lock ( ) . set_alloc_id_same_memory ( alloc_id, alloc) ;
339
+ decoder. tcx ( ) . set_alloc_id_same_memory ( alloc_id, alloc) ;
342
340
Ok ( alloc_id)
343
341
}
344
342
AllocDiscriminant :: Fn => {
345
343
assert ! ( alloc_id. is_none( ) ) ;
346
344
trace ! ( "creating fn alloc ID" ) ;
347
345
let instance = ty:: Instance :: decode ( decoder) ?;
348
346
trace ! ( "decoded fn alloc instance: {:?}" , instance) ;
349
- let alloc_id = decoder. tcx ( ) . alloc_map . lock ( ) . create_fn_alloc ( instance) ;
347
+ let alloc_id = decoder. tcx ( ) . create_fn_alloc ( instance) ;
350
348
Ok ( alloc_id)
351
349
}
352
350
AllocDiscriminant :: Static => {
353
351
assert ! ( alloc_id. is_none( ) ) ;
354
352
trace ! ( "creating extern static alloc ID" ) ;
355
353
let did = DefId :: decode ( decoder) ?;
356
354
trace ! ( "decoded static def-ID: {:?}" , did) ;
357
- let alloc_id = decoder. tcx ( ) . alloc_map . lock ( ) . create_static_alloc ( did) ;
355
+ let alloc_id = decoder. tcx ( ) . create_static_alloc ( did) ;
358
356
Ok ( alloc_id)
359
357
}
360
358
}
@@ -400,12 +398,6 @@ impl<'tcx> AllocMap<'tcx> {
400
398
pub fn new ( ) -> Self {
401
399
AllocMap { alloc_map : Default :: default ( ) , dedup : Default :: default ( ) , next_id : AllocId ( 0 ) }
402
400
}
403
-
404
- /// Obtains a new allocation ID that can be referenced but does not
405
- /// yet have an allocation backing it.
406
- ///
407
- /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
408
- /// an `AllocId` from a query.
409
401
pub fn reserve ( & mut self ) -> AllocId {
410
402
let next = self . next_id ;
411
403
self . next_id . 0 = self . next_id . 0 . checked_add ( 1 ) . expect (
@@ -415,34 +407,46 @@ impl<'tcx> AllocMap<'tcx> {
415
407
) ;
416
408
next
417
409
}
410
+ }
411
+
412
+ impl < ' tcx > TyCtxt < ' tcx > {
413
+ /// Obtains a new allocation ID that can be referenced but does not
414
+ /// yet have an allocation backing it.
415
+ ///
416
+ /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
417
+ /// an `AllocId` from a query.
418
+ pub fn reserve_alloc_id ( & self ) -> AllocId {
419
+ self . alloc_map . lock ( ) . reserve ( )
420
+ }
418
421
419
422
/// Reserves a new ID *if* this allocation has not been dedup-reserved before.
420
423
/// Should only be used for function pointers and statics, we don't want
421
424
/// to dedup IDs for "real" memory!
422
- fn reserve_and_set_dedup ( & mut self , alloc : GlobalAlloc < ' tcx > ) -> AllocId {
425
+ fn reserve_and_set_dedup ( & self , alloc : GlobalAlloc < ' tcx > ) -> AllocId {
426
+ let mut alloc_map = self . alloc_map . lock ( ) ;
423
427
match alloc {
424
428
GlobalAlloc :: Function ( ..) | GlobalAlloc :: Static ( ..) => { }
425
429
GlobalAlloc :: Memory ( ..) => bug ! ( "Trying to dedup-reserve memory with real data!" ) ,
426
430
}
427
- if let Some ( & alloc_id) = self . dedup . get ( & alloc) {
431
+ if let Some ( & alloc_id) = alloc_map . dedup . get ( & alloc) {
428
432
return alloc_id;
429
433
}
430
- let id = self . reserve ( ) ;
434
+ let id = alloc_map . reserve ( ) ;
431
435
debug ! ( "creating alloc {:?} with id {}" , alloc, id) ;
432
- self . alloc_map . insert ( id, alloc. clone ( ) ) ;
433
- self . dedup . insert ( alloc, id) ;
436
+ alloc_map . alloc_map . insert ( id, alloc. clone ( ) ) ;
437
+ alloc_map . dedup . insert ( alloc, id) ;
434
438
id
435
439
}
436
440
437
441
/// Generates an `AllocId` for a static or return a cached one in case this function has been
438
442
/// called on the same static before.
439
- pub fn create_static_alloc ( & mut self , static_id : DefId ) -> AllocId {
443
+ pub fn create_static_alloc ( & self , static_id : DefId ) -> AllocId {
440
444
self . reserve_and_set_dedup ( GlobalAlloc :: Static ( static_id) )
441
445
}
442
446
443
447
/// Generates an `AllocId` for a function. Depending on the function type,
444
448
/// this might get deduplicated or assigned a new ID each time.
445
- pub fn create_fn_alloc ( & mut self , instance : Instance < ' tcx > ) -> AllocId {
449
+ pub fn create_fn_alloc ( & self , instance : Instance < ' tcx > ) -> AllocId {
446
450
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
447
451
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
448
452
// duplicated across crates.
@@ -456,8 +460,9 @@ impl<'tcx> AllocMap<'tcx> {
456
460
} ) ;
457
461
if is_generic {
458
462
// Get a fresh ID.
459
- let id = self . reserve ( ) ;
460
- self . alloc_map . insert ( id, GlobalAlloc :: Function ( instance) ) ;
463
+ let mut alloc_map = self . alloc_map . lock ( ) ;
464
+ let id = alloc_map. reserve ( ) ;
465
+ alloc_map. alloc_map . insert ( id, GlobalAlloc :: Function ( instance) ) ;
461
466
id
462
467
} else {
463
468
// Deduplicate.
@@ -470,8 +475,8 @@ impl<'tcx> AllocMap<'tcx> {
470
475
/// Statics with identical content will still point to the same `Allocation`, i.e.,
471
476
/// their data will be deduplicated through `Allocation` interning -- but they
472
477
/// are different places in memory and as such need different IDs.
473
- pub fn create_memory_alloc ( & mut self , mem : & ' tcx Allocation ) -> AllocId {
474
- let id = self . reserve ( ) ;
478
+ pub fn create_memory_alloc ( & self , mem : & ' tcx Allocation ) -> AllocId {
479
+ let id = self . reserve_alloc_id ( ) ;
475
480
self . set_alloc_id_memory ( id, mem) ;
476
481
id
477
482
}
@@ -482,38 +487,38 @@ impl<'tcx> AllocMap<'tcx> {
482
487
/// This function exists to allow const eval to detect the difference between evaluation-
483
488
/// local dangling pointers and allocations in constants/statics.
484
489
#[ inline]
485
- pub fn get ( & self , id : AllocId ) -> Option < GlobalAlloc < ' tcx > > {
486
- self . alloc_map . get ( & id) . cloned ( )
490
+ pub fn get_global_alloc ( & self , id : AllocId ) -> Option < GlobalAlloc < ' tcx > > {
491
+ self . alloc_map . lock ( ) . alloc_map . get ( & id) . cloned ( )
487
492
}
488
493
489
494
/// Panics if the `AllocId` does not refer to an `Allocation`
490
495
pub fn unwrap_memory ( & self , id : AllocId ) -> & ' tcx Allocation {
491
- match self . get ( id) {
496
+ match self . get_global_alloc ( id) {
492
497
Some ( GlobalAlloc :: Memory ( mem) ) => mem,
493
498
_ => bug ! ( "expected allocation ID {} to point to memory" , id) ,
494
499
}
495
500
}
496
501
497
502
/// Panics if the `AllocId` does not refer to a function
498
503
pub fn unwrap_fn ( & self , id : AllocId ) -> Instance < ' tcx > {
499
- match self . get ( id) {
504
+ match self . get_global_alloc ( id) {
500
505
Some ( GlobalAlloc :: Function ( instance) ) => instance,
501
506
_ => bug ! ( "expected allocation ID {} to point to a function" , id) ,
502
507
}
503
508
}
504
509
505
510
/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
506
511
/// call this function twice, even with the same `Allocation` will ICE the compiler.
507
- pub fn set_alloc_id_memory ( & mut self , id : AllocId , mem : & ' tcx Allocation ) {
508
- if let Some ( old) = self . alloc_map . insert ( id, GlobalAlloc :: Memory ( mem) ) {
512
+ pub fn set_alloc_id_memory ( & self , id : AllocId , mem : & ' tcx Allocation ) {
513
+ if let Some ( old) = self . alloc_map . lock ( ) . alloc_map . insert ( id, GlobalAlloc :: Memory ( mem) ) {
509
514
bug ! ( "tried to set allocation ID {}, but it was already existing as {:#?}" , id, old) ;
510
515
}
511
516
}
512
517
513
518
/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
514
519
/// twice for the same `(AllocId, Allocation)` pair.
515
- fn set_alloc_id_same_memory ( & mut self , id : AllocId , mem : & ' tcx Allocation ) {
516
- self . alloc_map . insert_same ( id, GlobalAlloc :: Memory ( mem) ) ;
520
+ fn set_alloc_id_same_memory ( & self , id : AllocId , mem : & ' tcx Allocation ) {
521
+ self . alloc_map . lock ( ) . alloc_map . insert_same ( id, GlobalAlloc :: Memory ( mem) ) ;
517
522
}
518
523
}
519
524
0 commit comments