@@ -345,18 +345,6 @@ impl<D: Deps> DepGraphData<D> {
345
345
task : fn ( Ctxt , A ) -> R ,
346
346
hash_result : Option < fn ( & mut StableHashingContext < ' _ > , & R ) -> Fingerprint > ,
347
347
) -> ( R , DepNodeIndex ) {
348
- // If the following assertion triggers, it can have two reasons:
349
- // 1. Something is wrong with DepNode creation, either here or
350
- // in `DepGraph::try_mark_green()`.
351
- // 2. Two distinct query keys get mapped to the same `DepNode`
352
- // (see for example #48923).
353
- assert ! (
354
- !self . dep_node_exists( & key) ,
355
- "forcing query with already existing `DepNode`\n \
356
- - query-key: {arg:?}\n \
357
- - dep-node: {key:?}"
358
- ) ;
359
-
360
348
let with_deps = |task_deps| D :: with_deps ( task_deps, || task ( cx, arg) ) ;
361
349
let ( result, edges) = if cx. dep_context ( ) . is_eval_always ( key. kind ) {
362
350
( with_deps ( TaskDepsRef :: EvalAlways ) , EdgesVec :: new ( ) )
@@ -443,7 +431,31 @@ impl<D: Deps> DepGraphData<D> {
443
431
hash : self . current . anon_id_seed . combine ( hasher. finish ( ) ) . into ( ) ,
444
432
} ;
445
433
446
- self . current . intern_new_node ( target_dep_node, task_deps, Fingerprint :: ZERO )
434
+ // The DepNodes generated by the process above are not unique. 2 queries could
435
+ // have exactly the same dependencies. However, deserialization does not handle
436
+ // duplicated nodes, so we do the deduplication here directly.
437
+ //
438
+ // As anonymous nodes are a small quantity compared to the full dep-graph, the
439
+ // memory impact of this `anon_node_to_index` map remains tolerable, and helps
440
+ // us avoid useless growth of the graph with almost-equivalent nodes.
441
+ match self
442
+ . current
443
+ . anon_node_to_index
444
+ . get_shard_by_value ( & target_dep_node)
445
+ . lock ( )
446
+ . entry ( target_dep_node)
447
+ {
448
+ Entry :: Occupied ( entry) => * entry. get ( ) ,
449
+ Entry :: Vacant ( entry) => {
450
+ let dep_node_index = self . current . intern_new_node (
451
+ target_dep_node,
452
+ task_deps,
453
+ Fingerprint :: ZERO ,
454
+ ) ;
455
+ entry. insert ( dep_node_index) ;
456
+ dep_node_index
457
+ }
458
+ }
447
459
}
448
460
} ;
449
461
@@ -607,20 +619,6 @@ impl<D: Deps> DepGraph<D> {
607
619
}
608
620
609
621
impl < D : Deps > DepGraphData < D > {
610
- #[ inline]
611
- fn dep_node_index_of_opt ( & self , dep_node : & DepNode ) -> Option < DepNodeIndex > {
612
- if let Some ( prev_index) = self . previous . node_to_index_opt ( dep_node) {
613
- self . current . prev_index_to_index . lock ( ) [ prev_index]
614
- } else {
615
- self . current . new_node_to_index . lock_shard_by_value ( dep_node) . get ( dep_node) . copied ( )
616
- }
617
- }
618
-
619
- #[ inline]
620
- fn dep_node_exists ( & self , dep_node : & DepNode ) -> bool {
621
- self . dep_node_index_of_opt ( dep_node) . is_some ( )
622
- }
623
-
624
622
fn node_color ( & self , dep_node : & DepNode ) -> Option < DepNodeColor > {
625
623
if let Some ( prev_index) = self . previous . node_to_index_opt ( dep_node) {
626
624
self . colors . get ( prev_index)
@@ -653,11 +651,6 @@ impl<D: Deps> DepGraphData<D> {
653
651
}
654
652
655
653
impl < D : Deps > DepGraph < D > {
656
- #[ inline]
657
- pub fn dep_node_exists ( & self , dep_node : & DepNode ) -> bool {
658
- self . data . as_ref ( ) . is_some_and ( |data| data. dep_node_exists ( dep_node) )
659
- }
660
-
661
654
/// Checks whether a previous work product exists for `v` and, if
662
655
/// so, return the path that leads to it. Used to skip doing work.
663
656
pub fn previous_work_product ( & self , v : & WorkProductId ) -> Option < WorkProduct > {
@@ -1025,24 +1018,24 @@ rustc_index::newtype_index! {
1025
1018
/// largest in the compiler.
1026
1019
///
1027
1020
/// For this reason, we avoid storing `DepNode`s more than once as map
1028
- /// keys. The `new_node_to_index ` map only contains nodes not in the previous
1021
+ /// keys. The `anon_node_to_index ` map only contains nodes of anonymous queries not in the previous
1029
1022
/// graph, and we map nodes in the previous graph to indices via a two-step
1030
1023
/// mapping. `SerializedDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`,
1031
1024
/// and the `prev_index_to_index` vector (which is more compact and faster than
1032
1025
/// using a map) maps from `SerializedDepNodeIndex` to `DepNodeIndex`.
1033
1026
///
1034
- /// This struct uses three locks internally. The `data`, `new_node_to_index `,
1027
+ /// This struct uses three locks internally. The `data`, `anon_node_to_index `,
1035
1028
/// and `prev_index_to_index` fields are locked separately. Operations that take
1036
1029
/// a `DepNodeIndex` typically just access the `data` field.
1037
1030
///
1038
1031
/// We only need to manipulate at most two locks simultaneously:
1039
- /// `new_node_to_index ` and `data`, or `prev_index_to_index` and `data`. When
1040
- /// manipulating both, we acquire `new_node_to_index ` or `prev_index_to_index`
1032
+ /// `anon_node_to_index ` and `data`, or `prev_index_to_index` and `data`. When
1033
+ /// manipulating both, we acquire `anon_node_to_index ` or `prev_index_to_index`
1041
1034
/// first, and `data` second.
1042
1035
pub ( super ) struct CurrentDepGraph < D : Deps > {
1043
1036
encoder : GraphEncoder < D > ,
1044
- new_node_to_index : Sharded < FxHashMap < DepNode , DepNodeIndex > > ,
1045
1037
prev_index_to_index : Lock < IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > > ,
1038
+ anon_node_to_index : Sharded < FxHashMap < DepNode , DepNodeIndex > > ,
1046
1039
1047
1040
/// This is used to verify that fingerprints do not change between the creation of a node
1048
1041
/// and its recomputation.
@@ -1110,7 +1103,7 @@ impl<D: Deps> CurrentDepGraph<D> {
1110
1103
profiler,
1111
1104
previous,
1112
1105
) ,
1113
- new_node_to_index : Sharded :: new ( || {
1106
+ anon_node_to_index : Sharded :: new ( || {
1114
1107
FxHashMap :: with_capacity_and_hasher (
1115
1108
new_node_count_estimate / sharded:: shards ( ) ,
1116
1109
Default :: default ( ) ,
@@ -1145,14 +1138,7 @@ impl<D: Deps> CurrentDepGraph<D> {
1145
1138
edges : EdgesVec ,
1146
1139
current_fingerprint : Fingerprint ,
1147
1140
) -> DepNodeIndex {
1148
- let dep_node_index = match self . new_node_to_index . lock_shard_by_value ( & key) . entry ( key) {
1149
- Entry :: Occupied ( entry) => * entry. get ( ) ,
1150
- Entry :: Vacant ( entry) => {
1151
- let dep_node_index = self . encoder . send ( key, current_fingerprint, edges) ;
1152
- entry. insert ( dep_node_index) ;
1153
- dep_node_index
1154
- }
1155
- } ;
1141
+ let dep_node_index = self . encoder . send ( key, current_fingerprint, edges) ;
1156
1142
1157
1143
#[ cfg( debug_assertions) ]
1158
1144
self . record_edge ( dep_node_index, key, current_fingerprint) ;
@@ -1222,8 +1208,6 @@ impl<D: Deps> CurrentDepGraph<D> {
1222
1208
prev_graph : & SerializedDepGraph ,
1223
1209
prev_index : SerializedDepNodeIndex ,
1224
1210
) -> DepNodeIndex {
1225
- self . debug_assert_not_in_new_nodes ( prev_graph, prev_index) ;
1226
-
1227
1211
let mut prev_index_to_index = self . prev_index_to_index . lock ( ) ;
1228
1212
1229
1213
match prev_index_to_index[ prev_index] {
@@ -1241,19 +1225,6 @@ impl<D: Deps> CurrentDepGraph<D> {
1241
1225
}
1242
1226
}
1243
1227
}
1244
-
1245
- #[ inline]
1246
- fn debug_assert_not_in_new_nodes (
1247
- & self ,
1248
- prev_graph : & SerializedDepGraph ,
1249
- prev_index : SerializedDepNodeIndex ,
1250
- ) {
1251
- let node = & prev_graph. index_to_node ( prev_index) ;
1252
- debug_assert ! (
1253
- !self . new_node_to_index. lock_shard_by_value( node) . contains_key( node) ,
1254
- "node from previous graph present in new node collection"
1255
- ) ;
1256
- }
1257
1228
}
1258
1229
1259
1230
#[ derive( Debug , Clone , Copy ) ]
@@ -1375,7 +1346,7 @@ fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepN
1375
1346
1376
1347
if dep_node. is_none ( ) {
1377
1348
// Try to find it among the new nodes
1378
- for shard in data. current . new_node_to_index . lock_shards ( ) {
1349
+ for shard in data. current . anon_node_to_index . lock_shards ( ) {
1379
1350
if let Some ( ( node, _) ) = shard. iter ( ) . find ( |( _, index) | * * index == dep_node_index) {
1380
1351
dep_node = Some ( * node) ;
1381
1352
break ;
0 commit comments