Skip to content

Commit a7c20d5

Browse files
Rollup merge of #152377 - Zalathar:active-job-guard, r=nnethercote
Rename the query system's `JobOwner` to `ActiveJobGuard`, and include `key_hash` `JobOwner` appears to have had more responsibilities in the past, but nowadays it's just a stack-guard object used by `execute_job` to poison the query state for the current key if some inner part of query execution panics. The new name and comments should hopefully be clearer about its (limited) role. I have also included a follow-up change that stores both the key and its previously-computed hash in the guard, instead of just the key. This avoids having to pass the key to `complete`, and avoids having to recompute the hash in `drop`. r? nnethercote (or compiler)
2 parents 170859a + d2dbd38 commit a7c20d5

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

compiler/rustc_middle/src/ty/context/tls.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ pub struct ImplicitCtxt<'a, 'tcx> {
1616
/// The current `TyCtxt`.
1717
pub tcx: TyCtxt<'tcx>,
1818

19-
/// The current query job, if any. This is updated by `JobOwner::start` in
20-
/// `ty::query::plumbing` when executing a query.
19+
/// The current query job, if any.
2120
pub query: Option<QueryJobId>,
2221

2322
/// Used to prevent queries from calling too deeply.

compiler/rustc_query_impl/src/execution.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,18 @@ pub(crate) fn gather_active_jobs_inner<'tcx, K: Copy>(
8383
Some(())
8484
}
8585

86-
/// A type representing the responsibility to execute the job in the `job` field.
87-
/// This will poison the relevant query if dropped.
88-
struct JobOwner<'tcx, K>
86+
/// Guard object representing the responsibility to execute a query job and
87+
/// mark it as completed.
88+
///
89+
/// This will poison the relevant query key if it is dropped without calling
90+
/// [`Self::complete`].
91+
struct ActiveJobGuard<'tcx, K>
8992
where
9093
K: Eq + Hash + Copy,
9194
{
9295
state: &'tcx QueryState<'tcx, K>,
9396
key: K,
97+
key_hash: u64,
9498
}
9599

96100
#[cold]
@@ -139,20 +143,19 @@ where
139143
}
140144
}
141145

142-
impl<'tcx, K> JobOwner<'tcx, K>
146+
impl<'tcx, K> ActiveJobGuard<'tcx, K>
143147
where
144148
K: Eq + Hash + Copy,
145149
{
146150
/// Completes the query by updating the query cache with the `result`,
147-
/// signals the waiter and forgets the JobOwner, so it won't poison the query
148-
fn complete<C>(self, cache: &C, key_hash: u64, result: C::Value, dep_node_index: DepNodeIndex)
151+
/// signals the waiter, and forgets the guard so it won't poison the query.
152+
fn complete<C>(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex)
149153
where
150154
C: QueryCache<Key = K>,
151155
{
152-
let key = self.key;
153-
let state = self.state;
154-
155-
// Forget ourself so our destructor won't poison the query
156+
// Forget ourself so our destructor won't poison the query.
157+
// (Extract fields by value first to make sure we don't leak anything.)
158+
let Self { state, key, key_hash }: Self = self;
156159
mem::forget(self);
157160

158161
// Mark as complete before we remove the job from the active state
@@ -176,19 +179,18 @@ where
176179
}
177180
}
178181

179-
impl<'tcx, K> Drop for JobOwner<'tcx, K>
182+
impl<'tcx, K> Drop for ActiveJobGuard<'tcx, K>
180183
where
181184
K: Eq + Hash + Copy,
182185
{
183186
#[inline(never)]
184187
#[cold]
185188
fn drop(&mut self) {
186189
// Poison the query so jobs waiting on it panic.
187-
let state = self.state;
190+
let Self { state, key, key_hash } = *self;
188191
let job = {
189-
let key_hash = sharded::make_hash(&self.key);
190192
let mut shard = state.active.lock_shard_by_hash(key_hash);
191-
match shard.find_entry(key_hash, equivalent_key(&self.key)) {
193+
match shard.find_entry(key_hash, equivalent_key(&key)) {
192194
Err(_) => panic!(),
193195
Ok(occupied) => {
194196
let ((key, value), vacant) = occupied.remove();
@@ -356,11 +358,13 @@ fn execute_job<'tcx, Q, const INCR: bool>(
356358
where
357359
Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>,
358360
{
359-
// Use `JobOwner` so the query will be poisoned if executing it panics.
360-
let job_owner = JobOwner { state, key };
361+
// Set up a guard object that will automatically poison the query if a
362+
// panic occurs while executing the query (or any intermediate plumbing).
363+
let job_guard = ActiveJobGuard { state, key, key_hash };
361364

362365
debug_assert_eq!(qcx.tcx.dep_graph.is_fully_enabled(), INCR);
363366

367+
// Delegate to another function to actually execute the query job.
364368
let (result, dep_node_index) = if INCR {
365369
execute_job_incr(query, qcx, qcx.tcx.dep_graph.data().unwrap(), key, dep_node, id)
366370
} else {
@@ -402,7 +406,9 @@ where
402406
}
403407
}
404408
}
405-
job_owner.complete(cache, key_hash, result, dep_node_index);
409+
410+
// Tell the guard to perform completion bookkeeping, and also to not poison the query.
411+
job_guard.complete(cache, result, dep_node_index);
406412

407413
(result, Some(dep_node_index))
408414
}

0 commit comments

Comments
 (0)