Skip to content

Commit ac8c98d

Browse files
committed
Store layouts of i32 and u32 inside Evaluator
1 parent 8293d80 commit ac8c98d

File tree

3 files changed

+75
-25
lines changed

3 files changed

+75
-25
lines changed

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ pub use crate::diagnostics::{
5151
pub use crate::eval::{create_ecx, eval_main, MiriConfig};
5252
pub use crate::helpers::EvalContextExt as HelpersEvalContextExt;
5353
pub use crate::machine::{
54-
AllocExtra, Evaluator, FrameData, MemoryExtra, MiriEvalContext, MiriEvalContextExt,
55-
MiriMemoryKind, NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
54+
AllocExtra, EvalContextExt as MachineEvalContextExt, Evaluator, FrameData, MemoryExtra,
55+
MiriEvalContext, MiriEvalContextExt, MiriMemoryKind, NUM_CPUS, PAGE_SIZE, STACK_ADDR,
56+
STACK_SIZE,
5657
};
5758
pub use crate::mono_hash_map::MonoHashMap;
5859
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;

src/machine.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use log::trace;
1111
use rand::rngs::StdRng;
1212

1313
use rustc_data_structures::fx::FxHashMap;
14-
use rustc_middle::{mir, ty};
14+
use rustc_middle::{mir, ty::{self, layout::TyAndLayout}};
1515
use rustc_target::abi::{LayoutOf, Size};
1616
use rustc_ast::attr;
1717
use rustc_span::symbol::{sym, Symbol};
@@ -146,6 +146,39 @@ impl MemoryExtra {
146146
}
147147
}
148148

149+
/// Cached layouts of primitive types
150+
#[derive(Default)]
151+
struct PrimitiveLayouts<'tcx> {
152+
i32: RefCell<Option<TyAndLayout<'tcx>>>,
153+
u32: RefCell<Option<TyAndLayout<'tcx>>>,
154+
}
155+
156+
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
157+
fn i32(&self, ecx: &MiriEvalContext<'mir, 'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
158+
{
159+
let layout_ref = self.i32.borrow();
160+
if layout_ref.is_some() {
161+
return Ok(layout_ref.unwrap());
162+
}
163+
}
164+
let layout = ecx.layout_of(ecx.tcx.types.i32)?;
165+
*self.i32.borrow_mut() = Some(layout);
166+
Ok(layout)
167+
}
168+
169+
fn u32(&self, ecx: &MiriEvalContext<'mir, 'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
170+
{
171+
let layout_ref = self.u32.borrow();
172+
if layout_ref.is_some() {
173+
return Ok(layout_ref.unwrap());
174+
}
175+
}
176+
let layout = ecx.layout_of(ecx.tcx.types.u32)?;
177+
*self.u32.borrow_mut() = Some(layout);
178+
Ok(layout)
179+
}
180+
}
181+
149182
/// The machine itself.
150183
pub struct Evaluator<'tcx> {
151184
/// Environment variables set by `setenv`.
@@ -182,6 +215,9 @@ pub struct Evaluator<'tcx> {
182215

183216
/// The "time anchor" for this machine's monotone clock (for `Instant` simulation).
184217
pub(crate) time_anchor: Instant,
218+
219+
/// Cached `TyLayout`s for primitive data types that are commonly used inside Miri.
220+
primitive_layouts: PrimitiveLayouts<'tcx>,
185221
}
186222

187223
impl<'tcx> Evaluator<'tcx> {
@@ -201,6 +237,7 @@ impl<'tcx> Evaluator<'tcx> {
201237
dir_handler: Default::default(),
202238
panic_payload: None,
203239
time_anchor: Instant::now(),
240+
primitive_layouts: PrimitiveLayouts::default(),
204241
}
205242
}
206243
}
@@ -224,6 +261,20 @@ impl<'mir, 'tcx> MiriEvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx>
224261
}
225262
}
226263

264+
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {}
265+
/// Provides convenience methods for use elsewhere
266+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
267+
fn i32_layout(&self) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
268+
let this = self.eval_context_ref();
269+
this.machine.primitive_layouts.i32(this)
270+
}
271+
272+
fn u32_layout(&self) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
273+
let this = self.eval_context_ref();
274+
this.machine.primitive_layouts.u32(this)
275+
}
276+
}
277+
227278
/// Machine hook implementations.
228279
impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
229280
type MemoryKind = MiriMemoryKind;

