Skip to content

Commit 84f1238

Browse files
committed
---
yaml --- r: 184271 b: refs/heads/tmp c: ae7c534 h: refs/heads/master i: 184269: 7a659ee 184267: 66d9b99 184263: 7ca85b1 184255: f72564e v: v3
1 parent 2faaa79 commit 84f1238

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ refs/heads/building: 126db549b038c84269a1e4fe46f051b2c15d6970
3434
refs/heads/beta: 522d09dfecbeca1595f25ac58c6d0178bbd21d7d
3535
refs/heads/windistfix: 7608dbad651f02e837ed05eef3d74a6662a6e928
3636
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
37-
refs/heads/tmp: 9e0bb528a42a9c963d1616a86e0eb8fb80b34be8
37+
refs/heads/tmp: ae7c534d042bb37e7e22cefabaa81b304638bc0b

branches/tmp/src/libstd/collections/hash/table.rs

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use num::{Int, UnsignedInt};
2323
use ops::{Deref, DerefMut, Drop};
2424
use option::Option;
2525
use option::Option::{Some, None};
26-
use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory};
27-
use rt::heap::{allocate, deallocate};
26+
use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory};
27+
use rt::heap::{allocate, deallocate, EMPTY};
2828
use collections::hash_state::HashState;
2929

3030
const EMPTY_BUCKET: u64 = 0u64;
@@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64;
6969
pub struct RawTable<K, V> {
7070
capacity: usize,
7171
size: usize,
72-
hashes: *mut u64,
72+
hashes: Unique<u64>,
73+
7374
// Because K/V do not appear directly in any of the types in the struct,
7475
// inform rustc that in fact instances of K and V are reachable from here.
75-
marker: marker::CovariantType<(K,V)>,
76+
marker: marker::PhantomData<(K,V)>,
7677
}
7778

7879
unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
@@ -81,7 +82,8 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
8182
struct RawBucket<K, V> {
8283
hash: *mut u64,
8384
key: *mut K,
84-
val: *mut V
85+
val: *mut V,
86+
_marker: marker::PhantomData<(K,V)>,
8587
}
8688

8789
impl<K,V> Copy for RawBucket<K,V> {}
@@ -170,11 +172,12 @@ fn can_alias_safehash_as_u64() {
170172
}
171173

172174
impl<K, V> RawBucket<K, V> {
173-
unsafe fn offset(self, count: int) -> RawBucket<K, V> {
175+
unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
174176
RawBucket {
175177
hash: self.hash.offset(count),
176178
key: self.key.offset(count),
177179
val: self.val.offset(count),
180+
_marker: marker::PhantomData,
178181
}
179182
}
180183
}
@@ -567,10 +570,11 @@ impl<K, V> RawTable<K, V> {
567570
return RawTable {
568571
size: 0,
569572
capacity: 0,
570-
hashes: ptr::null_mut(),
571-
marker: marker::CovariantType,
573+
hashes: Unique::new(EMPTY as *mut u64),
574+
marker: marker::PhantomData,
572575
};
573576
}
577+
574578
// No need for `checked_mul` before a more restrictive check performed
575579
// later in this method.
576580
let hashes_size = capacity * size_of::<u64>();
@@ -606,25 +610,26 @@ impl<K, V> RawTable<K, V> {
606610
RawTable {
607611
capacity: capacity,
608612
size: 0,
609-
hashes: hashes,
610-
marker: marker::CovariantType,
613+
hashes: Unique::new(hashes),
614+
marker: marker::PhantomData,
611615
}
612616
}
613617

614618
fn first_bucket_raw(&self) -> RawBucket<K, V> {
615619
let hashes_size = self.capacity * size_of::<u64>();
616620
let keys_size = self.capacity * size_of::<K>();
617621

618-
let buffer = self.hashes as *mut u8;
622+
let buffer = *self.hashes as *mut u8;
619623
let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
620624
keys_size, min_align_of::<K>(),
621625
min_align_of::<V>());
622626

