提交 64b5d408 编写于 作者: J John Kåre Alsaker

Make DepGraph thread-safe

上级 cc794209
此差异已折叠。
...@@ -14,13 +14,12 @@ ...@@ -14,13 +14,12 @@
mod graph; mod graph;
mod prev; mod prev;
mod query; mod query;
mod raii;
mod safe; mod safe;
mod serialized; mod serialized;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig}; pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs}; pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor}; pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, OpenTask};
pub use self::graph::WorkProductFileKind; pub use self::graph::WorkProductFileKind;
pub use self::prev::PreviousDepGraph; pub use self::prev::PreviousDepGraph;
pub use self::query::DepGraphQuery; pub use self::query::DepGraphQuery;
......
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super::graph::CurrentDepGraph;
use std::cell::RefCell;
pub struct IgnoreTask<'graph> {
graph: &'graph RefCell<CurrentDepGraph>,
}
impl<'graph> IgnoreTask<'graph> {
pub(super) fn new(graph: &'graph RefCell<CurrentDepGraph>) -> IgnoreTask<'graph> {
graph.borrow_mut().push_ignore();
IgnoreTask {
graph,
}
}
}
impl<'graph> Drop for IgnoreTask<'graph> {
fn drop(&mut self) {
self.graph.borrow_mut().pop_ignore();
}
}
...@@ -79,26 +79,23 @@ pub(super) fn root(krate: &'hir Crate, ...@@ -79,26 +79,23 @@ pub(super) fn root(krate: &'hir Crate,
body_ids: _, body_ids: _,
} = *krate; } = *krate;
root_mod_sig_dep_index = dep_graph.with_task( root_mod_sig_dep_index = dep_graph.input_task(
root_mod_def_path_hash.to_dep_node(DepKind::Hir), root_mod_def_path_hash.to_dep_node(DepKind::Hir),
&hcx, &hcx,
HirItemLike { item_like: (module, attrs, span), hash_bodies: false }, HirItemLike { item_like: (module, attrs, span), hash_bodies: false },
identity_fn
).1; ).1;
root_mod_full_dep_index = dep_graph.with_task( root_mod_full_dep_index = dep_graph.input_task(
root_mod_def_path_hash.to_dep_node(DepKind::HirBody), root_mod_def_path_hash.to_dep_node(DepKind::HirBody),
&hcx, &hcx,
HirItemLike { item_like: (module, attrs, span), hash_bodies: true }, HirItemLike { item_like: (module, attrs, span), hash_bodies: true },
identity_fn
).1; ).1;
} }
{ {
dep_graph.with_task( dep_graph.input_task(
DepNode::new_no_params(DepKind::AllLocalTraitImpls), DepNode::new_no_params(DepKind::AllLocalTraitImpls),
&hcx, &hcx,
&krate.trait_impls, &krate.trait_impls,
identity_fn
); );
} }
...@@ -169,12 +166,11 @@ pub(super) fn finalize_and_compute_crate_hash(mut self, ...@@ -169,12 +166,11 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
let (_, crate_dep_node_index) = self let (_, crate_dep_node_index) = self
.dep_graph .dep_graph
.with_task(DepNode::new_no_params(DepKind::Krate), .input_task(DepNode::new_no_params(DepKind::Krate),
&self.hcx, &self.hcx,
(((node_hashes, upstream_crates), source_file_names), (((node_hashes, upstream_crates), source_file_names),
(commandline_args_hash, (commandline_args_hash,
crate_disambiguator.to_fingerprint())), crate_disambiguator.to_fingerprint())));
identity_fn);
let svh = Svh::new(self.dep_graph let svh = Svh::new(self.dep_graph
.fingerprint_of(crate_dep_node_index) .fingerprint_of(crate_dep_node_index)
...@@ -267,18 +263,16 @@ fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>, ...@@ -267,18 +263,16 @@ fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>,
let def_path_hash = self.definitions.def_path_hash(dep_node_owner); let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
self.current_signature_dep_index = self.dep_graph.with_task( self.current_signature_dep_index = self.dep_graph.input_task(
def_path_hash.to_dep_node(DepKind::Hir), def_path_hash.to_dep_node(DepKind::Hir),
&self.hcx, &self.hcx,
HirItemLike { item_like, hash_bodies: false }, HirItemLike { item_like, hash_bodies: false },
identity_fn
).1; ).1;
self.current_full_dep_index = self.dep_graph.with_task( self.current_full_dep_index = self.dep_graph.input_task(
def_path_hash.to_dep_node(DepKind::HirBody), def_path_hash.to_dep_node(DepKind::HirBody),
&self.hcx, &self.hcx,
HirItemLike { item_like, hash_bodies: true }, HirItemLike { item_like, hash_bodies: true },
identity_fn
).1; ).1;
self.hir_body_nodes.push((def_path_hash, self.current_full_dep_index)); self.hir_body_nodes.push((def_path_hash, self.current_full_dep_index));
...@@ -520,12 +514,6 @@ fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) { ...@@ -520,12 +514,6 @@ fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
} }
} }
// We use this with DepGraph::with_task(). Since we are handling only input
// values here, the "task" computing them just passes them through.
fn identity_fn<T>(_: &StableHashingContext, item_like: T) -> T {
item_like
}
// This is a wrapper structure that allows determining if span values within // This is a wrapper structure that allows determining if span values within
// the wrapped item should be hashed or not. // the wrapped item should be hashed or not.
struct HirItemLike<T> { struct HirItemLike<T> {
......
...@@ -1562,6 +1562,7 @@ pub fn enter_local<F, R>( ...@@ -1562,6 +1562,7 @@ pub fn enter_local<F, R>(
tcx, tcx,
query: icx.query.clone(), query: icx.query.clone(),
layout_depth: icx.layout_depth, layout_depth: icx.layout_depth,
task: icx.task,
}; };
ty::tls::enter_context(&new_icx, |new_icx| { ty::tls::enter_context(&new_icx, |new_icx| {
f(new_icx.tcx) f(new_icx.tcx)
...@@ -1740,7 +1741,8 @@ pub mod tls { ...@@ -1740,7 +1741,8 @@ pub mod tls {
use ty::maps; use ty::maps;
use errors::{Diagnostic, TRACK_DIAGNOSTICS}; use errors::{Diagnostic, TRACK_DIAGNOSTICS};
use rustc_data_structures::OnDrop; use rustc_data_structures::OnDrop;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::{Lrc, Lock};
use dep_graph::OpenTask;
/// This is the implicit state of rustc. It contains the current /// This is the implicit state of rustc. It contains the current
/// TyCtxt and query. It is updated when creating a local interner or /// TyCtxt and query. It is updated when creating a local interner or
...@@ -1759,6 +1761,10 @@ pub struct ImplicitCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { ...@@ -1759,6 +1761,10 @@ pub struct ImplicitCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
/// Used to prevent layout from recursing too deeply. /// Used to prevent layout from recursing too deeply.
pub layout_depth: usize, pub layout_depth: usize,
/// The current dep graph task. This is used to add dependencies to queries
/// when executing them
pub task: &'a Lock<OpenTask>,
} }
// A thread local value which stores a pointer to the current ImplicitCtxt // A thread local value which stores a pointer to the current ImplicitCtxt
...@@ -1845,6 +1851,7 @@ pub fn enter_global<'gcx, F, R>(gcx: &GlobalCtxt<'gcx>, f: F) -> R ...@@ -1845,6 +1851,7 @@ pub fn enter_global<'gcx, F, R>(gcx: &GlobalCtxt<'gcx>, f: F) -> R
tcx, tcx,
query: None, query: None,
layout_depth: 0, layout_depth: 0,
task: &Lock::new(OpenTask::Ignore),
}; };
enter_context(&icx, |_| { enter_context(&icx, |_| {
f(tcx) f(tcx)
......
...@@ -530,6 +530,7 @@ fn start_job<F, R>(tcx: TyCtxt<'_, $tcx, 'lcx>, ...@@ -530,6 +530,7 @@ fn start_job<F, R>(tcx: TyCtxt<'_, $tcx, 'lcx>,
tcx, tcx,
query: Some(job.clone()), query: Some(job.clone()),
layout_depth: icx.layout_depth, layout_depth: icx.layout_depth,
task: icx.task,
}; };
// Use the ImplicitCtxt while we execute the query // Use the ImplicitCtxt while we execute the query
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册