Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 3cb27f5

Browse files
committed
avoid thread-local var indirection for non-halting diagnostics
1 parent 4b9463c commit 3cb27f5

File tree

9 files changed

+133
-200
lines changed

9 files changed

+133
-200
lines changed

src/concurrency/weak_memory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
544544
validate,
545545
)?;
546546
if global.track_outdated_loads && recency == LoadRecency::Outdated {
547-
register_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad);
547+
this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad);
548548
}
549549

550550
return Ok(loaded);

src/diagnostics.rs

Lines changed: 105 additions & 172 deletions
Large diffs are not rendered by default.

src/eval.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,6 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
190190
Evaluator::new(config, layout_cx),
191191
);
192192

193-
// Capture the current interpreter stack state (which should be empty) so that we can emit
194-
// allocation-tracking and tag-tracking diagnostics for allocations which are part of the
195-
// early runtime setup.
196-
let info = ecx.preprocess_diagnostics();
197-
198193
// Some parts of initialization require a full `InterpCx`.
199194
Evaluator::late_init(&mut ecx, config)?;
200195

@@ -324,10 +319,6 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
324319
}
325320
}
326321

327-
// Emit any diagnostics related to the setup process for the runtime, so that when the
328-
// interpreter loop starts there are no unprocessed diagnostics.
329-
ecx.process_diagnostics(info);
330-
331322
Ok((ecx, ret_place))
332323
}
333324

@@ -356,7 +347,6 @@ pub fn eval_entry<'tcx>(
356347
let res: thread::Result<InterpResult<'_, i64>> = panic::catch_unwind(AssertUnwindSafe(|| {
357348
// Main loop.
358349
loop {
359-
let info = ecx.preprocess_diagnostics();
360350
match ecx.schedule()? {
361351
SchedulingAction::ExecuteStep => {
362352
assert!(ecx.step()?, "a terminated thread was scheduled for execution");
@@ -374,7 +364,6 @@ pub fn eval_entry<'tcx>(
374364
break;
375365
}
376366
}
377-
ecx.process_diagnostics(info);
378367
}
379368
let return_code = ecx.read_scalar(&ret_place.into())?.to_machine_isize(&ecx)?;
380369
Ok(return_code)

src/helpers.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
508508
Ok(())
509509
}
510510
RejectOpWith::Warning => {
511-
register_diagnostic(NonHaltingDiagnostic::RejectedIsolatedOp(op_name.to_string()));
511+
this.emit_diagnostic(NonHaltingDiagnostic::RejectedIsolatedOp(op_name.to_string()));
512512
Ok(())
513513
}
514514
RejectOpWith::NoWarning => Ok(()), // no warning
@@ -881,6 +881,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
881881
None => tcx.item_name(def_id),
882882
}
883883
}
884+
885+
fn current_span(&self) -> CurrentSpan<'_, 'mir, 'tcx> {
886+
let this = self.eval_context_ref();
887+
CurrentSpan { current_frame_idx: None, machine: &this.machine, tcx: *this.tcx }
888+
}
884889
}
885890

886891
impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
@@ -901,6 +906,12 @@ pub struct CurrentSpan<'a, 'mir, 'tcx> {
901906
}
902907

903908
impl<'a, 'mir: 'a, 'tcx: 'a + 'mir> CurrentSpan<'a, 'mir, 'tcx> {
909+
/// Not really about the `CurrentSpan`, but we just happen to have all the things needed to emit
910+
/// diagnostics like that.
911+
pub fn emit_diagnostic(&self, e: NonHaltingDiagnostic) {
912+
emit_diagnostic(e, self.machine, self.tcx);
913+
}
914+
904915
/// Get the current span, skipping non-local frames.
905916
/// This function is backed by a cache, and can be assumed to be very fast.
906917
pub fn get(&mut self) -> Span {

src/intptrcast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<'mir, 'tcx> GlobalStateInner {
142142
let first = past_warnings.is_empty();
143143
if past_warnings.insert(ecx.cur_span()) {
144144
// Newly inserted, so first time we see this span.
145-
register_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
145+
ecx.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
146146
}
147147
});
148148
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub use crate::concurrency::{
9494
},
9595
};
9696
pub use crate::diagnostics::{
97-
register_diagnostic, report_error, EvalContextExt as DiagnosticsEvalContextExt,
97+
emit_diagnostic, report_error, EvalContextExt as DiagnosticsEvalContextExt,
9898
NonHaltingDiagnostic, TerminationInfo,
9999
};
100100
pub use crate::eval::{

src/machine.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
755755
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> {
756756
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
757757
if ecx.machine.tracked_alloc_ids.contains(&id) {
758-
register_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
758+
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
759759
id,
760760
alloc.size(),
761761
alloc.align,
@@ -813,7 +813,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
813813
}
814814
let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr);
815815
let sb_tag = if let Some(stacked_borrows) = &ecx.machine.stacked_borrows {
816-
stacked_borrows.borrow_mut().base_ptr_tag(ptr.provenance)
816+
stacked_borrows.borrow_mut().base_ptr_tag(ptr.provenance, &ecx.current_span())
817817
} else {
818818
// Value does not matter, SB is disabled
819819
SbTag::default()
@@ -937,7 +937,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
937937
range: AllocRange,
938938
) -> InterpResult<'tcx> {
939939
if machine.tracked_alloc_ids.contains(&alloc_id) {
940-
register_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id));
940+
emit_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id), machine, tcx);
941941
}
942942
if let Some(data_race) = &mut alloc_extra.data_race {
943943
data_race.deallocate(
@@ -993,7 +993,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
993993
let stacked_borrows = ecx.machine.stacked_borrows.as_ref();
994994

995995
let extra = FrameData {
996-
stacked_borrows: stacked_borrows.map(|sb| sb.borrow_mut().new_frame()),
996+
stacked_borrows: stacked_borrows.map(|sb| sb.borrow_mut().new_frame(&ecx.current_span())),
997997
catch_unwind: None,
998998
timing,
999999
};
@@ -1018,7 +1018,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
10181018
// Possibly report our progress.
10191019
if let Some(report_progress) = ecx.machine.report_progress {
10201020
if ecx.machine.basic_block_count % u64::from(report_progress) == 0 {
1021-
register_diagnostic(NonHaltingDiagnostic::ProgressReport {
1021+
ecx.emit_diagnostic(NonHaltingDiagnostic::ProgressReport {
10221022
block_count: ecx.machine.basic_block_count,
10231023
});
10241024
}

src/stacked_borrows/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir
471471
Some((orig_tag, kind))
472472
}
473473
};
474-
register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(*item, summary));
474+
self.current_span.emit_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(*item, summary));
475475
}
476476
}
477477

src/stacked_borrows/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,11 @@ impl GlobalStateInner {
178178
id
179179
}
180180

181-
pub fn new_frame(&mut self) -> FrameExtra {
181+
pub fn new_frame(&mut self, current_span: &CurrentSpan<'_, '_, '_>) -> FrameExtra {
182182
let call_id = self.next_call_id;
183183
trace!("new_frame: Assigning call ID {}", call_id);
184184
if self.tracked_call_ids.contains(&call_id) {
185-
register_diagnostic(NonHaltingDiagnostic::CreatedCallId(call_id));
185+
current_span.emit_diagnostic(NonHaltingDiagnostic::CreatedCallId(call_id));
186186
}
187187
self.next_call_id = NonZeroU64::new(call_id.get() + 1).unwrap();
188188
FrameExtra { call_id, protected_tags: SmallVec::new() }
@@ -199,11 +199,11 @@ impl GlobalStateInner {
199199
}
200200
}
201201

202-
pub fn base_ptr_tag(&mut self, id: AllocId) -> SbTag {
202+
pub fn base_ptr_tag(&mut self, id: AllocId, current_span: &CurrentSpan<'_, '_, '_>) -> SbTag {
203203
self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| {
204204
let tag = self.new_ptr();
205205
if self.tracked_pointer_tags.contains(&tag) {
206-
register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(tag.0, None));
206+
current_span.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(tag.0, None));
207207
}
208208
trace!("New allocation {:?} has base tag {:?}", id, tag);
209209
self.base_ptr_tags.try_insert(id, tag).unwrap();
@@ -572,9 +572,9 @@ impl Stacks {
572572
// not through a pointer). That is, whenever we directly write to a local, this will pop
573573
// everything else off the stack, invalidating all previous pointers,
574574
// and in particular, *all* raw pointers.
575-
MemoryKind::Stack => (extra.base_ptr_tag(id), Permission::Unique),
575+
MemoryKind::Stack => (extra.base_ptr_tag(id, &current_span), Permission::Unique),
576576
// Everything else is shared by default.
577-
_ => (extra.base_ptr_tag(id), Permission::SharedReadWrite),
577+
_ => (extra.base_ptr_tag(id, &current_span), Permission::SharedReadWrite),
578578
};
579579
Stacks::new(size, perm, base_tag, id, &mut current_span)
580580
}
@@ -674,7 +674,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriEvalContextEx
674674
-> InterpResult<'tcx> {
675675
let global = this.machine.stacked_borrows.as_ref().unwrap().borrow();
676676
if global.tracked_pointer_tags.contains(&new_tag) {
677-
register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
677+
this.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
678678
new_tag.0,
679679
loc.map(|(alloc_id, base_offset, _)| (alloc_id, alloc_range(base_offset, size))),
680680
));

0 commit comments

Comments
 (0)