Skip to content

Commit 19c1012

Browse files
committed
Use a counter instead of pointers to the stack
1 parent 77ab0d0 commit 19c1012

File tree

5 files changed

+117
-76
lines changed

5 files changed

+117
-76
lines changed

src/librustc/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ pub mod tls {
16331633

16341634
/// The current query job, if any. This is updated by `JobOwner::start` in
16351635
/// `ty::query::plumbing` when executing a query.
1636-
pub query: Option<query::QueryToken>,
1636+
pub query: Option<query::QueryJobId>,
16371637

16381638
/// Where to store diagnostics for the current query job, if any.
16391639
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.

src/librustc/ty/query/job.rs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::dep_graph::DepKind;
12
use crate::ty::context::TyCtxt;
23
use crate::ty::query::plumbing::CycleError;
34
use crate::ty::query::Query;
@@ -7,7 +8,7 @@ use rustc_data_structures::fx::FxHashMap;
78
use rustc_span::Span;
89

910
use std::marker::PhantomData;
10-
use std::num::NonZeroUsize;
11+
use std::num::NonZeroU32;
1112

1213
#[cfg(parallel_compiler)]
1314
use {
@@ -31,19 +32,26 @@ pub struct QueryInfo<'tcx> {
3132
pub query: Query<'tcx>,
3233
}
3334

34-
type QueryMap<'tcx> = FxHashMap<QueryToken, QueryJobInfo<'tcx>>;
35+
type QueryMap<'tcx> = FxHashMap<QueryJobId, QueryJobInfo<'tcx>>;
36+
37+
/// A value uniquely identifiying an active query job within a shard in the query cache.
38+
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
39+
pub struct QueryShardJobId(pub NonZeroU32);
3540

3641
/// A value uniquely identifiying an active query job.
37-
/// This value is created from a stack pointer in `get_query` and `force_query`
38-
/// which is alive while the query executes.
3942
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
40-
pub struct QueryToken(NonZeroUsize);
43+
pub struct QueryJobId {
44+
/// Which job within a shard is this
45+
pub job: QueryShardJobId,
4146

42-
impl QueryToken {
43-
pub fn from<T>(v: &T) -> Self {
44-
QueryToken(NonZeroUsize::new(v as *const T as usize).unwrap())
45-
}
47+
/// In which shard is this job
48+
pub shard: u16,
49+
50+
/// What kind of query this job is
51+
pub kind: DepKind,
52+
}
4653

54+
impl QueryJobId {
4755
fn query<'tcx>(self, map: &QueryMap<'tcx>) -> Query<'tcx> {
4856
map.get(&self).unwrap().info.query.clone()
4957
}
@@ -54,7 +62,7 @@ impl QueryToken {
5462
}
5563

5664
#[cfg(parallel_compiler)]
57-
fn parent(self, map: &QueryMap<'_>) -> Option<QueryToken> {
65+
fn parent(self, map: &QueryMap<'_>) -> Option<QueryJobId> {
5866
map.get(&self).unwrap().job.parent
5967
}
6068

@@ -72,13 +80,13 @@ pub struct QueryJobInfo<'tcx> {
7280
/// Represents an active query job.
7381
#[derive(Clone)]
7482
pub struct QueryJob<'tcx> {
75-
pub token: QueryToken,
83+
pub id: QueryShardJobId,
7684

7785
/// The span corresponding to the reason for which this query was required.
7886
pub span: Span,
7987

8088
/// The parent query job which created this job and is implicitly waiting on it.
81-
pub parent: Option<QueryToken>,
89+
pub parent: Option<QueryJobId>,
8290

8391
/// The latch that is used to wait on this job.
8492
#[cfg(parallel_compiler)]
@@ -89,9 +97,9 @@ pub struct QueryJob<'tcx> {
8997

9098
impl<'tcx> QueryJob<'tcx> {
9199
/// Creates a new query job.
92-
pub fn new(token: QueryToken, span: Span, parent: Option<QueryToken>) -> Self {
100+
pub fn new(id: QueryShardJobId, span: Span, parent: Option<QueryJobId>) -> Self {
93101
QueryJob {
94-
token,
102+
id,
95103
span,
96104
parent,
97105
#[cfg(parallel_compiler)]
@@ -101,16 +109,16 @@ impl<'tcx> QueryJob<'tcx> {
101109
}
102110

103111
#[cfg(parallel_compiler)]
104-
pub(super) fn latch(&mut self) -> QueryLatch<'tcx> {
112+
pub(super) fn latch(&mut self, _id: QueryJobId) -> QueryLatch<'tcx> {
105113
if self.latch.is_none() {
106114
self.latch = Some(QueryLatch::new());
107115
}
108116
self.latch.as_ref().unwrap().clone()
109117
}
110118

111119
#[cfg(not(parallel_compiler))]
112-
pub(super) fn latch(&mut self) -> QueryLatch<'tcx> {
113-
QueryLatch { token: self.token, dummy: PhantomData }
120+
pub(super) fn latch(&mut self, id: QueryJobId) -> QueryLatch<'tcx> {
121+
QueryLatch { id, dummy: PhantomData }
114122
}
115123

116124
/// Signals to waiters that the query is complete.
@@ -126,7 +134,7 @@ impl<'tcx> QueryJob<'tcx> {
126134
#[cfg(not(parallel_compiler))]
127135
#[derive(Clone)]
128136
pub(super) struct QueryLatch<'tcx> {
129-
token: QueryToken,
137+
id: QueryJobId,
130138
dummy: PhantomData<&'tcx ()>,
131139
}
132140

@@ -143,7 +151,7 @@ impl<'tcx> QueryLatch<'tcx> {
143151
let info = query_map.get(&job).unwrap();
144152
cycle.push(info.info.clone());
145153

146-
if job == self.token {
154+
if job == self.id {
147155
cycle.reverse();
148156

149157
// This is the end of the cycle
@@ -169,7 +177,7 @@ impl<'tcx> QueryLatch<'tcx> {
169177

170178
#[cfg(parallel_compiler)]
171179
struct QueryWaiter<'tcx> {
172-
query: Option<QueryToken>,
180+
query: Option<QueryJobId>,
173181
condvar: Condvar,
174182
span: Span,
175183
cycle: Lock<Option<CycleError<'tcx>>>,
@@ -270,7 +278,7 @@ impl<'tcx> QueryLatch<'tcx> {
270278

271279
/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
272280
#[cfg(parallel_compiler)]
273-
type Waiter = (QueryToken, usize);
281+
type Waiter = (QueryJobId, usize);
274282

275283
/// Visits all the non-resumable and resumable waiters of a query.
276284
/// Only waiters in a query are visited.
@@ -284,11 +292,11 @@ type Waiter = (QueryToken, usize);
284292
#[cfg(parallel_compiler)]
285293
fn visit_waiters<'tcx, F>(
286294
query_map: &QueryMap<'tcx>,
287-
query: QueryToken,
295+
query: QueryJobId,
288296
mut visit: F,
289297
) -> Option<Option<Waiter>>
290298
where
291-
F: FnMut(Span, QueryToken) -> Option<Option<Waiter>>,
299+
F: FnMut(Span, QueryJobId) -> Option<Option<Waiter>>,
292300
{
293301
// Visit the parent query which is a non-resumable waiter since it's on the same stack
294302
if let Some(parent) = query.parent(query_map) {
@@ -319,10 +327,10 @@ where
319327
#[cfg(parallel_compiler)]
320328
fn cycle_check<'tcx>(
321329
query_map: &QueryMap<'tcx>,
322-
query: QueryToken,
330+
query: QueryJobId,
323331
span: Span,
324-
stack: &mut Vec<(Span, QueryToken)>,
325-
visited: &mut FxHashSet<QueryToken>,
332+
stack: &mut Vec<(Span, QueryJobId)>,
333+
visited: &mut FxHashSet<QueryJobId>,
326334
) -> Option<Option<Waiter>> {
327335
if !visited.insert(query) {
328336
return if let Some(p) = stack.iter().position(|q| q.1 == query) {
@@ -360,8 +368,8 @@ fn cycle_check<'tcx>(
360368
#[cfg(parallel_compiler)]
361369
fn connected_to_root<'tcx>(
362370
query_map: &QueryMap<'tcx>,
363-
query: QueryToken,
364-
visited: &mut FxHashSet<QueryToken>,
371+
query: QueryJobId,
372+
visited: &mut FxHashSet<QueryJobId>,
365373
) -> bool {
366374
// We already visited this or we're deliberately ignoring it
367375
if !visited.insert(query) {
@@ -381,7 +389,7 @@ fn connected_to_root<'tcx>(
381389

382390
// Deterministically pick an query from a list
383391
#[cfg(parallel_compiler)]
384-
fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryToken)>(
392+
fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryJobId)>(
385393
query_map: &QueryMap<'tcx>,
386394
tcx: TyCtxt<'tcx>,
387395
queries: &'a [T],
@@ -413,7 +421,7 @@ fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryToken)>(
413421
#[cfg(parallel_compiler)]
414422
fn remove_cycle<'tcx>(
415423
query_map: &QueryMap<'tcx>,
416-
jobs: &mut Vec<QueryToken>,
424+
jobs: &mut Vec<QueryJobId>,
417425
wakelist: &mut Vec<Lrc<QueryWaiter<'tcx>>>,
418426
tcx: TyCtxt<'tcx>,
419427
) -> bool {
@@ -468,7 +476,7 @@ fn remove_cycle<'tcx>(
468476
}
469477
}
470478
})
471-
.collect::<Vec<(Span, QueryToken, Option<(Span, QueryToken)>)>>();
479+
.collect::<Vec<(Span, QueryJobId, Option<(Span, QueryJobId)>)>>();
472480

473481
// Deterministically pick an entry point
474482
let (_, entry_point, usage) = pick_query(query_map, tcx, &entry_points, |e| (e.0, e.1));
@@ -548,7 +556,7 @@ fn deadlock(tcx: TyCtxt<'_>, registry: &rayon_core::Registry) {
548556

549557
let mut wakelist = Vec::new();
550558
let query_map = tcx.queries.try_collect_active_jobs().unwrap();
551-
let mut jobs: Vec<QueryToken> = query_map.keys().cloned().collect();
559+
let mut jobs: Vec<QueryJobId> = query_map.keys().cloned().collect();
552560

553561
let mut found_cycle = false;
554562

src/librustc/ty/query/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use rustc_span::symbol::Symbol;
5454
use rustc_span::{Span, DUMMY_SP};
5555
use std::any::type_name;
5656
use std::borrow::Cow;
57+
use std::convert::TryFrom;
5758
use std::ops::Deref;
5859
use std::sync::Arc;
5960
use syntax::ast;
@@ -67,7 +68,7 @@ mod job;
6768
#[cfg(parallel_compiler)]
6869
pub use self::job::handle_deadlock;
6970
use self::job::QueryJobInfo;
70-
pub use self::job::{QueryInfo, QueryJob, QueryToken};
71+
pub use self::job::{QueryInfo, QueryJob, QueryJobId};
7172

7273
mod keys;
7374
use self::keys::Key;

0 commit comments

Comments
 (0)