@@ -3,11 +3,15 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
33use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
44use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
55use smallvec:: SmallVec ;
6- use rustc_data_structures:: sync:: { Lrc , Lock , AtomicU32 , AtomicU64 , Ordering } ;
6+ use rustc_data_structures:: sync:: {
7+ Lrc , Lock , LockGuard , MappedLockGuard , AtomicU32 , AtomicU64 , Ordering
8+ } ;
79use rustc_data_structures:: sharded:: { self , Sharded } ;
810use std:: sync:: atomic:: Ordering :: { Acquire , SeqCst } ;
911use std:: env;
12+ use std:: iter;
1013use std:: hash:: Hash ;
14+ use std:: convert:: TryFrom ;
1115use std:: collections:: hash_map:: Entry ;
1216use std:: mem;
1317use crate :: ty:: { self , TyCtxt } ;
@@ -124,7 +128,15 @@ impl DepGraph {
124128 }
125129
126130 pub fn query ( & self ) -> DepGraphQuery {
127- let data = self . data . as_ref ( ) . unwrap ( ) . current . data . lock ( ) ;
131+ let current = & self . data . as_ref ( ) . unwrap ( ) . current ;
132+ let shards = current. data . lock_shards ( ) ;
133+ let node_count = current. node_count . load ( Acquire ) as usize ;
134+ let data: IndexVec < DepNodeIndex , _ > = ( 0 ..node_count) . map ( |i| {
135+ let shard = i % sharded:: SHARDS ;
136+ let inner = i / sharded:: SHARDS ;
137+ & shards[ shard] [ inner]
138+ } ) . collect ( ) ;
139+
128140 let nodes: Vec < _ > = data. iter ( ) . map ( |n| n. node ) . collect ( ) ;
129141 let mut edges = Vec :: new ( ) ;
130142 for ( from, edge_targets) in data. iter ( )
@@ -442,8 +454,7 @@ impl DepGraph {
442454
443455 #[ inline]
444456 pub fn fingerprint_of ( & self , dep_node_index : DepNodeIndex ) -> Fingerprint {
445- let data = self . data . as_ref ( ) . expect ( "dep graph enabled" ) . current . data . lock ( ) ;
446- data[ dep_node_index] . fingerprint
457+ self . data . as_ref ( ) . expect ( "dep graph enabled" ) . current . data ( dep_node_index) . fingerprint
447458 }
448459
449460 pub fn prev_fingerprint_of ( & self , dep_node : & DepNode ) -> Option < Fingerprint > {
@@ -507,25 +518,32 @@ impl DepGraph {
507518 }
508519
509520 pub fn serialize ( & self ) -> SerializedDepGraph {
510- let data = self . data . as_ref ( ) . unwrap ( ) . current . data . lock ( ) ;
521+ let current = & self . data . as_ref ( ) . unwrap ( ) . current ;
522+ let shards = current. data . lock_shards ( ) ;
523+ let node_count = current. node_count . load ( Acquire ) as usize ;
524+ let data = || ( 0 ..node_count) . map ( |i| {
525+ let shard = i % sharded:: SHARDS ;
526+ let inner = i / sharded:: SHARDS ;
527+ & shards[ shard] [ inner]
528+ } ) ;
511529
512530 let fingerprints: IndexVec < SerializedDepNodeIndex , _ > =
513- data. iter ( ) . map ( |d| d. fingerprint ) . collect ( ) ;
531+ data ( ) . map ( |d| d. fingerprint ) . collect ( ) ;
514532 let nodes: IndexVec < SerializedDepNodeIndex , _ > =
515- data. iter ( ) . map ( |d| d. node ) . collect ( ) ;
533+ data ( ) . map ( |d| d. node ) . collect ( ) ;
516534
517- let total_edge_count: usize = data. iter ( ) . map ( |d| d. edges . len ( ) ) . sum ( ) ;
535+ let total_edge_count: usize = data ( ) . map ( |d| d. edges . len ( ) ) . sum ( ) ;
518536
519537 let mut edge_list_indices = IndexVec :: with_capacity ( nodes. len ( ) ) ;
520538 let mut edge_list_data = Vec :: with_capacity ( total_edge_count) ;
521539
522- for ( current_dep_node_index, edges) in data. iter_enumerated ( ) . map ( |( i, d) | ( i, & d. edges ) ) {
540+ for ( current_dep_node_index, edges) in data ( ) . enumerate ( ) . map ( |( i, d) | ( i, & d. edges ) ) {
523541 let start = edge_list_data. len ( ) as u32 ;
524542 // This should really just be a memcpy :/
525543 edge_list_data. extend ( edges. iter ( ) . map ( |i| SerializedDepNodeIndex :: new ( i. index ( ) ) ) ) ;
526544 let end = edge_list_data. len ( ) as u32 ;
527545
528- debug_assert_eq ! ( current_dep_node_index. index ( ) , edge_list_indices. len( ) ) ;
546+ debug_assert_eq ! ( current_dep_node_index, edge_list_indices. len( ) ) ;
529547 edge_list_indices. push ( ( start, end) ) ;
530548 }
531549
@@ -964,7 +982,14 @@ struct DepNodeData {
964982}
965983
966984pub ( super ) struct CurrentDepGraph {
967- data : Lock < IndexVec < DepNodeIndex , DepNodeData > > ,
985+ /// The current node count. Used to allocate an index before storing it in the
986+ /// `data` and `node_to_node_index` field below.
987+ node_count : AtomicU64 ,
988+
989+ /// Maps from a `DepNodeIndex` to `DepNodeData`. The lowest bits of `DepNodeIndex` determines
990+ /// which shard is used and the higher bits are the index into the vector.
991+ data : Sharded < Vec < DepNodeData > > ,
992+
968993 node_to_node_index : Sharded < FxHashMap < DepNode , DepNodeIndex > > ,
969994 #[ allow( dead_code) ]
970995 forbidden_edge : Option < EdgeFilter > ,
@@ -1017,7 +1042,8 @@ impl CurrentDepGraph {
10171042 let new_node_count_estimate = ( prev_graph_node_count * 102 ) / 100 + 200 ;
10181043
10191044 CurrentDepGraph {
1020- data : Lock :: new ( IndexVec :: with_capacity ( new_node_count_estimate) ) ,
1045+ node_count : AtomicU64 :: new ( 0 ) ,
1046+ data : Sharded :: new ( || Vec :: with_capacity ( new_node_count_estimate / sharded:: SHARDS ) ) ,
10211047 node_to_node_index : Sharded :: new ( || FxHashMap :: with_capacity_and_hasher (
10221048 new_node_count_estimate / sharded:: SHARDS ,
10231049 Default :: default ( ) ,
@@ -1081,20 +1107,56 @@ impl CurrentDepGraph {
10811107 edges : SmallVec < [ DepNodeIndex ; 8 ] > ,
10821108 fingerprint : Fingerprint
10831109 ) -> DepNodeIndex {
1084- match self . node_to_node_index . get_shard_by_value ( & dep_node) . lock ( ) . entry ( dep_node) {
1110+ let ( index, inserted) = match self . node_to_node_index
1111+ . get_shard_by_value ( & dep_node)
1112+ . lock ( )
1113+ . entry ( dep_node) {
10851114 Entry :: Occupied ( entry) => * entry. get ( ) ,
10861115 Entry :: Vacant ( entry) => {
1087- let mut data = self . data . lock ( ) ;
1088- let dep_node_index = DepNodeIndex :: new ( data. len ( ) ) ;
1089- data. push ( DepNodeData {
1090- node : dep_node,
1091- edges,
1092- fingerprint
1093- } ) ;
1116+ let index = self . node_count . fetch_add ( 1 , SeqCst ) ;
1117+ // Cast to u32 to ensure we didn't overflow.
1118+ let index = u32:: try_from ( index) . unwrap ( ) ;
1119+
1120+ let dep_node_index = DepNodeIndex :: new ( index as usize ) ;
10941121 entry. insert ( dep_node_index) ;
10951122 dep_node_index
10961123 }
1124+ } ;
1125+
1126+ if inserted {
1127+ let dep_node_data = DepNodeData {
1128+ node : dep_node,
1129+ edges,
1130+ fingerprint
1131+ } ;
1132+ let inner_index = index. as_usize ( ) / sharded:: SHARDS ;
1133+ let mut data = self . data . get_shard_by_index ( index. as_usize ( ) ) . lock ( ) ;
1134+ let len = data. len ( ) ;
1135+ if likely ! ( len == inner_index) {
1136+ data. push ( dep_node_data)
1137+ } else {
1138+ let dummy_data = DepNodeData {
1139+ node : DepNode :: new_no_params ( DepKind :: Null ) ,
1140+ edges : SmallVec :: default ( ) ,
1141+ fingerprint : Fingerprint :: ZERO ,
1142+ } ;
1143+ if inner_index >= len {
1144+ data. extend ( iter:: repeat ( dummy_data) . take ( inner_index - len + 1 ) ) ;
1145+ }
1146+ data[ inner_index] = dep_node_data;
1147+ }
10971148 }
1149+
1150+ ( index, inserted)
1151+ }
1152+
1153+ fn data (
1154+ & self ,
1155+ index : DepNodeIndex ,
1156+ ) -> MappedLockGuard < ' _ , DepNodeData > {
1157+ LockGuard :: map ( self . data . get_shard_by_index ( index. as_usize ( ) ) . lock ( ) , |vec| {
1158+ & mut vec[ index. as_usize ( ) / sharded:: SHARDS ]
1159+ } )
10981160 }
10991161}
11001162
@@ -1113,9 +1175,8 @@ impl DepGraphData {
11131175 #[ cfg( debug_assertions) ]
11141176 {
11151177 if let Some ( target) = task_deps. node {
1116- let data = self . current . data . lock ( ) ;
11171178 if let Some ( ref forbidden_edge) = self . current . forbidden_edge {
1118- let source = data[ source] . node ;
1179+ let source = self . current . data ( source) . node ;
11191180 if forbidden_edge. test ( & source, & target) {
11201181 bug ! ( "forbidden edge {:?} -> {:?} created" ,
11211182 source,
0 commit comments