Skip to content

Commit b424c09

Browse files
committed
Use a sharded dep node to dep node index map
1 parent cd2747e commit b424c09

File tree

2 files changed

+44
-15
lines changed

2 files changed

+44
-15
lines changed

src/librustc/dep_graph/graph.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
55
use smallvec::SmallVec;
66
use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering};
7+
use rustc_data_structures::sharded::{self, Sharded};
78
use std::sync::atomic::Ordering::{Acquire, SeqCst};
89
use std::env;
910
use std::hash::Hash;
@@ -395,7 +396,7 @@ impl DepGraph {
395396
#[inline]
396397
pub fn read(&self, v: DepNode) {
397398
if let Some(ref data) = self.data {
398-
let map = data.current.node_to_node_index.lock();
399+
let map = data.current.node_to_node_index.get_shard_by_value(&v).lock();
399400
if let Some(dep_node_index) = map.get(&v).copied() {
400401
std::mem::drop(map);
401402
data.read_index(dep_node_index);
@@ -419,6 +420,7 @@ impl DepGraph {
419420
.unwrap()
420421
.current
421422
.node_to_node_index
423+
.get_shard_by_value(dep_node)
422424
.lock()
423425
.get(dep_node)
424426
.cloned()
@@ -428,7 +430,11 @@ impl DepGraph {
428430
#[inline]
429431
pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
430432
if let Some(ref data) = self.data {
431-
data.current.node_to_node_index.lock().contains_key(dep_node)
433+
data.current
434+
.node_to_node_index
435+
.get_shard_by_value(&dep_node)
436+
.lock()
437+
.contains_key(dep_node)
432438
} else {
433439
false
434440
}
@@ -609,7 +615,11 @@ impl DepGraph {
609615

610616
#[cfg(not(parallel_compiler))]
611617
{
612-
debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node));
618+
debug_assert!(!data.current
619+
.node_to_node_index
620+
.get_shard_by_value(dep_node)
621+
.lock()
622+
.contains_key(dep_node));
613623
debug_assert!(data.colors.get(prev_dep_node_index).is_none());
614624
}
615625

@@ -955,7 +965,7 @@ struct DepNodeData {
955965

956966
pub(super) struct CurrentDepGraph {
957967
data: Lock<IndexVec<DepNodeIndex, DepNodeData>>,
958-
node_to_node_index: Lock<FxHashMap<DepNode, DepNodeIndex>>,
968+
node_to_node_index: Sharded<FxHashMap<DepNode, DepNodeIndex>>,
959969
#[allow(dead_code)]
960970
forbidden_edge: Option<EdgeFilter>,
961971

@@ -1008,8 +1018,8 @@ impl CurrentDepGraph {
10081018

10091019
CurrentDepGraph {
10101020
data: Lock::new(IndexVec::with_capacity(new_node_count_estimate)),
1011-
node_to_node_index: Lock::new(FxHashMap::with_capacity_and_hasher(
1012-
new_node_count_estimate,
1021+
node_to_node_index: Sharded::new(|| FxHashMap::with_capacity_and_hasher(
1022+
new_node_count_estimate / sharded::SHARDS,
10131023
Default::default(),
10141024
)),
10151025
anon_id_seed: stable_hasher.finish(),
@@ -1058,7 +1068,10 @@ impl CurrentDepGraph {
10581068
edges: SmallVec<[DepNodeIndex; 8]>,
10591069
fingerprint: Fingerprint
10601070
) -> DepNodeIndex {
1061-
debug_assert!(!self.node_to_node_index.lock().contains_key(&dep_node));
1071+
debug_assert!(!self.node_to_node_index
1072+
.get_shard_by_value(&dep_node)
1073+
.lock()
1074+
.contains_key(&dep_node));
10621075
self.intern_node(dep_node, edges, fingerprint)
10631076
}
10641077

@@ -1068,7 +1081,7 @@ impl CurrentDepGraph {
10681081
edges: SmallVec<[DepNodeIndex; 8]>,
10691082
fingerprint: Fingerprint
10701083
) -> DepNodeIndex {
1071-
match self.node_to_node_index.lock().entry(dep_node) {
1084+
match self.node_to_node_index.get_shard_by_value(&dep_node).lock().entry(dep_node) {
10721085
Entry::Occupied(entry) => *entry.get(),
10731086
Entry::Vacant(entry) => {
10741087
let mut data = self.data.lock();

src/librustc_data_structures/sharded.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::hash::{Hasher, Hash};
22
use std::mem;
33
use std::borrow::Borrow;
44
use std::collections::hash_map::RawEntryMut;
5+
use smallvec::SmallVec;
56
use crate::fx::{FxHasher, FxHashMap};
67
use crate::sync::{Lock, LockGuard};
78

@@ -15,7 +16,7 @@ const SHARD_BITS: usize = 5;
1516
#[cfg(not(parallel_compiler))]
1617
const SHARD_BITS: usize = 0;
1718

18-
const SHARDS: usize = 1 << SHARD_BITS;
19+
pub const SHARDS: usize = 1 << SHARD_BITS;
1920

2021
/// An array of cache-line aligned inner locked structures with convenience methods.
2122
#[derive(Clone)]
@@ -26,21 +27,36 @@ pub struct Sharded<T> {
2627
impl<T: Default> Default for Sharded<T> {
2728
#[inline]
2829
fn default() -> Self {
30+
Self::new(|| T::default())
31+
}
32+
}
33+
34+
impl<T> Sharded<T> {
35+
#[inline]
36+
pub fn new(mut value: impl FnMut() -> T) -> Self {
37+
// Create a vector of the values we want
38+
let mut values: SmallVec<[_; SHARDS]> = (0..SHARDS).map(|_| {
39+
CacheAligned(Lock::new(value()))
40+
}).collect();
41+
42+
// Create an unintialized array
2943
let mut shards: mem::MaybeUninit<[CacheAligned<Lock<T>>; SHARDS]> =
3044
mem::MaybeUninit::uninit();
31-
let first = shards.as_mut_ptr() as *mut CacheAligned<Lock<T>>;
45+
3246
unsafe {
33-
for i in 0..SHARDS {
34-
first.add(i).write(CacheAligned(Lock::new(T::default())));
35-
}
47+
// Copy the values into our array
48+
let first = shards.as_mut_ptr() as *mut CacheAligned<Lock<T>>;
49+
values.as_ptr().copy_to_nonoverlapping(first, SHARDS);
50+
51+
// Ignore the content of the vector
52+
values.set_len(0);
53+
3654
Sharded {
3755
shards: shards.assume_init(),
3856
}
3957
}
4058
}
41-
}
4259

43-
impl<T> Sharded<T> {
4460
#[inline]
4561
pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
4662
if SHARDS == 1 {

0 commit comments

Comments
 (0)