Skip to content

Commit 5861d13

Browse files
committed
Set the current span (somewhat) lazily
1 parent f3f7e08 commit 5861d13

File tree

5 files changed

+58
-33
lines changed

5 files changed

+58
-33
lines changed

src/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,10 @@ pub fn report_error<'tcx, 'mir>(
165165
];
166166
match history {
167167
Some(TagHistory::Tagged {tag, created: (created_range, created_span), invalidated, protected }) => {
168-
let msg = format!("{:?} was created due to a retag at offsets {}", tag, HexRange(*created_range));
168+
let msg = format!("{:?} was created by a retag at offsets {}", tag, HexRange(*created_range));
169169
helps.push((Some(created_span.clone()), msg));
170170
if let Some((invalidated_range, invalidated_span)) = invalidated {
171-
let msg = format!("{:?} was later invalidated due to a retag at offsets {}", tag, HexRange(*invalidated_range));
171+
let msg = format!("{:?} was later invalidated at offsets {}", tag, HexRange(*invalidated_range));
172172
helps.push((Some(invalidated_span.clone()), msg));
173173
}
174174
if let Some((protecting_tag, protecting_tag_span, protection_span)) = protected {

src/eval.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_target::spec::abi::Abi;
1616
use rustc_session::config::EntryFnType;
1717

1818
use std::collections::HashSet;
19+
use rustc_span::DUMMY_SP;
1920

2021
use crate::*;
2122

@@ -283,24 +284,6 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
283284
Ok((ecx, ret_place))
284285
}
285286

286-
// This is potentially a performance hazard.
287-
// Factoring it into its own function lets us keep an eye on how much it shows up in a profile.
288-
fn set_current_span<'mir, 'tcx: 'mir>(ecx: &mut MiriEvalContext<'mir, 'tcx>) {
289-
let current_span = Machine::stack(&ecx)
290-
.into_iter()
291-
.rev()
292-
.find(|frame| {
293-
let info =
294-
FrameInfo { instance: frame.instance, span: frame.current_span(), lint_root: None };
295-
ecx.machine.is_local(&info)
296-
})
297-
.map(|frame| frame.current_span())
298-
.unwrap_or(rustc_span::DUMMY_SP);
299-
if let Some(sb) = ecx.machine.stacked_borrows.as_mut() {
300-
sb.get_mut().current_span = current_span;
301-
}
302-
}
303-
304287
/// Evaluates the entry function specified by `entry_id`.
305288
/// Returns `Some(return_code)` if program executed completed.
306289
/// Returns `None` if an evaluation error occured.
@@ -328,8 +311,8 @@ pub fn eval_entry<'tcx>(
328311
let info = ecx.preprocess_diagnostics();
329312
match ecx.schedule()? {
330313
SchedulingAction::ExecuteStep => {
331-
if ecx.machine.stacked_borrows.is_some() {
332-
set_current_span(&mut ecx);
314+
if let Some(sb) = ecx.machine.stacked_borrows.as_mut() {
315+
sb.get_mut().current_span = DUMMY_SP;
333316
}
334317
assert!(ecx.step()?, "a terminated thread was scheduled for execution");
335318
}

src/machine.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_middle::{
2525
};
2626
use rustc_span::def_id::{CrateNum, DefId};
2727
use rustc_span::symbol::{sym, Symbol};
28+
use rustc_span::DUMMY_SP;
2829
use rustc_target::abi::Size;
2930
use rustc_target::spec::abi::Abi;
3031

@@ -561,6 +562,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
561562
alloc: Cow<'b, Allocation>,
562563
kind: Option<MemoryKind<Self::MemoryKind>>,
563564
) -> Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>> {
565+
set_current_span(&ecx.machine);
564566
if ecx.machine.tracked_alloc_ids.contains(&id) {
565567
register_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id));
566568
}
@@ -589,6 +591,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
589591
ecx: &MiriEvalContext<'mir, 'tcx>,
590592
ptr: Pointer<AllocId>,
591593
) -> Pointer<Tag> {
594+
set_current_span(&ecx.machine);
592595
let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr);
593596
let sb_tag = if let Some(stacked_borrows) = &ecx.machine.stacked_borrows {
594597
stacked_borrows.borrow_mut().base_tag(ptr.provenance)
@@ -624,6 +627,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
624627
(alloc_id, tag): (AllocId, Self::TagExtra),
625628
range: AllocRange,
626629
) -> InterpResult<'tcx> {
630+
set_current_span(&machine);
627631
if let Some(data_race) = &alloc_extra.data_race {
628632
data_race.read(alloc_id, range, machine.data_race.as_ref().unwrap())?;
629633
}
@@ -632,7 +636,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
632636
alloc_id,
633637
tag,
634638
range,
635-
machine.stacked_borrows.as_ref().unwrap(),
639+
machine.stacked_borrows.as_ref().unwrap(),
636640
)
637641
} else {
638642
Ok(())
@@ -647,6 +651,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
647651
(alloc_id, tag): (AllocId, Self::TagExtra),
648652
range: AllocRange,
649653
) -> InterpResult<'tcx> {
654+
set_current_span(&machine);
650655
if let Some(data_race) = &mut alloc_extra.data_race {
651656
data_race.write(alloc_id, range, machine.data_race.as_mut().unwrap())?;
652657
}
@@ -670,6 +675,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
670675
(alloc_id, tag): (AllocId, Self::TagExtra),
671676
range: AllocRange,
672677
) -> InterpResult<'tcx> {
678+
set_current_span(&machine);
673679
if machine.tracked_alloc_ids.contains(&alloc_id) {
674680
register_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id));
675681
}
@@ -694,7 +700,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
694700
kind: mir::RetagKind,
695701
place: &PlaceTy<'tcx, Tag>,
696702
) -> InterpResult<'tcx> {
697-
if ecx.machine.stacked_borrows.is_some() { ecx.retag(kind, place) } else { Ok(()) }
703+
if ecx.machine.stacked_borrows.is_some() {
704+
set_current_span(&ecx.machine);
705+
ecx.retag(kind, place)
706+
} else {
707+
Ok(())
708+
}
698709
}
699710

