@@ -11,6 +11,7 @@ use rand::rngs::StdRng;
11
11
use rand:: Rng ;
12
12
use rand:: SeedableRng ;
13
13
14
+ use rustc_attr:: InlineAttr ;
14
15
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
15
16
#[ allow( unused) ]
16
17
use rustc_data_structures:: static_assert_size;
@@ -23,6 +24,7 @@ use rustc_middle::{
23
24
Instance , Ty , TyCtxt ,
24
25
} ,
25
26
} ;
27
+ use rustc_session:: config:: InliningThreshold ;
26
28
use rustc_span:: def_id:: { CrateNum , DefId } ;
27
29
use rustc_span:: { Span , SpanData , Symbol } ;
28
30
use rustc_target:: abi:: { Align , Size } ;
@@ -47,10 +49,10 @@ pub const SIGRTMIN: i32 = 34;
47
49
/// `SIGRTMAX` - `SIGRTMIN` >= 8 (which is the value of `_POSIX_RTSIG_MAX`)
48
50
pub const SIGRTMAX : i32 = 42 ;
49
51
50
- /// Each const has multiple addresses, but only this many. Since const allocations are never
51
- /// deallocated, choosing a new [`AllocId`] and thus base address for each evaluation would
52
- /// produce unbounded memory usage.
53
- const ADDRS_PER_CONST : usize = 16 ;
52
+ /// Each anonymous global (constant, vtable, function pointer, ...) has multiple addresses, but only
53
+ /// this many. Since const allocations are never deallocated, choosing a new [`AllocId`] and thus
54
+ /// base address for each evaluation would produce unbounded memory usage.
55
+ const ADDRS_PER_ANON_GLOBAL : usize = 32 ;
54
56
55
57
/// Extra data stored with each stack frame
56
58
pub struct FrameExtra < ' tcx > {
@@ -1372,7 +1374,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
1372
1374
catch_unwind : None ,
1373
1375
timing,
1374
1376
is_user_relevant : ecx. machine . is_user_relevant ( & frame) ,
1375
- salt : ecx. machine . rng . borrow_mut ( ) . gen :: < usize > ( ) % ADDRS_PER_CONST ,
1377
+ salt : ecx. machine . rng . borrow_mut ( ) . gen :: < usize > ( ) % ADDRS_PER_ANON_GLOBAL ,
1376
1378
} ;
1377
1379
1378
1380
Ok ( frame. with_extra ( extra) )
@@ -1518,4 +1520,45 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
1518
1520
Entry :: Occupied ( oe) => Ok ( oe. get ( ) . clone ( ) ) ,
1519
1521
}
1520
1522
}
1523
+
1524
+ fn get_global_alloc_salt (
1525
+ ecx : & InterpCx < ' tcx , Self > ,
1526
+ instance : Option < ty:: Instance < ' tcx > > ,
1527
+ ) -> usize {
1528
+ let unique = if let Some ( instance) = instance {
1529
+ // Functions cannot be identified by pointers, as asm-equal functions can get
1530
+ // deduplicated by the linker (we set the "unnamed_addr" attribute for LLVM) and
1531
+ // functions can be duplicated across crates. We thus generate a new `AllocId` for every
1532
+ // mention of a function. This means that `main as fn() == main as fn()` is false, while
1533
+ // `let x = main as fn(); x == x` is true. However, as a quality-of-life feature it can
1534
+ // be useful to identify certain functions uniquely, e.g. for backtraces. So we identify
1535
+ // whether codegen will actually emit duplicate functions. It does that when they have
1536
+ // non-lifetime generics, or when they can be inlined. All other functions are given a
1537
+ // unique address. This is not a stable guarantee! The `inline` attribute is a hint and
1538
+ // cannot be relied upon for anything. But if we don't do this, the
1539
+ // `__rust_begin_short_backtrace`/`__rust_end_short_backtrace` logic breaks and panic
1540
+ // backtraces look terrible.
1541
+ let is_generic = instance
1542
+ . args
1543
+ . into_iter ( )
1544
+ . any ( |kind| !matches ! ( kind. unpack( ) , ty:: GenericArgKind :: Lifetime ( _) ) ) ;
1545
+ let can_be_inlined = matches ! (
1546
+ ecx. tcx. sess. opts. unstable_opts. cross_crate_inline_threshold,
1547
+ InliningThreshold :: Always
1548
+ ) || !matches ! (
1549
+ ecx. tcx. codegen_fn_attrs( instance. def_id( ) ) . inline,
1550
+ InlineAttr :: Never
1551
+ ) ;
1552
+ !is_generic && !can_be_inlined
1553
+ } else {
1554
+ // Non-functions are never unique.
1555
+ false
1556
+ } ;
1557
+ // Always use the same salt if the allocation is unique.
1558
+ if unique {
1559
+ CTFE_ALLOC_SALT
1560
+ } else {
1561
+ ecx. machine . rng . borrow_mut ( ) . gen :: < usize > ( ) % ADDRS_PER_ANON_GLOBAL
1562
+ }
1563
+ }
1521
1564
}
0 commit comments