-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track local frames incrementally during execution #2647
Conversation
f0aa729
to
cd78f83
Compare
So those benchmarks are without #2646? |
Yes. That PR adds extra work to the data race machinery in order to store the spans which has its own very small regression, so I wanted to keep the effects separate. |
I think this is ready for re-review. Not quite ready for merge yet IMO, I think the cache invalidation might be a bit too aggressive based on a glance at the benchmarks... |
8f184d3
to
c9430d9
Compare
LGTM, what are the benchmarks saying? How could the cache be invalidated less aggressively than on each pop? |
I force-pushed after making this comment. Previously I was invalidating on every pop, not just pops of local frames. Most frames we create are in the standard library. |
cbe3146
to
cc99f2a
Compare
I updated the PR description. We have the same marginal improvement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All right so this is a simplification without perf loss. I like it, just some nits.
☔ The latest upstream changes (presumably #2684) made this pull request unmergeable. Please resolve the merge conflicts. |
cc99f2a
to
5c72788
Compare
Co-authored-by: Ralf Jung <post@ralfj.de>
Co-authored-by: Ralf Jung <post@ralfj.de>
src/helpers.rs
Outdated
let frame_idx = cmp::min(frame_idx, stack.len().saturating_sub(2)); | ||
stack.get(frame_idx).map(Frame::current_span).unwrap_or(rustc_span::DUMMY_SP) | ||
self.top_user_relevant_frame() | ||
.map(|frame_idx| cmp::min(frame_idx, self.stack().len() - 2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes semantics I think?
.map(|frame_idx| cmp::min(frame_idx, self.stack().len() - 2)) | |
.map(|frame_idx| cmp::min(frame_idx, self.stack().len().saturating_sub(2))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to ask for the caller span (especially in an FnEntry retag) when we have one stack frame? I wrote this thinking "no, that would be a bug, so a crash would be good"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then it should be checked_sub(2).unwrap()
@bors r+ |
☀️ Test successful - checks-actions |
Data race spans Fixes #2205 This adds output to data race errors very similar to the spans we emit for Stacked Borrows errors. For example, from our test suite: ``` help: The Atomic Load on thread `<unnamed>` is here --> tests/fail/data_race/atomic_read_na_write_race1.rs:23:13 | 23 | ... (&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between Atomic Load on thread `<unnamed>` and Write o... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: The Write on thread `<unnamed>` is here --> tests/fail/data_race/atomic_read_na_write_race1.rs:19:13 | 19 | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^``` ``` Because of #2647 this comes without a perf regression, according to our benchmarks.
Data race spans Fixes rust-lang/miri#2205 This adds output to data race errors very similar to the spans we emit for Stacked Borrows errors. For example, from our test suite: ``` help: The Atomic Load on thread `<unnamed>` is here --> tests/fail/data_race/atomic_read_na_write_race1.rs:23:13 | 23 | ... (&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between Atomic Load on thread `<unnamed>` and Write o... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: The Write on thread `<unnamed>` is here --> tests/fail/data_race/atomic_read_na_write_race1.rs:19:13 | 19 | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^``` ``` Because of rust-lang/miri#2647 this comes without a perf regression, according to our benchmarks.
#2646 currently introduces a performance regression. This change removes that regression, and provides a minor perf improvement.
The existing lazy strategy for tracking the span we want to display is as efficient as it is only because we often create a
CurrentSpan
then never call.get()
. Most of the calls to thebefore_memory_read
andbefore_memory_write
hooks do not create any event that we store inAllocHistory
. But data races are totally different, any memory read or write may race, so every call to those hooks needs to access to the current local span.So this changes to a strategy where we update some state in a
Thread
andFrameExtra
incrementally, upon entering and existing each function call.Before:
After:
(This change is marginal, but the point is that it avoids a much more significant regression)