623627
unsafe {
624628
RawBucket {
625-
hash: self.hashes,
629+
hash: *self.hashes,
626630
key: buffer.offset(keys_offset as isize) as *mut K,
627-
val: buffer.offset(vals_offset as isize) as *mut V
631+
val: buffer.offset(vals_offset as isize) as *mut V,
632+
_marker: marker::PhantomData,
628633
}
629634
}
630635
}
@@ -634,7 +639,7 @@ impl<K, V> RawTable<K, V> {
634639
pub fn new(capacity: usize) -> RawTable<K, V> {
635640
unsafe {
636641
let ret = RawTable::new_uninitialized(capacity);
637-
zero_memory(ret.hashes, capacity);
642+
zero_memory(*ret.hashes, capacity);
638643
ret
639644
}
640645
}
@@ -656,7 +661,7 @@ impl<K, V> RawTable<K, V> {
656661
hashes_end: unsafe {
657662
self.hashes.offset(self.capacity as isize)
658663
},
659-
marker: marker::ContravariantLifetime,
664+
marker: marker::PhantomData,
660665
}
661666
}
662667

@@ -681,7 +686,7 @@ impl<K, V> RawTable<K, V> {
681686
iter: RawBuckets {
682687
raw: raw,
683688
hashes_end: hashes_end,
684-
marker: marker::ContravariantLifetime,
689+
marker: marker::PhantomData,
685690
},
686691
table: self,
687692
}
@@ -694,7 +699,7 @@ impl<K, V> RawTable<K, V> {
694699
iter: RawBuckets {
695700
raw: raw,
696701
hashes_end: hashes_end,
697-
marker: marker::ContravariantLifetime::<'static>,
702+
marker: marker::PhantomData,
698703
},
699704
table: self,
700705
}
@@ -708,7 +713,7 @@ impl<K, V> RawTable<K, V> {
708713
raw: raw_bucket.offset(self.capacity as isize),
709714
hashes_end: raw_bucket.hash,
710715
elems_left: self.size,
711-
marker: marker::ContravariantLifetime,
716+
marker: marker::PhantomData,
712717
}
713718
}
714719
}
@@ -718,7 +723,13 @@ impl<K, V> RawTable<K, V> {
718723
struct RawBuckets<'a, K, V> {
719724
raw: RawBucket<K, V>,
720725
hashes_end: *mut u64,
721-
marker: marker::ContravariantLifetime<'a>,
726+
727+
// Strictly speaking, this should be &'a (K,V), but that would
728+
// require that K:'a, and we often use RawBuckets<'static...> for
729+
// move iterations, so that messes up a lot of other things. So
730+
// just use `&'a (K,V)` as this is not a publicly exposed type
731+
// anyway.
732+
marker: marker::PhantomData<&'a ()>,
722733
}
723734

724735
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -727,7 +738,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
727738
RawBuckets {
728739
raw: self.raw,
729740
hashes_end: self.hashes_end,
730-
marker: marker::ContravariantLifetime,
741+
marker: marker::PhantomData,
731742
}
732743
}
733744
}
@@ -759,7 +770,11 @@ struct RevMoveBuckets<'a, K, V> {
759770
raw: RawBucket<K, V>,
760771
hashes_end: *mut u64,
761772
elems_left: usize,
762-
marker: marker::ContravariantLifetime<'a>,
773+
774+
// As above, `&'a (K,V)` would seem better, but we often use
775+
// 'static for the lifetime, and this is not a publicly exposed
776+
// type.
777+
marker: marker::PhantomData<&'a ()>,
763778
}
764779

765780
impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
@@ -966,9 +981,10 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
966981
#[unsafe_destructor]
967982
impl<K, V> Drop for RawTable<K, V> {
968983
fn drop(&mut self) {
969-
if self.hashes.is_null() {
984+
if self.capacity == 0 {
970985
return;
971986
}
987+
972988
// This is done in reverse because we've likely partially taken
973989
// some elements out with `.into_iter()` from the front.
974990
// Check if the size is 0, so we don't do a useless scan when
@@ -986,7 +1002,7 @@ impl<K, V> Drop for RawTable<K, V> {
9861002
vals_size, min_align_of::<V>());
9871003

9881004
unsafe {
989-
deallocate(self.hashes as *mut u8, size, align);
1005+
deallocate(*self.hashes as *mut u8, size, align);
9901006
// Remember how everything was allocated out of one buffer
9911007
// during initialization? We only need one call to free here.
9921008
}

0 commit comments

Comments
 (0)