aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexis Beingessner <a.beingessner@gmail.com>2017-10-19 23:58:02 -0400
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-10-20 15:15:22 +0200
commitf7f898b3b35da9e9274a0e20b1a70f25098b2363 (patch)
tree3ad267edd33aa2b21eb3edab8b4bd4fd7272fce3
parent07e9794306d597afe5d90d192fd32a99572c3cc3 (diff)
downloadservo-f7f898b3b35da9e9274a0e20b1a70f25098b2363.tar.gz
servo-f7f898b3b35da9e9274a0e20b1a70f25098b2363.zip
Report hash value at HashMap corruption location.
-rw-r--r--components/hashglobe/src/diagnostic.rs17
-rw-r--r--components/hashglobe/src/hash_map.rs6
-rw-r--r--components/hashglobe/src/table.rs9
3 files changed, 27 insertions, 5 deletions
diff --git a/components/hashglobe/src/diagnostic.rs b/components/hashglobe/src/diagnostic.rs
index f761e31a6ab..e5cfebf5168 100644
--- a/components/hashglobe/src/diagnostic.rs
+++ b/components/hashglobe/src/diagnostic.rs
@@ -62,17 +62,21 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
let mut position = 0;
let mut count = 0;
let mut bad_canary = None;
- for (_,v) in self.map.iter() {
+
+ let mut iter = self.map.iter();
+ while let Some((h, _, v)) = iter.next_with_hash() {
let canary_ref = &v.0;
position += 1;
+
if *canary_ref == CANARY {
continue;
}
+
count += 1;
- bad_canary = Some((*canary_ref, canary_ref, position));
+ bad_canary = Some((h, *canary_ref, canary_ref, position));
}
if let Some(c) = bad_canary {
- self.report_corruption(c.0, c.1, c.2, count);
+ self.report_corruption(c.0, c.1, c.2, c.3, count);
}
}
@@ -158,6 +162,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
#[inline(never)]
fn report_corruption(
&self,
+ hash: usize,
canary: usize,
canary_addr: *const usize,
position: usize,
@@ -172,12 +177,14 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
value.as_ptr(),
);
}
+
panic!(
- concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, count={}, ",
- "last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"),
+ concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, hash={:#x}, cnry={:#x}, ",
+ "count={}, last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"),
self.map.len(),
self.map.raw_capacity(),
::std::mem::size_of::<(K, (usize, V))>(),
+ hash,
canary,
count,
position,
diff --git a/components/hashglobe/src/hash_map.rs b/components/hashglobe/src/hash_map.rs
index e17f6fd6a8e..e588b5b208c 100644
--- a/components/hashglobe/src/hash_map.rs
+++ b/components/hashglobe/src/hash_map.rs
@@ -1339,6 +1339,12 @@ impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> {
}
}
+impl<'a, K: 'a, V: 'a> Iter<'a, K, V> {
+ pub fn next_with_hash(&mut self) -> Option<(usize, &'a K, &'a V)> {
+ self.inner.next_with_hash()
+ }
+}
+
/// A mutable iterator over the entries of a `HashMap`.
///
/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
diff --git a/components/hashglobe/src/table.rs b/components/hashglobe/src/table.rs
index adaf52ee54e..65542de4be2 100644
--- a/components/hashglobe/src/table.rs
+++ b/components/hashglobe/src/table.rs
@@ -1130,6 +1130,15 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
}
}
+impl<'a, K, V> Iter<'a, K, V> {
+ pub fn next_with_hash(&mut self) -> Option<(usize, &'a K, &'a V)> {
+ self.iter.next().map(|raw| unsafe {
+ let (hash_ptr, pair_ptr) = raw.hash_pair();
+ (*hash_ptr, &(*pair_ptr).0, &(*pair_ptr).1)
+ })
+ }
+}
+
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);