diff options
| author | bors <bors@rust-lang.org> | 2014-07-08 00:31:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-07-08 00:31:42 +0000 |
| commit | a3257804df2bace236f83d9e5a9e887a1df30ef5 (patch) | |
| tree | c363f1128a77eade9cfd55fc52589f4aaf7681d8 /src/libcore | |
| parent | 00cdd639a93ec1dcad85cebc52214eeba0441c93 (diff) | |
| parent | fa8da9d6b317f39402f1127575e2bd08db33c508 (diff) | |
| download | rust-a3257804df2bace236f83d9e5a9e887a1df30ef5.tar.gz rust-a3257804df2bace236f83d9e5a9e887a1df30ef5.zip | |
auto merge of #15406 : luqmana/rust/nop, r=pcwalton
Extend the null ptr optimization to work with slices, closures, procs, & trait objects by using the internal pointers as the discriminant. This decreases the size of `Option<&[int]>` (and similar) by one word.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/slice.rs | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 0178c0318b8..8197a7c2dcb 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -884,17 +884,20 @@ macro_rules! iterator { if self.ptr == self.end { None } else { - let old = self.ptr; - self.ptr = if mem::size_of::<T>() == 0 { + if mem::size_of::<T>() == 0 { // purposefully don't use 'ptr.offset' because for // vectors with 0-size elements this would return the // same pointer. - transmute(self.ptr as uint + 1) + self.ptr = transmute(self.ptr as uint + 1); + + // Use a non-null pointer value + Some(transmute(1u)) } else { - self.ptr.offset(1) - }; + let old = self.ptr; + self.ptr = self.ptr.offset(1); - Some(transmute(old)) + Some(transmute(old)) + } } } } @@ -916,13 +919,17 @@ macro_rules! iterator { if self.end == self.ptr { None } else { - self.end = if mem::size_of::<T>() == 0 { + if mem::size_of::<T>() == 0 { // See above for why 'ptr.offset' isn't used - transmute(self.end as uint - 1) + self.end = transmute(self.end as uint - 1); + + // Use a non-null pointer value + Some(transmute(1u)) } else { - self.end.offset(-1) - }; - Some(transmute(self.end)) + self.end = self.end.offset(-1); + + Some(transmute(self.end)) + } } } } @@ -956,7 +963,12 @@ impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> { fn idx(&mut self, index: uint) -> Option<&'a T> { unsafe { if index < self.indexable() { - transmute(self.ptr.offset(index as int)) + if mem::size_of::<T>() == 0 { + // Use a non-null pointer value + Some(transmute(1u)) + } else { + Some(transmute(self.ptr.offset(index as int))) + } } else { None } |
