diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /compiler/rustc_query_system/src/query/job.rs | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_query_system/src/query/job.rs')
-rw-r--r-- | compiler/rustc_query_system/src/query/job.rs | 110 |
1 files changed, 64 insertions, 46 deletions
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 49bbcf578..a5a2f0093 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -1,6 +1,8 @@ +use crate::dep_graph::DepKind; use crate::error::CycleStack; use crate::query::plumbing::CycleError; use crate::query::{QueryContext, QueryStackFrame}; +use core::marker::PhantomData; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{ @@ -22,54 +24,54 @@ use { rustc_data_structures::{jobserver, OnDrop}, rustc_rayon_core as rayon_core, rustc_span::DUMMY_SP, - std::iter::{self, FromIterator}, - std::{mem, process}, + std::iter, + std::process, }; /// Represents a span and a query key. #[derive(Clone, Debug)] -pub struct QueryInfo { +pub struct QueryInfo<D: DepKind> { /// The span corresponding to the reason for which this query was required. pub span: Span, - pub query: QueryStackFrame, + pub query: QueryStackFrame<D>, } -pub type QueryMap = FxHashMap<QueryJobId, QueryJobInfo>; +pub type QueryMap<D> = FxHashMap<QueryJobId, QueryJobInfo<D>>; /// A value uniquely identifying an active query job. #[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct QueryJobId(pub NonZeroU64); impl QueryJobId { - fn query(self, map: &QueryMap) -> QueryStackFrame { + fn query<D: DepKind>(self, map: &QueryMap<D>) -> QueryStackFrame<D> { map.get(&self).unwrap().query.clone() } #[cfg(parallel_compiler)] - fn span(self, map: &QueryMap) -> Span { + fn span<D: DepKind>(self, map: &QueryMap<D>) -> Span { map.get(&self).unwrap().job.span } #[cfg(parallel_compiler)] - fn parent(self, map: &QueryMap) -> Option<QueryJobId> { + fn parent<D: DepKind>(self, map: &QueryMap<D>) -> Option<QueryJobId> { map.get(&self).unwrap().job.parent } #[cfg(parallel_compiler)] - fn latch<'a>(self, map: &'a QueryMap) -> Option<&'a QueryLatch> { + fn latch<D: DepKind>(self, map: &QueryMap<D>) -> Option<&QueryLatch<D>> { map.get(&self).unwrap().job.latch.as_ref() } } #[derive(Clone)] -pub struct QueryJobInfo { - pub query: QueryStackFrame, - pub job: QueryJob, +pub struct QueryJobInfo<D: DepKind> { + pub query: QueryStackFrame<D>, + pub job: QueryJob<D>, } /// Represents an active query job. #[derive(Clone)] -pub struct QueryJob { +pub struct QueryJob<D: DepKind> { pub id: QueryJobId, /// The span corresponding to the reason for which this query was required. @@ -80,10 +82,11 @@ pub struct QueryJob { /// The latch that is used to wait on this job. #[cfg(parallel_compiler)] - latch: Option<QueryLatch>, + latch: Option<QueryLatch<D>>, + spooky: core::marker::PhantomData<D>, } -impl QueryJob { +impl<D: DepKind> QueryJob<D> { /// Creates a new query job. #[inline] pub fn new(id: QueryJobId, span: Span, parent: Option<QueryJobId>) -> Self { @@ -93,11 +96,12 @@ impl QueryJob { parent, #[cfg(parallel_compiler)] latch: None, + spooky: PhantomData, } } #[cfg(parallel_compiler)] - pub(super) fn latch(&mut self) -> QueryLatch { + pub(super) fn latch(&mut self) -> QueryLatch<D> { if self.latch.is_none() { self.latch = Some(QueryLatch::new()); } @@ -123,12 +127,12 @@ impl QueryJobId { #[cold] #[inline(never)] #[cfg(not(parallel_compiler))] - pub(super) fn find_cycle_in_stack( + pub(super) fn find_cycle_in_stack<D: DepKind>( &self, - query_map: QueryMap, + query_map: QueryMap<D>, current_job: &Option<QueryJobId>, span: Span, - ) -> CycleError { + ) -> CycleError<D> { // Find the waitee amongst `current_job` parents let mut cycle = Vec::new(); let mut current_job = Option::clone(current_job); @@ -162,14 +166,18 @@ impl QueryJobId { #[cold] #[inline(never)] - pub fn try_find_layout_root(&self, query_map: QueryMap) -> Option<(QueryJobInfo, usize)> { + pub fn try_find_layout_root<D: DepKind>( + &self, + query_map: QueryMap<D>, + ) -> Option<(QueryJobInfo<D>, usize)> { let mut last_layout = None; let mut current_id = Some(*self); let mut depth = 0; while let Some(id) = current_id { let info = query_map.get(&id).unwrap(); - if info.query.name == "layout_of" { + // FIXME: This string comparison should probably not be done. + if format!("{:?}", info.query.dep_kind) == "layout_of" { depth += 1; last_layout = Some((info.clone(), depth)); } @@ -180,15 +188,15 @@ impl QueryJobId { } #[cfg(parallel_compiler)] -struct QueryWaiter { +struct QueryWaiter<D: DepKind> { query: Option<QueryJobId>, condvar: Condvar, span: Span, - cycle: Lock<Option<CycleError>>, + cycle: Lock<Option<CycleError<D>>>, } #[cfg(parallel_compiler)] -impl QueryWaiter { +impl<D: DepKind> QueryWaiter<D> { fn notify(&self, registry: &rayon_core::Registry) { rayon_core::mark_unblocked(registry); self.condvar.notify_one(); @@ -196,19 +204,19 @@ impl QueryWaiter { } #[cfg(parallel_compiler)] -struct QueryLatchInfo { +struct QueryLatchInfo<D: DepKind> { complete: bool, - waiters: Vec<Lrc<QueryWaiter>>, + waiters: Vec<Lrc<QueryWaiter<D>>>, } #[cfg(parallel_compiler)] #[derive(Clone)] -pub(super) struct QueryLatch { - info: Lrc<Mutex<QueryLatchInfo>>, +pub(super) struct QueryLatch<D: DepKind> { + info: Lrc<Mutex<QueryLatchInfo<D>>>, } #[cfg(parallel_compiler)] -impl QueryLatch { +impl<D: DepKind> QueryLatch<D> { fn new() -> Self { QueryLatch { info: Lrc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })), @@ -216,7 +224,11 @@ impl QueryLatch { } /// Awaits for the query job to complete. - pub(super) fn wait_on(&self, query: Option<QueryJobId>, span: Span) -> Result<(), CycleError> { + pub(super) fn wait_on( + &self, + query: Option<QueryJobId>, + span: Span, + ) -> Result<(), CycleError<D>> { let waiter = Lrc::new(QueryWaiter { query, span, cycle: Lock::new(None), condvar: Condvar::new() }); self.wait_on_inner(&waiter); @@ -231,7 +243,7 @@ impl QueryLatch { } /// Awaits the caller on this latch by blocking the current thread. - fn wait_on_inner(&self, waiter: &Lrc<QueryWaiter>) { + fn wait_on_inner(&self, waiter: &Lrc<QueryWaiter<D>>) { let mut info = self.info.lock(); if !info.complete { // We push the waiter on to the `waiters` list. It can be accessed inside @@ -247,7 +259,7 @@ impl QueryLatch { jobserver::release_thread(); waiter.condvar.wait(&mut info); // Release the lock before we potentially block in `acquire_thread` - mem::drop(info); + drop(info); jobserver::acquire_thread(); } } @@ -265,7 +277,7 @@ impl QueryLatch { /// Removes a single waiter from the list of waiters. /// This is used to break query cycles. - fn extract_waiter(&self, waiter: usize) -> Lrc<QueryWaiter> { + fn extract_waiter(&self, waiter: usize) -> Lrc<QueryWaiter<D>> { let mut info = self.info.lock(); debug_assert!(!info.complete); // Remove the waiter from the list of waiters @@ -287,9 +299,14 @@ type Waiter = (QueryJobId, usize); /// required information to resume the waiter. /// If all `visit` calls returns None, this function also returns None. #[cfg(parallel_compiler)] -fn visit_waiters<F>(query_map: &QueryMap, query: QueryJobId, mut visit: F) -> Option<Option<Waiter>> +fn visit_waiters<F, D>( + query_map: &QueryMap<D>, + query: QueryJobId, + mut visit: F, +) -> Option<Option<Waiter>> where F: FnMut(Span, QueryJobId) -> Option<Option<Waiter>>, + D: DepKind, { // Visit the parent query which is a non-resumable waiter since it's on the same stack if let Some(parent) = query.parent(query_map) { @@ -318,8 +335,8 @@ where /// If a cycle is detected, this initial value is replaced with the span causing /// the cycle. #[cfg(parallel_compiler)] -fn cycle_check( - query_map: &QueryMap, +fn cycle_check<D: DepKind>( + query_map: &QueryMap<D>, query: QueryJobId, span: Span, stack: &mut Vec<(Span, QueryJobId)>, @@ -359,8 +376,8 @@ fn cycle_check( /// from `query` without going through any of the queries in `visited`. /// This is achieved with a depth first search. #[cfg(parallel_compiler)] -fn connected_to_root( - query_map: &QueryMap, +fn connected_to_root<D: DepKind>( + query_map: &QueryMap<D>, query: QueryJobId, visited: &mut FxHashSet<QueryJobId>, ) -> bool { @@ -382,9 +399,10 @@ fn connected_to_root( // Deterministically pick an query from a list #[cfg(parallel_compiler)] -fn pick_query<'a, T, F>(query_map: &QueryMap, queries: &'a [T], f: F) -> &'a T +fn pick_query<'a, T, F, D>(query_map: &QueryMap<D>, queries: &'a [T], f: F) -> &'a T where F: Fn(&T) -> (Span, QueryJobId), + D: DepKind, { // Deterministically pick an entry point // FIXME: Sort this instead @@ -408,10 +426,10 @@ where /// If a cycle was not found, the starting query is removed from `jobs` and /// the function returns false. #[cfg(parallel_compiler)] -fn remove_cycle( - query_map: &QueryMap, +fn remove_cycle<D: DepKind>( + query_map: &QueryMap<D>, jobs: &mut Vec<QueryJobId>, - wakelist: &mut Vec<Lrc<QueryWaiter>>, + wakelist: &mut Vec<Lrc<QueryWaiter<D>>>, ) -> bool { let mut visited = FxHashSet::default(); let mut stack = Vec::new(); @@ -513,7 +531,7 @@ fn remove_cycle( /// There may be multiple cycles involved in a deadlock, so this searches /// all active queries for cycles before finally resuming all the waiters at once. #[cfg(parallel_compiler)] -pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) { +pub fn deadlock<D: DepKind>(query_map: QueryMap<D>, registry: &rayon_core::Registry) { let on_panic = OnDrop(|| { eprintln!("deadlock handler panicked, aborting process"); process::abort(); @@ -549,9 +567,9 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) { #[inline(never)] #[cold] -pub(crate) fn report_cycle<'a>( +pub(crate) fn report_cycle<'a, D: DepKind>( sess: &'a Session, - CycleError { usage, cycle: stack }: &CycleError, + CycleError { usage, cycle: stack }: &CycleError<D>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { assert!(!stack.is_empty()); @@ -617,7 +635,7 @@ pub fn print_query_stack<Qcx: QueryContext>( }; let mut diag = Diagnostic::new( Level::FailureNote, - &format!("#{} [{}] {}", i, query_info.query.name, query_info.query.description), + &format!("#{} [{:?}] {}", i, query_info.query.dep_kind, query_info.query.description), ); diag.span = query_info.job.span.into(); handler.force_print_diagnostic(diag); |