src/shims/sync.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ fn mutexattr_get_kind<'mir, 'tcx: 'mir>(
3030
// Ensure that the following read at an offset to the attr pointer is within bounds
3131
assert_ptr_target_min_size(ecx, attr_op, 4)?;
3232
let attr_place = ecx.deref_operand(attr_op)?;
33-
let i32_layout = ecx.layout_of(ecx.tcx.types.i32)?;
34-
let kind_place = attr_place.offset(Size::ZERO, MemPlaceMeta::None, i32_layout, ecx)?;
33+
let kind_place = attr_place.offset(Size::ZERO, MemPlaceMeta::None, ecx.i32_layout()?, ecx)?;
3534
ecx.read_scalar(kind_place.into())
3635
}
3736

@@ -43,8 +42,7 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
4342
// Ensure that the following write at an offset to the attr pointer is within bounds
4443
assert_ptr_target_min_size(ecx, attr_op, 4)?;
4544
let attr_place = ecx.deref_operand(attr_op)?;
46-
let i32_layout = ecx.layout_of(ecx.tcx.types.i32)?;
47-
let kind_place = attr_place.offset(Size::ZERO, MemPlaceMeta::None, i32_layout, ecx)?;
45+
let kind_place = attr_place.offset(Size::ZERO, MemPlaceMeta::None, ecx.i32_layout()?, ecx)?;
4846
ecx.write_scalar(kind.into(), kind_place.into())
4947
}
5048

@@ -64,9 +62,8 @@ fn mutex_get_locked_count<'mir, 'tcx: 'mir>(
6462
// Ensure that the following read at an offset to the mutex pointer is within bounds
6563
assert_ptr_target_min_size(ecx, mutex_op, 20)?;
6664
let mutex_place = ecx.deref_operand(mutex_op)?;
67-
let u32_layout = ecx.layout_of(ecx.tcx.types.u32)?;
6865
let locked_count_place =
69-
mutex_place.offset(Size::from_bytes(4), MemPlaceMeta::None, u32_layout, ecx)?;
66+
mutex_place.offset(Size::from_bytes(4), MemPlaceMeta::None, ecx.u32_layout()?, ecx)?;
7067
ecx.read_scalar(locked_count_place.into())
7168
}
7269

@@ -78,9 +75,8 @@ fn mutex_set_locked_count<'mir, 'tcx: 'mir>(
7875
// Ensure that the following write at an offset to the mutex pointer is within bounds
7976
assert_ptr_target_min_size(ecx, mutex_op, 20)?;
8077
let mutex_place = ecx.deref_operand(mutex_op)?;
81-
let u32_layout = ecx.layout_of(ecx.tcx.types.u32)?;
8278
let locked_count_place =
83-
mutex_place.offset(Size::from_bytes(4), MemPlaceMeta::None, u32_layout, ecx)?;
79+
mutex_place.offset(Size::from_bytes(4), MemPlaceMeta::None, ecx.u32_layout()?, ecx)?;
8480
ecx.write_scalar(locked_count.into(), locked_count_place.into())
8581
}
8682

@@ -91,10 +87,13 @@ fn mutex_get_kind<'mir, 'tcx: 'mir>(
9187
// Ensure that the following read at an offset to the mutex pointer is within bounds
9288
assert_ptr_target_min_size(ecx, mutex_op, 20)?;
9389
let mutex_place = ecx.deref_operand(mutex_op)?;
94-
let i32_layout = ecx.layout_of(ecx.tcx.types.i32)?;
9590
let kind_offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
96-
let kind_place =
97-
mutex_place.offset(Size::from_bytes(kind_offset), MemPlaceMeta::None, i32_layout, ecx)?;
91+
let kind_place = mutex_place.offset(
92+
Size::from_bytes(kind_offset),
93+
MemPlaceMeta::None,
94+
ecx.i32_layout()?,
95+
ecx,
96+
)?;
9897
ecx.read_scalar(kind_place.into())
9998
}
10099

