mirror of
https://github.com/servo/servo.git
synced 2025-08-08 06:55:31 +01:00
Auto merge of #18977 - Manishearth:map-len, r=Gankro
Include map length in diagnostics If this doesn't match with the size it's more likely for anything caught t be hardware corruption. If it does the situation is more interesting. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18977) <!-- Reviewable:end -->
This commit is contained in:
commit
ba9af5c124
3 changed files with 37 additions and 6 deletions
|
@ -62,17 +62,21 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
|
||||||
let mut position = 0;
|
let mut position = 0;
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let mut bad_canary = None;
|
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;
|
let canary_ref = &v.0;
|
||||||
position += 1;
|
position += 1;
|
||||||
|
|
||||||
if *canary_ref == CANARY {
|
if *canary_ref == CANARY {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
count += 1;
|
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 {
|
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,10 +162,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn report_corruption(
|
fn report_corruption(
|
||||||
&self,
|
&self,
|
||||||
|
hash: usize,
|
||||||
canary: usize,
|
canary: usize,
|
||||||
canary_addr: *const usize,
|
canary_addr: *const usize,
|
||||||
position: usize,
|
position: usize,
|
||||||
count: usize,
|
count: usize
|
||||||
) {
|
) {
|
||||||
use ::std::ffi::CString;
|
use ::std::ffi::CString;
|
||||||
let key = b"HashMapJournal\0";
|
let key = b"HashMapJournal\0";
|
||||||
|
@ -172,12 +177,15 @@ impl<K: Hash + Eq, V, S: BuildHasher> DiagnosticHashMap<K, V, S>
|
||||||
value.as_ptr(),
|
value.as_ptr(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
panic!(
|
panic!(
|
||||||
concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, count={}, ",
|
concat!("HashMap Corruption (sz={}, buffer_hash_sz={}, cap={}, pairsz={}, hash={:#x}, cnry={:#x}, ",
|
||||||
"last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"),
|
"count={}, last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"),
|
||||||
self.map.len(),
|
self.map.len(),
|
||||||
|
self.map.diagnostic_count_hashes(),
|
||||||
self.map.raw_capacity(),
|
self.map.raw_capacity(),
|
||||||
::std::mem::size_of::<(K, (usize, V))>(),
|
::std::mem::size_of::<(K, (usize, V))>(),
|
||||||
|
hash,
|
||||||
canary,
|
canary,
|
||||||
count,
|
count,
|
||||||
position,
|
position,
|
||||||
|
|
|
@ -1257,6 +1257,10 @@ impl<K, V, S> HashMap<K, V, S>
|
||||||
debug_assert!(elems_left == 0 || bucket.index() != start_index);
|
debug_assert!(elems_left == 0 || bucket.index() != start_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn diagnostic_count_hashes(&self) -> usize {
|
||||||
|
self.table.diagnostic_count_hashes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V, S> PartialEq for HashMap<K, V, S>
|
impl<K, V, S> PartialEq for HashMap<K, V, S>
|
||||||
|
@ -1339,6 +1343,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`.
|
/// A mutable iterator over the entries of a `HashMap`.
|
||||||
///
|
///
|
||||||
/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
|
/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
|
||||||
|
|
|
@ -896,6 +896,10 @@ impl<K, V> RawTable<K, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn diagnostic_count_hashes(&self) -> usize {
|
||||||
|
(0..self.capacity()).filter(|&i| unsafe { *self.raw_bucket_at(i).hash() != EMPTY_BUCKET }).count()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter<K, V> {
|
pub fn iter(&self) -> Iter<K, V> {
|
||||||
Iter {
|
Iter {
|
||||||
iter: self.raw_buckets(),
|
iter: self.raw_buckets(),
|
||||||
|
@ -1130,6 +1134,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> {
|
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
|
||||||
type Item = (&'a K, &'a mut V);
|
type Item = (&'a K, &'a mut V);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue