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

Commit 17fc52a

Browse files
saethlinRalfJung
authored andcommitted
Clean up diff churn a bit, adjust comments
1 parent 14e72e7 commit 17fc52a

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/stacked_borrows/diagnostics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ impl<'ecx, 'mir, 'tcx, 'history> DiagnosticCx<'ecx, 'mir, 'tcx, 'history> {
370370
}
371371

372372
/// Report a descriptive error when `new` could not be granted from `derived_from`.
373+
#[inline(never)] // This is only called on fatal code paths
373374
pub fn grant_error(&self, perm: Permission, stack: &Stack) -> InterpError<'tcx> {
374375
let Operation::Retag(op) = &self.operation else {
375376
unreachable!("grant_error should only be called during a retag")
@@ -389,6 +390,7 @@ impl<'ecx, 'mir, 'tcx, 'history> DiagnosticCx<'ecx, 'mir, 'tcx, 'history> {
389390
}
390391

391392
/// Report a descriptive error when `access` is not permitted based on `tag`.
393+
#[inline(never)] // This is only called on fatal code paths
392394
pub fn access_error(&self, stack: &Stack) -> InterpError<'tcx> {
393395
let Operation::Access(op) = &self.operation else {
394396
unreachable!("access_error should only be called during an access")
@@ -407,6 +409,7 @@ impl<'ecx, 'mir, 'tcx, 'history> DiagnosticCx<'ecx, 'mir, 'tcx, 'history> {
407409
)
408410
}
409411

412+
#[inline(never)] // This is only called on fatal code paths
410413
pub fn protector_error(&self, item: &Item) -> InterpError<'tcx> {
411414
let call_id = self
412415
.threads
@@ -441,6 +444,7 @@ impl<'ecx, 'mir, 'tcx, 'history> DiagnosticCx<'ecx, 'mir, 'tcx, 'history> {
441444
}
442445
}
443446

447+
#[inline(never)] // This is only called on fatal code paths
444448
pub fn dealloc_error(&self) -> InterpError<'tcx> {
445449
let Operation::Dealloc(op) = &self.operation else {
446450
unreachable!("dealloc_error should only be called during a deallocation")

src/stacked_borrows/mod.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,19 @@ impl<'tcx> Stack {
296296
return Ok(());
297297
}
298298

299+
// We store tags twice, once in global.protected_tags and once in each call frame.
300+
// We do this because consulting a single global set in this function is faster
301+
// than attempting to search all call frames in the program for the `FrameExtra`
302+
// (if any) which is protecting the popped tag.
303+
//
304+
// This duplication trades off making `end_call` slower to make this function faster. This
305+
// trade-off is profitable in practice for a combination of two reasons.
306+
// 1. A single protected tag can (and does in some programs) protect thousands of `Item`s.
307+
// Therefore, adding overhead in function call/return is profitable even if it only
308+
// saves a little work in this function.
309+
// 2. Most frames protect only one or two tags. So this duplicative global turns a search
310+
// which ends up about linear in the number of protected tags in the program into a
311+
// constant time check (and a slow linear, because the tags in the frames aren't contiguous).
299312
if global.protected_tags.contains(&item.tag()) {
300313
return Err(dcx.protector_error(item).into());
301314
}
@@ -622,6 +635,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
622635
protect: bool,
623636
) -> InterpResult<'tcx, Option<AllocId>> {
624637
let this = self.eval_context_mut();
638+
let current_span = this.machine.current_span(*this.tcx);
625639

626640
// It is crucial that this gets called on all code paths, to ensure we track tag creation.
627641
let log_creation = |this: &MiriEvalContext<'mir, 'tcx>,
@@ -674,8 +688,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
674688
Ok(())
675689
};
676690

677-
let current_span = this.machine.current_span(*this.tcx);
678-
679691
if size == Size::ZERO {
680692
trace!(
681693
"reborrow of size 0: {} reference {:?} derived from {:?} (pointee {})",
@@ -726,19 +738,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
726738
);
727739

728740
if protect {
729-
// We store tags twice, once in global.protected_tags and once in each call frame.
730-
// We do this because consulting a single global set in this function is faster
731-
// than attempting to search all call frames in the program for the `FrameExtra`
732-
// (if any) which is protecting the popped tag.
733-
//
734-
// This duplication trades off making `end_call` slower to make this function faster. This
735-
// trade-off is profitable in practice for a combination of two reasons.
736-
// 1. A single protected tag can (and does in some programs) protect thousands of `Item`s.
737-
// Therefore, adding overhead to in function call/return is profitable even if it only
738-
// saves a little work in this function.
739-
// 2. Most frames protect only one or two tags. So this duplicative global turns a search
740-
// which ends up about linear in the number of protected tags in the program into a
741-
// constant time check (and a slow linear, because the tags in the frames aren't contiguous).
741+
// See comment in `Stack::item_popped` for why we store the tag twice.
742742
this.frame_mut().extra.stacked_borrows.as_mut().unwrap().protected_tags.push(new_tag);
743743
this.machine.stacked_borrows.as_mut().unwrap().get_mut().protected_tags.insert(new_tag);
744744
}
@@ -818,7 +818,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
818818
let range = alloc_range(base_offset, size);
819819
let mut global = machine.stacked_borrows.as_ref().unwrap().borrow_mut();
820820
let dcx = DiagnosticCxBuilder::retag(
821-
machine.current_span(tcx),
821+
machine.current_span(tcx), // `get_alloc_extra_mut` invalidated our old `current_span`
822822
&machine.threads,
823823
retag_cause,
824824
new_tag,

0 commit comments

Comments
 (0)