@@ -106,10 +105,13 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
106105
// Ensure that the following write at an offset to the mutex pointer is within bounds
107106
assert_ptr_target_min_size(ecx, mutex_op, 20)?;
108107
let mutex_place = ecx.deref_operand(mutex_op)?;
109-
let i32_layout = ecx.layout_of(ecx.tcx.types.i32)?;
110108
let kind_offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
111-
let kind_place =
112-
mutex_place.offset(Size::from_bytes(kind_offset), MemPlaceMeta::None, i32_layout, ecx)?;
109+
let kind_place = mutex_place.offset(
110+
Size::from_bytes(kind_offset),
111+
MemPlaceMeta::None,
112+
ecx.i32_layout()?,
113+
ecx,
114+
)?;
113115
ecx.write_scalar(kind.into(), kind_place.into())
114116
}
115117

@@ -128,9 +130,8 @@ fn rwlock_get_readers<'mir, 'tcx: 'mir>(
128130
// Ensure that the following read at an offset to the rwlock pointer is within bounds
129131
assert_ptr_target_min_size(ecx, rwlock_op, 12)?;
130132
let rwlock_place = ecx.deref_operand(rwlock_op)?;
131-
let u32_layout = ecx.layout_of(ecx.tcx.types.u32)?;
132133
let readers_place =
133-
rwlock_place.offset(Size::from_bytes(4), MemPlaceMeta::None, u32_layout, ecx)?;
134+
rwlock_place.offset(Size::from_bytes(4), MemPlaceMeta::None, ecx.u32_layout()?, ecx)?;
134135
ecx.read_scalar(readers_place.into())
135136
}
136137

@@ -142,9 +143,8 @@ fn rwlock_set_readers<'mir, 'tcx: 'mir>(
142143
// Ensure that the following write at an offset to the rwlock pointer is within bounds
143144
assert_ptr_target_min_size(ecx, rwlock_op, 12)?;
144145
let rwlock_place = ecx.deref_operand(rwlock_op)?;
145-
let u32_layout = ecx.layout_of(ecx.tcx.types.u32)?;
146146
let readers_place =
147-
rwlock_place.offset(Size::from_bytes(4), MemPlaceMeta::None, u32_layout, ecx)?;
147+
rwlock_place.offset(Size::from_bytes(4), MemPlaceMeta::None, ecx.u32_layout()?, ecx)?;
148148
ecx.write_scalar(readers.into(), readers_place.into())
149149
}
150150

@@ -155,9 +155,8 @@ fn rwlock_get_writers<'mir, 'tcx: 'mir>(
155155
// Ensure that the following read at an offset to the rwlock pointer is within bounds
156156
assert_ptr_target_min_size(ecx, rwlock_op, 12)?;
157157
let rwlock_place = ecx.deref_operand(rwlock_op)?;
158-
let u32_layout = ecx.layout_of(ecx.tcx.types.u32)?;
159158
let writers_place =
160-
rwlock_place.offset(Size::from_bytes(8), MemPlaceMeta::None, u32_layout, ecx)?;
159+
rwlock_place.offset(Size::from_bytes(8), MemPlaceMeta::None, ecx.u32_layout()?, ecx)?;
161160
ecx.read_scalar(writers_place.into())
162161
}
163162

@@ -169,9 +168,8 @@ fn rwlock_set_writers<'mir, 'tcx: 'mir>(
169168
// Ensure that the following write at an offset to the rwlock pointer is within bounds
170169
assert_ptr_target_min_size(ecx, rwlock_op, 12)?;
171170
let rwlock_place = ecx.deref_operand(rwlock_op)?;
172-
let u32_layout = ecx.layout_of(ecx.tcx.types.u32)?;
173171
let writers_place =
174-
rwlock_place.offset(Size::from_bytes(8), MemPlaceMeta::None, u32_layout, ecx)?;
172+
rwlock_place.offset(Size::from_bytes(8), MemPlaceMeta::None, ecx.u32_layout()?, ecx)?;
175173
ecx.write_scalar(writers.into(), writers_place.into())
176174
}
177175

0 commit comments

Comments
 (0)