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

Make DepGraph thread-safe

上级 cc794209
此差异已折叠。
......@@ -14,13 +14,12 @@
mod graph;
mod prev;
mod query;
mod raii;
mod safe;
mod serialized;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
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::prev::PreviousDepGraph;
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,
body_ids: _,
} = *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),
&hcx,
HirItemLike { item_like: (module, attrs, span), hash_bodies: false },
identity_fn
).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),
&hcx,
HirItemLike { item_like: (module, attrs, span), hash_bodies: true },
identity_fn
).1;
}
{
dep_graph.with_task(
dep_graph.input_task(
DepNode::new_no_params(DepKind::AllLocalTraitImpls),
&hcx,
&krate.trait_impls,
identity_fn
);
}
......@@ -169,12 +166,11 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
let (_, crate_dep_node_index) = self
.dep_graph
.with_task(DepNode::new_no_params(DepKind::Krate),
.input_task(DepNode::new_no_params(DepKind::Krate),
&self.hcx,
(((node_hashes, upstream_crates), source_file_names),
(commandline_args_hash,
crate_disambiguator.to_fingerprint())),
identity_fn);
crate_disambiguator.to_fingerprint())));
let svh = Svh::new(self.dep_graph
.fingerprint_of(crate_dep_node_index)
......@@ -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);
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),
&self.hcx,
HirItemLike { item_like, hash_bodies: false },
identity_fn
).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),
&self.hcx,
HirItemLike { item_like, hash_bodies: true },
identity_fn
).1;
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) {
}
}
// 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
// the wrapped item should be hashed or not.
struct HirItemLike<T> {
......
......@@ -1562,6 +1562,7 @@ pub fn enter_local<F, R>(
tcx,
query: icx.query.clone(),
layout_depth: icx.layout_depth,
task: icx.task,
};
ty::tls::enter_context(&new_icx, |new_icx| {
f(new_icx.tcx)
......@@ -1740,7 +1741,8 @@ pub mod tls {
use ty::maps;
use errors::{Diagnostic, TRACK_DIAGNOSTICS};
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
/// 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> {
/// Used to prevent layout from recursing too deeply.
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
......@@ -1845,6 +1851,7 @@ pub fn enter_global<'gcx, F, R>(gcx: &GlobalCtxt<'gcx>, f: F) -> R
tcx,
query: None,
layout_depth: 0,
task: &Lock::new(OpenTask::Ignore),
};
enter_context(&icx, |_| {
f(tcx)
......
......@@ -530,6 +530,7 @@ fn start_job<F, R>(tcx: TyCtxt<'_, $tcx, 'lcx>,
tcx,
query: Some(job.clone()),
layout_depth: icx.layout_depth,
task: icx.task,
};
// 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.
先完成此消息的编辑!
想要评论请 注册