X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_query_system%2Fsrc%2Fquery%2Fplumbing.rs;h=9278bb602e11d6f9742873bd118c8ce100cc35eb;hb=9deed6f74ea2df0ba08fb72342bef4eb303d0777;hp=da1f3617647804b835a289dcbb6ca6218ee54326;hpb=cce9231c19378f57b05f3c8b09df317c3a512f82;p=rust.git diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index da1f3617647..9278bb602e1 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -5,16 +5,14 @@ use crate::dep_graph::{DepContext, DepNode, DepNodeIndex, DepNodeParams}; use crate::query::caches::QueryCache; use crate::query::config::{QueryDescription, QueryVtable}; -use crate::query::job::{ - report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId, -}; +use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo}; use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHasher}; #[cfg(parallel_compiler)] use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::sharded::{get_shard_index_by_hash, Sharded}; -use rustc_data_structures::sync::{Lock, LockGuard}; +use rustc_data_structures::sync::Lock; use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{DiagnosticBuilder, FatalError}; use rustc_session::Session; @@ -24,24 +22,12 @@ use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::mem; -use std::num::NonZeroU32; use std::ptr; -pub struct QueryCacheStore { - cache: C, - shards: Sharded, -} - -impl Default for QueryCacheStore { - fn default() -> Self { - Self { cache: C::default(), shards: Default::default() } - } -} - /// Values used when checking a query cache which can be reused on a cache-miss to execute the query. pub struct QueryLookup { pub(super) key_hash: u64, - shard: usize, + pub(super) shard: usize, } // We compute the key's hash once and then use it for both the @@ -53,52 +39,32 @@ fn hash_for_shard(key: &K) -> u64 { hasher.finish() } -impl QueryCacheStore { - pub(super) fn get_lookup<'tcx>( - &'tcx self, - key: &C::Key, - ) -> (QueryLookup, LockGuard<'tcx, C::Sharded>) { - let key_hash = hash_for_shard(key); - let shard = get_shard_index_by_hash(key_hash); - let lock = self.shards.get_shard_by_index(shard).lock(); - (QueryLookup { key_hash, shard }, lock) - } - - pub fn iter_results(&self, f: &mut dyn FnMut(&C::Key, &C::Value, DepNodeIndex)) { - self.cache.iter(&self.shards, f) - } -} - -struct QueryStateShard { - active: FxHashMap>, - - /// Used to generate unique ids for active jobs. - jobs: u32, +struct QueryStateShard { + active: FxHashMap, } -impl Default for QueryStateShard { - fn default() -> QueryStateShard { - QueryStateShard { active: Default::default(), jobs: 0 } +impl Default for QueryStateShard { + fn default() -> QueryStateShard { + QueryStateShard { active: Default::default() } } } -pub struct QueryState { - shards: Sharded>, +pub struct QueryState { + shards: Sharded>, } /// Indicates the state of a query for a given key in a query map. -enum QueryResult { +enum QueryResult { /// An already executing query. The query job can be used to await for its completion. - Started(QueryJob), + Started(QueryJob), /// The query panicked. Queries trying to wait on this will raise a fatal error which will /// silently panic. Poisoned, } -impl QueryState +impl QueryState where - D: Copy + Clone + Eq + Hash, K: Eq + Hash + Clone + Debug, { pub fn all_inactive(&self) -> bool { @@ -109,19 +75,17 @@ pub fn all_inactive(&self) -> bool { pub fn try_collect_active_jobs( &self, tcx: CTX, - kind: D, make_query: fn(CTX, K) -> QueryStackFrame, - jobs: &mut QueryMap, + jobs: &mut QueryMap, ) -> Option<()> { // We use try_lock_shards here since we are called from the // deadlock handler, and this shouldn't be locked. let shards = self.shards.try_lock_shards()?; - for (shard_id, shard) in shards.iter().enumerate() { + for shard in shards.iter() { for (k, v) in shard.active.iter() { if let QueryResult::Started(ref job) = *v { - let id = QueryJobId::new(job.id, shard_id, kind); let query = make_query(tcx, k.clone()); - jobs.insert(id, QueryJobInfo { query, job: job.clone() }); + jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } } @@ -130,22 +94,21 @@ pub fn try_collect_active_jobs( } } -impl Default for QueryState { - fn default() -> QueryState { +impl Default for QueryState { + fn default() -> QueryState { QueryState { shards: Default::default() } } } /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. -struct JobOwner<'tcx, D, K> +struct JobOwner<'tcx, K> where - D: Copy + Clone + Eq + Hash, K: Eq + Hash + Clone, { - state: &'tcx QueryState, + state: &'tcx QueryState, key: K, - id: QueryJobId, + id: QueryJobId, } #[cold] @@ -166,9 +129,8 @@ fn mk_cycle( cache.store_nocache(value) } -impl<'tcx, D, K> JobOwner<'tcx, D, K> +impl<'tcx, K> JobOwner<'tcx, K> where - D: Copy + Clone + Eq + Hash, K: Eq + Hash + Clone, { /// Either gets a `JobOwner` corresponding the query, allowing us to @@ -182,12 +144,11 @@ impl<'tcx, D, K> JobOwner<'tcx, D, K> #[inline(always)] fn try_start<'b, CTX>( tcx: &'b CTX, - state: &'b QueryState, + state: &'b QueryState, span: Span, key: K, lookup: QueryLookup, - dep_kind: CTX::DepKind, - ) -> TryGetJob<'b, CTX::DepKind, K> + ) -> TryGetJob<'b, K> where CTX: QueryContext, { @@ -197,27 +158,21 @@ fn try_start<'b, CTX>( match lock.active.entry(key) { Entry::Vacant(entry) => { - // Generate an id unique within this shard. - let id = lock.jobs.checked_add(1).unwrap(); - lock.jobs = id; - let id = QueryShardJobId(NonZeroU32::new(id).unwrap()); - + let id = tcx.next_job_id(); let job = tcx.current_query_job(); let job = QueryJob::new(id, span, job); let key = entry.key().clone(); entry.insert(QueryResult::Started(job)); - let global_id = QueryJobId::new(id, shard, dep_kind); - let owner = JobOwner { state, id: global_id, key }; + let owner = JobOwner { state, id, key }; return TryGetJob::NotYetStarted(owner); } Entry::Occupied(mut entry) => { match entry.get_mut() { #[cfg(not(parallel_compiler))] QueryResult::Started(job) => { - let id = QueryJobId::new(job.id, shard, dep_kind); - + let id = job.id; drop(state_lock); // If we are single-threaded we know that we have cycle error, @@ -257,12 +212,7 @@ fn try_start<'b, CTX>( /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query - fn complete( - self, - cache: &QueryCacheStore, - result: C::Value, - dep_node_index: DepNodeIndex, - ) -> C::Stored + fn complete(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) -> C::Stored where C: QueryCache, { @@ -283,10 +233,7 @@ fn complete( QueryResult::Poisoned => panic!(), } }; - let result = { - let mut lock = cache.shards.get_shard_by_index(shard).lock(); - cache.cache.complete(&mut lock, key, result, dep_node_index) - }; + let result = cache.complete(key, result, dep_node_index); (job, result) }; @@ -295,9 +242,8 @@ fn complete( } } -impl<'tcx, D, K> Drop for JobOwner<'tcx, D, K> +impl<'tcx, K> Drop for JobOwner<'tcx, K> where - D: Copy + Clone + Eq + Hash, K: Eq + Hash + Clone, { #[inline(never)] @@ -329,13 +275,12 @@ pub(crate) struct CycleError { } /// The result of `try_start`. -enum TryGetJob<'tcx, D, K> +enum TryGetJob<'tcx, K> where - D: Copy + Clone + Eq + Hash, K: Eq + Hash + Clone, { /// The query is not yet started. Contains a guard to the cache eventually used to start it. - NotYetStarted(JobOwner<'tcx, D, K>), + NotYetStarted(JobOwner<'tcx, K>), /// The query was already completed. /// Returns the result of the query and its dep-node index @@ -354,7 +299,7 @@ enum TryGetJob<'tcx, D, K> #[inline] pub fn try_get_cached<'a, CTX, C, R, OnHit>( tcx: CTX, - cache: &'a QueryCacheStore, + cache: &'a C, key: &C::Key, // `on_hit` can be called while holding a lock to the query cache on_hit: OnHit, @@ -364,7 +309,7 @@ pub fn try_get_cached<'a, CTX, C, R, OnHit>( CTX: DepContext, OnHit: FnOnce(&C::Stored) -> R, { - cache.cache.lookup(cache, &key, |value, index| { + cache.lookup(&key, |value, index| { if unlikely!(tcx.profiler().enabled()) { tcx.profiler().query_cache_hit(index.into()); } @@ -375,8 +320,8 @@ pub fn try_get_cached<'a, CTX, C, R, OnHit>( fn try_execute_query( tcx: CTX, - state: &QueryState, - cache: &QueryCacheStore, + state: &QueryState, + cache: &C, span: Span, key: C::Key, lookup: QueryLookup, @@ -388,28 +333,20 @@ fn try_execute_query( C::Key: Clone + DepNodeParams, CTX: QueryContext, { - match JobOwner::<'_, CTX::DepKind, C::Key>::try_start( - &tcx, - state, - span, - key.clone(), - lookup, - query.dep_kind, - ) { + match JobOwner::<'_, C::Key>::try_start(&tcx, state, span, key.clone(), lookup) { TryGetJob::NotYetStarted(job) => { let (result, dep_node_index) = execute_job(tcx, key, dep_node, query, job.id); let result = job.complete(cache, result, dep_node_index); (result, Some(dep_node_index)) } TryGetJob::Cycle(error) => { - let result = mk_cycle(tcx, error, query.handle_cycle_error, &cache.cache); + let result = mk_cycle(tcx, error, query.handle_cycle_error, cache); (result, None) } #[cfg(parallel_compiler)] TryGetJob::JobCompleted(query_blocked_prof_timer) => { let (v, index) = cache - .cache - .lookup(cache, &key, |value, index| (value.clone(), index)) + .lookup(&key, |value, index| (value.clone(), index)) .unwrap_or_else(|_| panic!("value must be in cache after waiting")); if unlikely!(tcx.dep_context().profiler().enabled()) { @@ -427,7 +364,7 @@ fn execute_job( key: K, mut dep_node_opt: Option>, query: &QueryVtable, - job_id: QueryJobId, + job_id: QueryJobId, ) -> (V, DepNodeIndex) where K: Clone + DepNodeParams, @@ -787,7 +724,7 @@ pub fn force_query(tcx: CTX, key: Q::Key, dep_node: DepNode