@@ -3,7 +3,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3
3
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
4
4
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
5
5
use smallvec:: SmallVec ;
6
- use rustc_data_structures:: sync:: { Lrc , Lock , AtomicU32 , Ordering } ;
6
+ use rustc_data_structures:: sync:: { Lrc , Lock , AtomicU32 , AtomicU64 , Ordering } ;
7
+ use std:: sync:: atomic:: Ordering :: { Acquire , SeqCst } ;
7
8
use std:: env;
8
9
use std:: hash:: Hash ;
9
10
use std:: collections:: hash_map:: Entry ;
@@ -54,7 +55,7 @@ struct DepGraphData {
54
55
/// tracking. The `current` field is the dependency graph of only the
55
56
/// current compilation session: We don't merge the previous dep-graph into
56
57
/// current one anymore.
57
- current : Lock < CurrentDepGraph > ,
58
+ current : CurrentDepGraph ,
58
59
59
60
/// The dep-graph from the previous compilation session. It contains all
60
61
/// nodes and edges as well as all fingerprints of nodes that have them.
@@ -77,7 +78,7 @@ struct DepGraphData {
77
78
dep_node_debug : Lock < FxHashMap < DepNode , String > > ,
78
79
79
80
// Used for testing, only populated when -Zquery-dep-graph is specified.
80
- loaded_from_cache : Lock < FxHashMap < DepNodeIndex , bool > > ,
81
+ loaded_from_cache : Lock < FxHashMap < DepNode , bool > > ,
81
82
}
82
83
83
84
pub fn hash_result < R > ( hcx : & mut StableHashingContext < ' _ > , result : & R ) -> Option < Fingerprint >
@@ -99,7 +100,7 @@ impl DepGraph {
99
100
data : Some ( Lrc :: new ( DepGraphData {
100
101
previous_work_products : prev_work_products,
101
102
dep_node_debug : Default :: default ( ) ,
102
- current : Lock :: new ( CurrentDepGraph :: new ( prev_graph_node_count) ) ,
103
+ current : CurrentDepGraph :: new ( prev_graph_node_count) ,
103
104
emitting_diagnostics : Default :: default ( ) ,
104
105
emitting_diagnostics_cond_var : Condvar :: new ( ) ,
105
106
previous : prev_graph,
@@ -122,13 +123,13 @@ impl DepGraph {
122
123
}
123
124
124
125
pub fn query ( & self ) -> DepGraphQuery {
125
- let current_dep_graph = self . data . as_ref ( ) . unwrap ( ) . current . borrow ( ) ;
126
- let nodes: Vec < _ > = current_dep_graph . data . iter ( ) . map ( |n| n. node ) . collect ( ) ;
126
+ let data = self . data . as_ref ( ) . unwrap ( ) . current . data . lock ( ) ;
127
+ let nodes: Vec < _ > = data. iter ( ) . map ( |n| n. node ) . collect ( ) ;
127
128
let mut edges = Vec :: new ( ) ;
128
- for ( from, edge_targets) in current_dep_graph . data . iter ( )
129
+ for ( from, edge_targets) in data. iter ( )
129
130
. map ( |d| ( d. node , & d. edges ) ) {
130
131
for & edge_target in edge_targets. iter ( ) {
131
- let to = current_dep_graph . data [ edge_target] . node ;
132
+ let to = data[ edge_target] . node ;
132
133
edges. push ( ( from, to) ) ;
133
134
}
134
135
}
@@ -207,7 +208,7 @@ impl DepGraph {
207
208
read_set : Default :: default ( ) ,
208
209
} ) ,
209
210
|data, key, fingerprint, task| {
210
- data. borrow_mut ( ) . complete_task ( key, task. unwrap ( ) , fingerprint)
211
+ data. complete_task ( key, task. unwrap ( ) , fingerprint)
211
212
} ,
212
213
hash_result)
213
214
}
@@ -228,7 +229,7 @@ impl DepGraph {
228
229
self . with_task_impl ( key, cx, input, true , identity_fn,
229
230
|_| None ,
230
231
|data, key, fingerprint, _| {
231
- data. borrow_mut ( ) . alloc_node ( key, SmallVec :: new ( ) , fingerprint)
232
+ data. alloc_node ( key, SmallVec :: new ( ) , fingerprint)
232
233
} ,
233
234
hash_result :: < R > )
234
235
}
@@ -241,7 +242,7 @@ impl DepGraph {
241
242
no_tcx : bool ,
242
243
task : fn ( C , A ) -> R ,
243
244
create_task : fn ( DepNode ) -> Option < TaskDeps > ,
244
- finish_task_and_alloc_depnode : fn ( & Lock < CurrentDepGraph > ,
245
+ finish_task_and_alloc_depnode : fn ( & CurrentDepGraph ,
245
246
DepNode ,
246
247
Fingerprint ,
247
248
Option < TaskDeps > ) -> DepNodeIndex ,
@@ -363,7 +364,6 @@ impl DepGraph {
363
364
( r, task_deps. into_inner ( ) )
364
365
} ) ;
365
366
let dep_node_index = data. current
366
- . borrow_mut ( )
367
367
. complete_anon_task ( dep_kind, task_deps) ;
368
368
( result, dep_node_index)
369
369
} else {
@@ -387,18 +387,17 @@ impl DepGraph {
387
387
self . with_task_impl ( key, cx, arg, false , task,
388
388
|_| None ,
389
389
|data, key, fingerprint, _| {
390
- let mut current = data. borrow_mut ( ) ;
391
- current. alloc_node ( key, smallvec ! [ ] , fingerprint)
390
+ data. alloc_node ( key, smallvec ! [ ] , fingerprint)
392
391
} ,
393
392
hash_result)
394
393
}
395
394
396
395
#[ inline]
397
396
pub fn read ( & self , v : DepNode ) {
398
397
if let Some ( ref data) = self . data {
399
- let current = data. current . borrow_mut ( ) ;
400
- if let Some ( & dep_node_index) = current . node_to_node_index . get ( & v) {
401
- std:: mem:: drop ( current ) ;
398
+ let map = data. current . node_to_node_index . lock ( ) ;
399
+ if let Some ( dep_node_index) = map . get ( & v) . copied ( ) {
400
+ std:: mem:: drop ( map ) ;
402
401
data. read_index ( dep_node_index) ;
403
402
} else {
404
403
bug ! ( "DepKind {:?} should be pre-allocated but isn't." , v. kind)
@@ -419,8 +418,8 @@ impl DepGraph {
419
418
. as_ref ( )
420
419
. unwrap ( )
421
420
. current
422
- . borrow_mut ( )
423
421
. node_to_node_index
422
+ . lock ( )
424
423
. get ( dep_node)
425
424
. cloned ( )
426
425
. unwrap ( )
@@ -429,16 +428,16 @@ impl DepGraph {
429
428
#[ inline]
430
429
pub fn dep_node_exists ( & self , dep_node : & DepNode ) -> bool {
431
430
if let Some ( ref data) = self . data {
432
- data. current . borrow_mut ( ) . node_to_node_index . contains_key ( dep_node)
431
+ data. current . node_to_node_index . lock ( ) . contains_key ( dep_node)
433
432
} else {
434
433
false
435
434
}
436
435
}
437
436
438
437
#[ inline]
439
438
pub fn fingerprint_of ( & self , dep_node_index : DepNodeIndex ) -> Fingerprint {
440
- let current = self . data . as_ref ( ) . expect ( "dep graph enabled" ) . current . borrow_mut ( ) ;
441
- current . data [ dep_node_index] . fingerprint
439
+ let data = self . data . as_ref ( ) . expect ( "dep graph enabled" ) . current . data . lock ( ) ;
440
+ data[ dep_node_index] . fingerprint
442
441
}
443
442
444
443
pub fn prev_fingerprint_of ( & self , dep_node : & DepNode ) -> Option < Fingerprint > {
@@ -492,32 +491,29 @@ impl DepGraph {
492
491
493
492
pub fn edge_deduplication_data ( & self ) -> Option < ( u64 , u64 ) > {
494
493
if cfg ! ( debug_assertions) {
495
- let current_dep_graph = self . data . as_ref ( ) . unwrap ( ) . current . borrow ( ) ;
494
+ let current_dep_graph = & self . data . as_ref ( ) . unwrap ( ) . current ;
496
495
497
- Some ( ( current_dep_graph. total_read_count ,
498
- current_dep_graph. total_duplicate_read_count ) )
496
+ Some ( ( current_dep_graph. total_read_count . load ( Acquire ) ,
497
+ current_dep_graph. total_duplicate_read_count . load ( Acquire ) ) )
499
498
} else {
500
499
None
501
500
}
502
501
}
503
502
504
503
pub fn serialize ( & self ) -> SerializedDepGraph {
505
- let current_dep_graph = self . data . as_ref ( ) . unwrap ( ) . current . borrow ( ) ;
504
+ let data = self . data . as_ref ( ) . unwrap ( ) . current . data . lock ( ) ;
506
505
507
506
let fingerprints: IndexVec < SerializedDepNodeIndex , _ > =
508
- current_dep_graph . data . iter ( ) . map ( |d| d. fingerprint ) . collect ( ) ;
507
+ data. iter ( ) . map ( |d| d. fingerprint ) . collect ( ) ;
509
508
let nodes: IndexVec < SerializedDepNodeIndex , _ > =
510
- current_dep_graph . data . iter ( ) . map ( |d| d. node ) . collect ( ) ;
509
+ data. iter ( ) . map ( |d| d. node ) . collect ( ) ;
511
510
512
- let total_edge_count: usize = current_dep_graph. data . iter ( )
513
- . map ( |d| d. edges . len ( ) )
514
- . sum ( ) ;
511
+ let total_edge_count: usize = data. iter ( ) . map ( |d| d. edges . len ( ) ) . sum ( ) ;
515
512
516
513
let mut edge_list_indices = IndexVec :: with_capacity ( nodes. len ( ) ) ;
517
514
let mut edge_list_data = Vec :: with_capacity ( total_edge_count) ;
518
515
519
- for ( current_dep_node_index, edges) in current_dep_graph. data . iter_enumerated ( )
520
- . map ( |( i, d) | ( i, & d. edges ) ) {
516
+ for ( current_dep_node_index, edges) in data. iter_enumerated ( ) . map ( |( i, d) | ( i, & d. edges ) ) {
521
517
let start = edge_list_data. len ( ) as u32 ;
522
518
// This should really just be a memcpy :/
523
519
edge_list_data. extend ( edges. iter ( ) . map ( |i| SerializedDepNodeIndex :: new ( i. index ( ) ) ) ) ;
@@ -746,15 +742,13 @@ impl DepGraph {
746
742
// There may be multiple threads trying to mark the same dep node green concurrently
747
743
748
744
let dep_node_index = {
749
- let mut current = data. current . borrow_mut ( ) ;
750
-
751
745
// Copy the fingerprint from the previous graph,
752
746
// so we don't have to recompute it
753
747
let fingerprint = data. previous . fingerprint_by_index ( prev_dep_node_index) ;
754
748
755
749
// We allocating an entry for the node in the current dependency graph and
756
750
// adding all the appropriate edges imported from the previous graph
757
- current. intern_node ( * dep_node, current_deps, fingerprint)
751
+ data . current . intern_node ( * dep_node, current_deps, fingerprint)
758
752
} ;
759
753
760
754
// ... emitting any stored diagnostic ...
@@ -889,23 +883,21 @@ impl DepGraph {
889
883
}
890
884
}
891
885
892
- pub fn mark_loaded_from_cache ( & self , dep_node_index : DepNodeIndex , state : bool ) {
893
- debug ! ( "mark_loaded_from_cache({:?}, {})" ,
894
- self . data. as_ref( ) . unwrap( ) . current. borrow( ) . data[ dep_node_index] . node,
895
- state) ;
886
+ pub fn mark_loaded_from_cache ( & self , dep_node : DepNode , state : bool ) {
887
+ debug ! ( "mark_loaded_from_cache({:?}, {})" , dep_node, state) ;
896
888
897
889
self . data
898
890
. as_ref ( )
899
891
. unwrap ( )
900
892
. loaded_from_cache
901
893
. borrow_mut ( )
902
- . insert ( dep_node_index , state) ;
894
+ . insert ( dep_node , state) ;
903
895
}
904
896
897
+ // FIXME: Remove this since it appears to be unused?
905
898
pub fn was_loaded_from_cache ( & self , dep_node : & DepNode ) -> Option < bool > {
906
899
let data = self . data . as_ref ( ) . unwrap ( ) ;
907
- let dep_node_index = data. current . borrow ( ) . node_to_node_index [ dep_node] ;
908
- data. loaded_from_cache . borrow ( ) . get ( & dep_node_index) . cloned ( )
900
+ data. loaded_from_cache . borrow ( ) . get ( & dep_node) . cloned ( )
909
901
}
910
902
}
911
903
@@ -962,8 +954,8 @@ struct DepNodeData {
962
954
}
963
955
964
956
pub ( super ) struct CurrentDepGraph {
965
- data : IndexVec < DepNodeIndex , DepNodeData > ,
966
- node_to_node_index : FxHashMap < DepNode , DepNodeIndex > ,
957
+ data : Lock < IndexVec < DepNodeIndex , DepNodeData > > ,
958
+ node_to_node_index : Lock < FxHashMap < DepNode , DepNodeIndex > > ,
967
959
#[ allow( dead_code) ]
968
960
forbidden_edge : Option < EdgeFilter > ,
969
961
@@ -980,8 +972,8 @@ pub(super) struct CurrentDepGraph {
980
972
/// the `DepGraph` is created.
981
973
anon_id_seed : Fingerprint ,
982
974
983
- total_read_count : u64 ,
984
- total_duplicate_read_count : u64 ,
975
+ total_read_count : AtomicU64 ,
976
+ total_duplicate_read_count : AtomicU64 ,
985
977
}
986
978
987
979
impl CurrentDepGraph {
@@ -1015,28 +1007,28 @@ impl CurrentDepGraph {
1015
1007
let new_node_count_estimate = ( prev_graph_node_count * 102 ) / 100 + 200 ;
1016
1008
1017
1009
CurrentDepGraph {
1018
- data : IndexVec :: with_capacity ( new_node_count_estimate) ,
1019
- node_to_node_index : FxHashMap :: with_capacity_and_hasher (
1010
+ data : Lock :: new ( IndexVec :: with_capacity ( new_node_count_estimate) ) ,
1011
+ node_to_node_index : Lock :: new ( FxHashMap :: with_capacity_and_hasher (
1020
1012
new_node_count_estimate,
1021
1013
Default :: default ( ) ,
1022
- ) ,
1014
+ ) ) ,
1023
1015
anon_id_seed : stable_hasher. finish ( ) ,
1024
1016
forbidden_edge,
1025
- total_read_count : 0 ,
1026
- total_duplicate_read_count : 0 ,
1017
+ total_read_count : AtomicU64 :: new ( 0 ) ,
1018
+ total_duplicate_read_count : AtomicU64 :: new ( 0 ) ,
1027
1019
}
1028
1020
}
1029
1021
1030
1022
fn complete_task (
1031
- & mut self ,
1023
+ & self ,
1032
1024
node : DepNode ,
1033
1025
task_deps : TaskDeps ,
1034
1026
fingerprint : Fingerprint
1035
1027
) -> DepNodeIndex {
1036
1028
self . alloc_node ( node, task_deps. reads , fingerprint)
1037
1029
}
1038
1030
1039
- fn complete_anon_task ( & mut self , kind : DepKind , task_deps : TaskDeps ) -> DepNodeIndex {
1031
+ fn complete_anon_task ( & self , kind : DepKind , task_deps : TaskDeps ) -> DepNodeIndex {
1040
1032
debug_assert ! ( !kind. is_eval_always( ) ) ;
1041
1033
1042
1034
let mut hasher = StableHasher :: new ( ) ;
@@ -1061,28 +1053,27 @@ impl CurrentDepGraph {
1061
1053
}
1062
1054
1063
1055
fn alloc_node (
1064
- & mut self ,
1056
+ & self ,
1065
1057
dep_node : DepNode ,
1066
1058
edges : SmallVec < [ DepNodeIndex ; 8 ] > ,
1067
1059
fingerprint : Fingerprint
1068
1060
) -> DepNodeIndex {
1069
- debug_assert ! ( !self . node_to_node_index. contains_key( & dep_node) ) ;
1061
+ debug_assert ! ( !self . node_to_node_index. lock ( ) . contains_key( & dep_node) ) ;
1070
1062
self . intern_node ( dep_node, edges, fingerprint)
1071
1063
}
1072
1064
1073
1065
fn intern_node (
1074
- & mut self ,
1066
+ & self ,
1075
1067
dep_node : DepNode ,
1076
1068
edges : SmallVec < [ DepNodeIndex ; 8 ] > ,
1077
1069
fingerprint : Fingerprint
1078
1070
) -> DepNodeIndex {
1079
- debug_assert_eq ! ( self . node_to_node_index. len( ) , self . data. len( ) ) ;
1080
-
1081
- match self . node_to_node_index . entry ( dep_node) {
1071
+ match self . node_to_node_index . lock ( ) . entry ( dep_node) {
1082
1072
Entry :: Occupied ( entry) => * entry. get ( ) ,
1083
1073
Entry :: Vacant ( entry) => {
1084
- let dep_node_index = DepNodeIndex :: new ( self . data . len ( ) ) ;
1085
- self . data . push ( DepNodeData {
1074
+ let mut data = self . data . lock ( ) ;
1075
+ let dep_node_index = DepNodeIndex :: new ( data. len ( ) ) ;
1076
+ data. push ( DepNodeData {
1086
1077
node : dep_node,
1087
1078
edges,
1088
1079
fingerprint
@@ -1101,17 +1092,17 @@ impl DepGraphData {
1101
1092
if let Some ( task_deps) = icx. task_deps {
1102
1093
let mut task_deps = task_deps. lock ( ) ;
1103
1094
if cfg ! ( debug_assertions) {
1104
- self . current . lock ( ) . total_read_count += 1 ;
1095
+ self . current . total_read_count . fetch_add ( 1 , SeqCst ) ;
1105
1096
}
1106
1097
if task_deps. read_set . insert ( source) {
1107
1098
task_deps. reads . push ( source) ;
1108
1099
1109
1100
#[ cfg( debug_assertions) ]
1110
1101
{
1111
1102
if let Some ( target) = task_deps. node {
1112
- let graph = self . current . lock ( ) ;
1113
- if let Some ( ref forbidden_edge) = graph . forbidden_edge {
1114
- let source = graph . data [ source] . node ;
1103
+ let data = self . current . data . lock ( ) ;
1104
+ if let Some ( ref forbidden_edge) = self . current . forbidden_edge {
1105
+ let source = data[ source] . node ;
1115
1106
if forbidden_edge. test ( & source, & target) {
1116
1107
bug ! ( "forbidden edge {:?} -> {:?} created" ,
1117
1108
source,
@@ -1121,7 +1112,7 @@ impl DepGraphData {
1121
1112
}
1122
1113
}
1123
1114
} else if cfg ! ( debug_assertions) {
1124
- self . current . lock ( ) . total_duplicate_read_count += 1 ;
1115
+ self . current . total_duplicate_read_count . fetch_add ( 1 , SeqCst ) ;
1125
1116
}
1126
1117
}
1127
1118
} )
0 commit comments