700711
#[inline(always)]
@@ -740,7 +751,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
740751

741752
#[inline(always)]
742753
fn after_stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
743-
if ecx.machine.stacked_borrows.is_some() { ecx.retag_return_place() } else { Ok(()) }
754+
if ecx.machine.stacked_borrows.is_some() {
755+
set_current_span(&ecx.machine);
756+
ecx.retag_return_place()
757+
} else {
758+
Ok(())
759+
}
744760
}
745761

746762
#[inline(always)]
@@ -757,3 +773,29 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
757773
res
758774
}
759775
}
776+
777+
// This is potentially a performance hazard.
778+
// Factoring it into its own function lets us keep an eye on how much it shows up in a profile.
779+
fn set_current_span<'mir, 'tcx: 'mir>(machine: &Evaluator<'mir, 'tcx>) {
780+
if let Some(sb) = machine.stacked_borrows.as_ref() {
781+
if sb.borrow().current_span != DUMMY_SP {
782+
return;
783+
}
784+
let current_span = machine
785+
.threads
786+
.active_thread_stack()
787+
.into_iter()
788+
.rev()
789+
.find(|frame| {
790+
let info = FrameInfo {
791+
instance: frame.instance,
792+
span: frame.current_span(),
793+
lint_root: None,
794+
};
795+
machine.is_local(&info)
796+
})
797+
.map(|frame| frame.current_span())
798+
.unwrap_or(rustc_span::DUMMY_SP);
799+
sb.borrow_mut().current_span = current_span;
800+
}
801+
}

src/stacked_borrows.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ struct AllocHistory {
125125
// The time tags can be compressed down to one bit per event, by just storing a Vec<u8>
126126
// where each bit is set to indicate if the event was a creation or a retag
127127
current_time: usize,
128-
creations: Vec<Event>,
129-
invalidations: Vec<Event>,
130-
protectors: Vec<Protection>,
128+
creations: smallvec::SmallVec<[Event; 2]>,
129+
invalidations: smallvec::SmallVec<[Event; 1]>,
130+
protectors: smallvec::SmallVec<[Protection; 1]>,
131131
}
132132

133133
#[derive(Debug)]
@@ -552,9 +552,9 @@ impl<'tcx> Stack {
552552
// Two main steps: Find granting item, remove incompatible items above.
553553

554554
// Step 1: Find granting item.
555-
let granting_idx = self.find_granting(access, tag).ok_or_else(|| {
556-
self.access_error(access, tag, alloc_id, alloc_range, offset, global)
557-
})?;
555+
let granting_idx = self
556+
.find_granting(access, tag)
557+
.ok_or_else(|| self.access_error(access, tag, alloc_id, alloc_range, offset, global))?;
558558

559559
// Step 2: Remove incompatible items above them. Make sure we do not remove protected
560560
// items. Behavior differs for reads and writes.
@@ -852,7 +852,7 @@ impl Stacks {
852852
let mut state = state.borrow_mut();
853853
stack.access(AccessKind::Read, tag, (alloc_id, range, offset), &mut state)
854854
})
855-
}
855+
}
856856

857857
#[inline(always)]
858858
pub fn memory_written<'tcx>(

src/thread.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
263263
}
264264

265265
/// Borrow the stack of the active thread.
266-
fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Tag, FrameData<'tcx>>] {
266+
pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Tag, FrameData<'tcx>>] {
267267
&self.threads[self.active_thread].stack
268268
}
269269

0 commit comments

Comments
 (0)