Skip to content

Commit 0454a41

Browse files
incr.comp.: Address review comments.
1 parent c96d0bf commit 0454a41

File tree

2 files changed

+71
-31
lines changed

2 files changed

+71
-31
lines changed

src/librustc/dep_graph/graph.rs

+54-25
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub struct DepNodeIndex {
5252

5353
impl Idx for DepNodeIndex {
5454
fn new(idx: usize) -> Self {
55-
assert!((idx & 0xFFFF_FFFF) == idx);
55+
debug_assert!((idx & 0xFFFF_FFFF) == idx);
5656
DepNodeIndex { index: idx as u32 }
5757
}
5858
fn index(self) -> usize {
@@ -228,20 +228,31 @@ impl DepGraph {
228228

229229
let current_fingerprint = stable_hasher.finish();
230230

231-
assert!(self.fingerprints
232-
.borrow_mut()
233-
.insert(key, current_fingerprint)
234-
.is_none());
231+
// Store the current fingerprint
232+
{
233+
let old_value = self.fingerprints
234+
.borrow_mut()
235+
.insert(key, current_fingerprint);
236+
debug_assert!(old_value.is_none(),
237+
"DepGraph::with_task() - Duplicate fingerprint \
238+
insertion for {:?}", key);
239+
}
235240

236-
let prev_fingerprint = data.previous.fingerprint_of(&key);
241+
// Determine the color of the new DepNode.
242+
{
243+
let prev_fingerprint = data.previous.fingerprint_of(&key);
237244

238-
let color = if Some(current_fingerprint) == prev_fingerprint {
239-
DepNodeColor::Green(dep_node_index)
240-
} else {
241-
DepNodeColor::Red
242-
};
245+
let color = if Some(current_fingerprint) == prev_fingerprint {
246+
DepNodeColor::Green(dep_node_index)
247+
} else {
248+
DepNodeColor::Red
249+
};
243250

244-
assert!(data.colors.borrow_mut().insert(key, color).is_none());
251+
let old_value = data.colors.borrow_mut().insert(key, color);
252+
debug_assert!(old_value.is_none(),
253+
"DepGraph::with_task() - Duplicate DepNodeColor \
254+
insertion for {:?}", key);
255+
}
245256

246257
(result, dep_node_index)
247258
} else {
@@ -250,10 +261,12 @@ impl DepGraph {
250261
let result = task(cx, arg);
251262
let mut stable_hasher = StableHasher::new();
252263
result.hash_stable(&mut hcx, &mut stable_hasher);
253-
assert!(self.fingerprints
254-
.borrow_mut()
255-
.insert(key, stable_hasher.finish())
256-
.is_none());
264+
let old_value = self.fingerprints
265+
.borrow_mut()
266+
.insert(key, stable_hasher.finish());
267+
debug_assert!(old_value.is_none(),
268+
"DepGraph::with_task() - Duplicate fingerprint \
269+
insertion for {:?}", key);
257270
(result, DepNodeIndex::INVALID)
258271
} else {
259272
(task(cx, arg), DepNodeIndex::INVALID)
@@ -549,16 +562,20 @@ impl DepGraph {
549562
// ... copying the fingerprint from the previous graph too, so we don't
550563
// have to recompute it ...
551564
let fingerprint = data.previous.fingerprint_by_index(prev_dep_node_index);
552-
assert!(self.fingerprints
553-
.borrow_mut()
554-
.insert(*dep_node, fingerprint)
555-
.is_none());
565+
let old_fingerprint = self.fingerprints
566+
.borrow_mut()
567+
.insert(*dep_node, fingerprint);
568+
debug_assert!(old_fingerprint.is_none(),
569+
"DepGraph::try_mark_green() - Duplicate fingerprint \
570+
insertion for {:?}", dep_node);
556571

557572
// ... and finally storing a "Green" entry in the color map.
558-
assert!(data.colors
559-
.borrow_mut()
560-
.insert(*dep_node, DepNodeColor::Green(dep_node_index))
561-
.is_none());
573+
let old_color = data.colors
574+
.borrow_mut()
575+
.insert(*dep_node, DepNodeColor::Green(dep_node_index));
576+
debug_assert!(old_color.is_none(),
577+
"DepGraph::try_mark_green() - Duplicate DepNodeColor \
578+
insertion for {:?}", dep_node);
562579

563580
debug!("try_mark_green({:?}) - END - successfully marked as green", dep_node.kind);
564581
Some(dep_node_index)
@@ -637,9 +654,21 @@ pub(super) struct CurrentDepGraph {
637654
nodes: IndexVec<DepNodeIndex, DepNode>,
638655
edges: IndexVec<DepNodeIndex, Vec<DepNodeIndex>>,
639656
node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
640-
anon_id_seed: Fingerprint,
641657
task_stack: Vec<OpenTask>,
642658
forbidden_edge: Option<EdgeFilter>,
659+
660+
// Anonymous DepNodes are nodes the ID of which we compute from the list of
661+
// their edges. This has the beneficial side-effect that multiple anonymous
662+
// nodes can be coalesced into one without changing the semantics of the
663+
// dependency graph. However, the merging of nodes can lead to a subtle
664+
// problem during red-green marking: The color of an anonymous node from
665+
// the current session might "shadow" the color of the node with the same
666+
// ID from the previous session. In order to side-step this problem, we make
667+
// sure that anon-node IDs allocated in different sessions don't overlap.
668+
// This is implemented by mixing a session-key into the ID fingerprint of
669+
// each anon node. The session-key is just a random number generated when
670+
// the DepGraph is created.
671+
anon_id_seed: Fingerprint,
643672
}
644673

645674
impl CurrentDepGraph {

src/librustc/ty/maps/plumbing.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,19 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
609609
use ty::maps::keys::Key;
610610
use hir::def_id::LOCAL_CRATE;
611611

612-
// We should never get into the situation of having to force this from the DepNode.
613-
// Since we cannot reconstruct the query key, we would always end up having to evaluate
614-
// the first caller of this query that *is* reconstructible. This might very well be
615-
// compile_codegen_unit() in which case we'd lose all re-use.
612+
// We must avoid ever having to call force_from_dep_node() for a
613+
// DepNode::CodegenUnit:
614+
// Since we cannot reconstruct the query key of a DepNode::CodegenUnit, we
615+
// would always end up having to evaluate the first caller of the
616+
// `codegen_unit` query that *is* reconstructible. This might very well be
617+
// the `compile_codegen_unit` query, thus re-translating the whole CGU just
618+
// to re-trigger calling the `codegen_unit` query with the right key. At
619+
// that point we would already have re-done all the work we are trying to
620+
// avoid doing in the first place.
621+
// The solution is simple: Just explicitly call the `codegen_unit` query for
622+
// each CGU, right after partitioning. This way `try_mark_green` will always
623+
// hit the cache instead of having to go through `force_from_dep_node`.
624+
// This assertion makes sure, we actually keep applying the solution above.
616625
debug_assert!(dep_node.kind != DepKind::CodegenUnit,
617626
"calling force_from_dep_node() on DepKind::CodegenUnit");
618627

@@ -666,6 +675,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
666675
}
667676
};
668677

678+
// FIXME(#45015): We should try move this boilerplate code into a macro
679+
// somehow.
669680
match dep_node.kind {
670681
// These are inputs that are expected to be pre-allocated and that
671682
// should therefore always be red or green already
@@ -695,13 +706,13 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
695706
DepKind::CodegenUnit |
696707
DepKind::CompileCodegenUnit |
697708

698-
// This one is just odd
709+
// These are just odd
699710
DepKind::Null |
700711
DepKind::WorkProduct => {
701712
bug!("force_from_dep_node() - Encountered {:?}", dep_node.kind)
702713
}
703714

704-
// These is not a queries
715+
// These are not queries
705716
DepKind::CoherenceCheckTrait |
706717
DepKind::ItemVarianceConstraints => {
707718
return false

0 commit comments

Comments
 (0)