Skip to content

Commit 3bd0e8a

Browse files
committed
move checking ptr tracking on item pop into cold helper function
1 parent 4e9de31 commit 3bd0e8a

File tree

1 file changed

+62
-39
lines changed

1 file changed

+62
-39
lines changed

src/stacked_borrows.rs

+62-39
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,22 @@ impl<'tcx> Stack {
316316
alloc_history: &mut AllocHistory,
317317
threads: &ThreadManager<'_, 'tcx>,
318318
) -> InterpResult<'tcx> {
319-
if global.tracked_pointer_tags.contains(&item.tag()) {
320-
register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(
321-
*item,
322-
provoking_access.map(|(tag, _alloc_range, _size, access)| (tag, access)),
323-
));
319+
if !global.tracked_pointer_tags.is_empty() {
320+
check_tracked(item, &provoking_access, global);
321+
322+
#[inline(never)] // cold path
323+
fn check_tracked(
324+
item: &Item,
325+
provoking_access: &Option<(SbTagExtra, AllocRange, Size, AccessKind)>,
326+
global: &GlobalStateInner,
327+
) {
328+
if global.tracked_pointer_tags.contains(&item.tag()) {
329+
register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(
330+
*item,
331+
provoking_access.map(|(tag, _alloc_range, _size, access)| (tag, access)),
332+
));
333+
}
334+
}
324335
}
325336

326337
if !item.protected() {
@@ -341,40 +352,52 @@ impl<'tcx> Stack {
341352
// which ends up about linear in the number of protected tags in the program into a
342353
// constant time check (and a slow linear, because the tags in the frames aren't contiguous).
343354
if global.protected_tags.contains(&item.tag()) {
344-
// This path is cold because it is fatal to the program. So here it is fine to do the
345-
// more expensive search to figure out which call is responsible for protecting this
346-
// tag.
347-
let call_id = threads
348-
.all_stacks()
349-
.flatten()
350-
.map(|frame| {
351-
frame
352-
.extra
353-
.stacked_borrows
354-
.as_ref()
355-
.expect("we should have Stacked Borrows data")
356-
})
357-
.find(|frame| frame.protected_tags.contains(&item.tag()))
358-
.map(|frame| frame.call_id)
359-
.unwrap(); // FIXME: Surely we should find something, but a panic seems wrong here?
360-
if let Some((tag, _alloc_range, _offset, _access)) = provoking_access {
361-
Err(err_sb_ub(
362-
format!(
363-
"not granting access to tag {:?} because incompatible item {:?} is protected by call {:?}",
364-
tag, item, call_id
365-
),
366-
None,
367-
tag.and_then(|tag| alloc_history.get_logs_relevant_to(tag, Some(item.tag()))),
368-
))?
369-
} else {
370-
Err(err_sb_ub(
371-
format!(
372-
"deallocating while item {:?} is protected by call {:?}",
373-
item, call_id
374-
),
375-
None,
376-
None,
377-
))?
355+
return Err(protector_error(item, &provoking_access, alloc_history, threads));
356+
357+
#[inline(never)] // cold path
358+
fn protector_error<'tcx>(
359+
item: &Item,
360+
provoking_access: &Option<(SbTagExtra, AllocRange, Size, AccessKind)>,
361+
alloc_history: &mut AllocHistory,
362+
threads: &ThreadManager<'_, 'tcx>,
363+
) -> InterpErrorInfo<'tcx> {
364+
// This path is cold because it is fatal to the program. So here it is fine to do the
365+
// more expensive search to figure out which call is responsible for protecting this
366+
// tag.
367+
let call_id = threads
368+
.all_stacks()
369+
.flatten()
370+
.map(|frame| {
371+
frame
372+
.extra
373+
.stacked_borrows
374+
.as_ref()
375+
.expect("we should have Stacked Borrows data")
376+
})
377+
.find(|frame| frame.protected_tags.contains(&item.tag()))
378+
.map(|frame| frame.call_id)
379+
.unwrap(); // FIXME: Surely we should find something, but a panic seems wrong here?
380+
if let Some((tag, _alloc_range, _offset, _access)) = provoking_access {
381+
err_sb_ub(
382+
format!(
383+
"not granting access to tag {:?} because incompatible item {:?} is protected by call {:?}",
384+
tag, item, call_id
385+
),
386+
None,
387+
tag.and_then(|tag| {
388+
alloc_history.get_logs_relevant_to(tag, Some(item.tag()))
389+
}),
390+
)
391+
} else {
392+
err_sb_ub(
393+
format!(
394+
"deallocating while item {:?} is protected by call {:?}",
395+
item, call_id
396+
),
397+
None,
398+
None,
399+
)
400+
}.into()
378401
}
379402
}
380403
Ok(())

0 commit comments

Comments
 (0)