-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #118336 - saethlin:const-to-op-cache, r=RalfJung
Return a finite number of AllocIds per ConstAllocation in Miri Before this, every evaluation of a const slice would produce a new AllocId. So in Miri, this program used to have unbounded memory use: ```rust fn main() { loop { helper(); } } fn helper() { "ouch"; } ``` Every trip around the loop creates a new AllocId which we need to keep track of a base address for. And the provenance GC can never clean up that AllocId -> u64 mapping, because the AllocId is for a const allocation which will never be deallocated. So this PR moves the logic of producing an AllocId for a ConstAllocation to the Machine trait, and the implementation that Miri provides will only produce 16 AllocIds for each allocation. The cache is also keyed on the Instance that the const is evaluated in, so that equal consts evaluated in two functions will have disjoint base addresses. r? RalfJung
- Loading branch information
Showing
4 changed files
with
119 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// The const fn interpreter creates a new AllocId every time it evaluates any const. | ||
// If we do that in Miri, repeatedly evaluating a const causes unbounded memory use | ||
// we need to keep track of the base address for that AllocId, and the allocation is never | ||
// deallocated. | ||
// In Miri we explicitly store previously-assigned AllocIds for each const and ensure | ||
// that we only hand out a finite number of AllocIds per const. | ||
// MIR inlining will put every evaluation of the const we're repeatedly evaluting into the same | ||
// stack frame, breaking this test. | ||
//@compile-flags: -Zinline-mir=no | ||
#![feature(strict_provenance)] | ||
|
||
const EVALS: usize = 256; | ||
|
||
use std::collections::HashSet; | ||
fn main() { | ||
let mut addrs = HashSet::new(); | ||
for _ in 0..EVALS { | ||
addrs.insert(const_addr()); | ||
} | ||
// Check that the const allocation has multiple base addresses | ||
assert!(addrs.len() > 1); | ||
// But also that we get a limited number of unique base addresses | ||
assert!(addrs.len() < EVALS); | ||
|
||
// Check that within a call we always produce the same address | ||
let mut prev = 0; | ||
for iter in 0..EVALS { | ||
let addr = "test".as_bytes().as_ptr().addr(); | ||
if iter > 0 { | ||
assert_eq!(prev, addr); | ||
} | ||
prev = addr; | ||
} | ||
} | ||
|
||
fn const_addr() -> usize { | ||
"test".as_bytes().as_ptr().addr() | ||
} |