@@ -13,7 +13,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1313use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1414use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
1515use smallvec:: SmallVec ;
16- use rustc_data_structures:: sync:: { Lrc , Lock } ;
16+ use rustc_data_structures:: sync:: { Lrc , Lock , AtomicU64 , Ordering :: Relaxed } ;
17+ use rustc_data_structures:: vec:: SmallVecExt ;
1718use std:: env;
1819use std:: hash:: Hash ;
1920use ty:: { self , TyCtxt } ;
@@ -69,6 +70,8 @@ struct DepGraphData {
6970 /// current one anymore.
7071 current : Lock < CurrentDepGraph > ,
7172
73+ current_atomic : CurrentDepGraphAtomic ,
74+
7275 /// The dep-graph from the previous compilation session. It contains all
7376 /// nodes and edges as well as all fingerprints of nodes that have them.
7477 previous : PreviousDepGraph ,
@@ -98,11 +101,13 @@ impl DepGraph {
98101
99102 let fingerprints = IndexVec :: from_elem_n ( Fingerprint :: ZERO ,
100103 ( prev_graph_node_count * 115 ) / 100 ) ;
104+ let ( current, current_atomic) = CurrentDepGraph :: new ( ) ;
101105 DepGraph {
102106 data : Some ( Lrc :: new ( DepGraphData {
103107 previous_work_products : prev_work_products,
104108 dep_node_debug : Default :: default ( ) ,
105- current : Lock :: new ( CurrentDepGraph :: new ( ) ) ,
109+ current : Lock :: new ( current) ,
110+ current_atomic,
106111 previous : prev_graph,
107112 colors : Lock :: new ( DepNodeColorMap :: new ( prev_graph_node_count) ) ,
108113 loaded_from_cache : Default :: default ( ) ,
@@ -446,9 +451,10 @@ impl DepGraph {
446451 #[ inline]
447452 pub fn read ( & self , v : DepNode ) {
448453 if let Some ( ref data) = self . data {
449- let mut current = data. current . borrow_mut ( ) ;
454+ let current = data. current . borrow_mut ( ) ;
450455 if let Some ( & dep_node_index) = current. node_to_node_index . get ( & v) {
451- current. read_index ( dep_node_index) ;
456+ std:: mem:: drop ( current) ;
457+ data. current_atomic . read_index ( & data. current , dep_node_index) ;
452458 } else {
453459 bug ! ( "DepKind {:?} should be pre-allocated but isn't." , v. kind)
454460 }
@@ -458,7 +464,7 @@ impl DepGraph {
458464 #[ inline]
459465 pub fn read_index ( & self , dep_node_index : DepNodeIndex ) {
460466 if let Some ( ref data) = self . data {
461- data. current . borrow_mut ( ) . read_index ( dep_node_index) ;
467+ data. current_atomic . read_index ( & data . current , dep_node_index) ;
462468 }
463469 }
464470
@@ -549,9 +555,10 @@ impl DepGraph {
549555 }
550556
551557 pub fn edge_deduplication_data ( & self ) -> ( u64 , u64 ) {
552- let current_dep_graph = self . data . as_ref ( ) . unwrap ( ) . current . borrow ( ) ;
558+ let current_dep_graph = & self . data . as_ref ( ) . unwrap ( ) . current_atomic ;
553559
554- ( current_dep_graph. total_read_count , current_dep_graph. total_duplicate_read_count )
560+ ( current_dep_graph. total_read_count . load ( Relaxed ) ,
561+ current_dep_graph. total_duplicate_read_count . load ( Relaxed ) )
555562 }
556563
557564 pub fn serialize ( & self ) -> SerializedDepGraph {
@@ -936,6 +943,11 @@ pub enum WorkProductFileKind {
936943 BytecodeCompressed ,
937944}
938945
946+ pub ( super ) struct CurrentDepGraphAtomic {
947+ total_read_count : AtomicU64 ,
948+ total_duplicate_read_count : AtomicU64 ,
949+ }
950+
939951pub ( super ) struct CurrentDepGraph {
940952 nodes : IndexVec < DepNodeIndex , DepNode > ,
941953 edges : IndexVec < DepNodeIndex , SmallVec < [ DepNodeIndex ; 8 ] > > ,
@@ -954,13 +966,10 @@ pub(super) struct CurrentDepGraph {
954966 // each anon node. The session-key is just a random number generated when
955967 // the DepGraph is created.
956968 anon_id_seed : Fingerprint ,
957-
958- total_read_count : u64 ,
959- total_duplicate_read_count : u64 ,
960969}
961970
962971impl CurrentDepGraph {
963- fn new ( ) -> CurrentDepGraph {
972+ fn new ( ) -> ( CurrentDepGraph , CurrentDepGraphAtomic ) {
964973 use std:: time:: { SystemTime , UNIX_EPOCH } ;
965974
966975 let duration = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ;
@@ -983,15 +992,16 @@ impl CurrentDepGraph {
983992 None
984993 } ;
985994
986- CurrentDepGraph {
995+ ( CurrentDepGraph {
987996 nodes : IndexVec :: new ( ) ,
988997 edges : IndexVec :: new ( ) ,
989998 node_to_node_index : Default :: default ( ) ,
990999 anon_id_seed : stable_hasher. finish ( ) ,
9911000 forbidden_edge,
992- total_read_count : 0 ,
993- total_duplicate_read_count : 0 ,
994- }
1001+ } , CurrentDepGraphAtomic {
1002+ total_read_count : AtomicU64 :: new ( 0 ) ,
1003+ total_duplicate_read_count : AtomicU64 :: new ( 0 ) ,
1004+ } )
9951005 }
9961006
9971007 #[ inline( always) ]
@@ -1085,22 +1095,39 @@ impl CurrentDepGraph {
10851095 }
10861096 }
10871097
1088- fn read_index ( & mut self , source : DepNodeIndex ) {
1098+ fn alloc_node ( & mut self ,
1099+ dep_node : DepNode ,
1100+ edges : SmallVec < [ DepNodeIndex ; 8 ] > )
1101+ -> DepNodeIndex {
1102+ debug_assert_eq ! ( self . edges. len( ) , self . nodes. len( ) ) ;
1103+ debug_assert_eq ! ( self . node_to_node_index. len( ) , self . nodes. len( ) ) ;
1104+ debug_assert ! ( !self . node_to_node_index. contains_key( & dep_node) ) ;
1105+ let dep_node_index = DepNodeIndex :: new ( self . nodes . len ( ) ) ;
1106+ self . nodes . push ( dep_node) ;
1107+ self . node_to_node_index . insert ( dep_node, dep_node_index) ;
1108+ self . edges . push ( edges) ;
1109+ dep_node_index
1110+ }
1111+ }
1112+
1113+ impl CurrentDepGraphAtomic {
1114+ fn read_index ( & self , lock : & Lock < CurrentDepGraph > , source : DepNodeIndex ) {
10891115 ty:: tls:: with_context_opt ( |icx| {
10901116 let icx = if let Some ( icx) = icx { icx } else { return } ;
10911117 match * icx. task {
10921118 OpenTask :: Regular ( ref task) => {
10931119 let mut task = task. lock ( ) ;
1094- self . total_read_count += 1 ;
1120+ self . total_read_count . fetch_add ( 1 , Relaxed ) ;
10951121 // FIXME: Only use the set of the SmallVec moved to the heap
10961122 // Use an array and switch to the set after?
10971123 if task. read_set . insert ( source) {
1098- task. reads . push ( source) ;
1124+ task. reads . push_light ( source) ;
10991125
11001126 if cfg ! ( debug_assertions) {
1101- if let Some ( ref forbidden_edge) = self . forbidden_edge {
1127+ let graph = lock. lock ( ) ;
1128+ if let Some ( ref forbidden_edge) = graph. forbidden_edge {
11021129 let target = & task. node ;
1103- let source = self . nodes [ source] ;
1130+ let source = graph . nodes [ source] ;
11041131 if forbidden_edge. test ( & source, & target) {
11051132 bug ! ( "forbidden edge {:?} -> {:?} created" ,
11061133 source,
@@ -1109,7 +1136,7 @@ impl CurrentDepGraph {
11091136 }
11101137 }
11111138 } else {
1112- self . total_duplicate_read_count += 1 ;
1139+ self . total_duplicate_read_count . fetch_add ( 1 , Relaxed ) ;
11131140 }
11141141 }
11151142 OpenTask :: Anon ( ref task) => {
@@ -1124,20 +1151,6 @@ impl CurrentDepGraph {
11241151 }
11251152 } )
11261153 }
1127-
1128- fn alloc_node ( & mut self ,
1129- dep_node : DepNode ,
1130- edges : SmallVec < [ DepNodeIndex ; 8 ] > )
1131- -> DepNodeIndex {
1132- debug_assert_eq ! ( self . edges. len( ) , self . nodes. len( ) ) ;
1133- debug_assert_eq ! ( self . node_to_node_index. len( ) , self . nodes. len( ) ) ;
1134- debug_assert ! ( !self . node_to_node_index. contains_key( & dep_node) ) ;
1135- let dep_node_index = DepNodeIndex :: new ( self . nodes . len ( ) ) ;
1136- self . nodes . push ( dep_node) ;
1137- self . node_to_node_index . insert ( dep_node, dep_node_index) ;
1138- self . edges . push ( edges) ;
1139- dep_node_index
1140- }
11411154}
11421155
11431156pub struct RegularOpenTask {
0 commit comments