Skip to content

Commit 9751bcd

Browse files
committed
---
yaml --- r: 180179 b: refs/heads/tmp c: 43a2004 h: refs/heads/master i: 180177: b5eac4f 180175: 6ee7dc1 v: v3
1 parent 356fa3e commit 9751bcd

File tree

110 files changed

+2437
-548
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+2437
-548
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: 44a287e6eb22ec3c2a687fc156813577464017f7
3535
refs/heads/windistfix: 7608dbad651f02e837ed05eef3d74a6662a6e928
3636
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
37-
refs/heads/tmp: d4985accb7ab03d1d08945a77b535bfeaf03186c
37+
refs/heads/tmp: 43a200441674a4f58a55b181cff08d60fa25014c

branches/tmp/src/libarena/lib.rs

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use std::cell::{Cell, RefCell};
4242
use std::cmp;
4343
use std::intrinsics::{TyDesc, get_tydesc};
4444
use std::intrinsics;
45+
use std::marker;
4546
use std::mem;
4647
use std::num::{Int, UnsignedInt};
4748
use std::ptr;
@@ -88,27 +89,29 @@ impl Chunk {
8889
/// than objects without destructors. This reduces overhead when initializing
8990
/// plain-old-data (`Copy` types) and means we don't need to waste time running
9091
/// their destructors.
91-
pub struct Arena {
92+
pub struct Arena<'longer_than_self> {
9293
// The head is separated out from the list as a unbenchmarked
9394
// microoptimization, to avoid needing to case on the list to access the
9495
// head.
9596
head: RefCell<Chunk>,
9697
copy_head: RefCell<Chunk>,
9798
chunks: RefCell<Vec<Chunk>>,
99+
_invariant: marker::InvariantLifetime<'longer_than_self>,
98100
}
99101

100-
impl Arena {
102+
impl<'a> Arena<'a> {
101103
/// Allocates a new Arena with 32 bytes preallocated.
102-
pub fn new() -> Arena {
104+
pub fn new() -> Arena<'a> {
103105
Arena::new_with_size(32)
104106
}
105107

106108
/// Allocates a new Arena with `initial_size` bytes preallocated.
107-
pub fn new_with_size(initial_size: usize) -> Arena {
109+
pub fn new_with_size(initial_size: usize) -> Arena<'a> {
108110
Arena {
109111
head: RefCell::new(chunk(initial_size, false)),
110112
copy_head: RefCell::new(chunk(initial_size, true)),
111113
chunks: RefCell::new(Vec::new()),
114+
_invariant: marker::InvariantLifetime,
112115
}
113116
}
114117
}
@@ -122,7 +125,7 @@ fn chunk(size: usize, is_copy: bool) -> Chunk {
122125
}
123126

124127
#[unsafe_destructor]
125-
impl Drop for Arena {
128+
impl<'longer_than_self> Drop for Arena<'longer_than_self> {
126129
fn drop(&mut self) {
127130
unsafe {
128131
destroy_chunk(&*self.head.borrow());
@@ -180,7 +183,7 @@ fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
180183
((p & !1) as *const TyDesc, p & 1 == 1)
181184
}
182185

183-
impl Arena {
186+
impl<'longer_than_self> Arena<'longer_than_self> {
184187
fn chunk_size(&self) -> usize {
185188
self.copy_head.borrow().capacity()
186189
}
@@ -293,7 +296,7 @@ impl Arena {
293296
/// Allocates a new item in the arena, using `op` to initialize the value,
294297
/// and returns a reference to it.
295298
#[inline]
296-
pub fn alloc<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
299+
pub fn alloc<T:'longer_than_self, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
297300
unsafe {
298301
if intrinsics::needs_drop::<T>() {
299302
self.alloc_noncopy(op)
@@ -317,20 +320,6 @@ fn test_arena_destructors() {
317320
}
318321
}
319322

320-
#[test]
321-
fn test_arena_alloc_nested() {
322-
struct Inner { value: usize }
323-
struct Outer<'a> { inner: &'a Inner }
324-
325-
let arena = Arena::new();
326-
327-
let result = arena.alloc(|| Outer {
328-
inner: arena.alloc(|| Inner { value: 10 })
329-
});
330-
331-
assert_eq!(result.inner.value, 10);
332-
}
333-
334323
#[test]
335324
#[should_fail]
336325
fn test_arena_destructors_fail() {
@@ -365,6 +354,10 @@ pub struct TypedArena<T> {
365354

366355
/// A pointer to the first arena segment.
367356
first: RefCell<*mut TypedArenaChunk<T>>,
357+
358+
/// Marker indicating that dropping the arena causes its owned
359+
/// instances of `T` to be dropped.
360+
_own: marker::PhantomData<T>,
368361
}
369362

370363
struct TypedArenaChunk<T> {
@@ -460,6 +453,7 @@ impl<T> TypedArena<T> {
460453
ptr: Cell::new((*chunk).start() as *const T),
461454
end: Cell::new((*chunk).end() as *const T),
462455
first: RefCell::new(chunk),
456+
_own: marker::PhantomData,
463457
}
464458
}
465459
}
@@ -523,6 +517,41 @@ mod tests {
523517
z: i32,
524518
}
525519

520+
#[test]
521+
fn test_arena_alloc_nested() {
522+
struct Inner { value: u8 }
523+
struct Outer<'a> { inner: &'a Inner }
524+
enum EI<'e> { I(Inner), O(Outer<'e>) }
525+
526+
struct Wrap<'a>(TypedArena<EI<'a>>);
527+
528+
impl<'a> Wrap<'a> {
529+
fn alloc_inner<F:Fn() -> Inner>(&self, f: F) -> &Inner {
530+
let r: &EI = self.0.alloc(EI::I(f()));
531+
if let &EI::I(ref i) = r {
532+
i
533+
} else {
534+
panic!("mismatch");
535+
}
536+
}
537+
fn alloc_outer<F:Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
538+
let r: &EI = self.0.alloc(EI::O(f()));
539+
if let &EI::O(ref o) = r {
540+
o
541+
} else {
542+
panic!("mismatch");
543+
}
544+
}
545+
}
546+
547+
let arena = Wrap(TypedArena::new());
548+
549+
let result = arena.alloc_outer(|| Outer {
550+
inner: arena.alloc_inner(|| Inner { value: 10 }) });
551+
552+
assert_eq!(result.inner.value, 10);
553+
}
554+
526555
#[test]
527556
pub fn test_copy() {
528557
let arena = TypedArena::new();

branches/tmp/src/libcollections/bench.rs

Lines changed: 103 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -8,103 +8,113 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use prelude::*;
12-
use std::rand;
13-
use std::rand::Rng;
14-
use test::{Bencher, black_box};
15-
16-
pub fn insert_rand_n<M, I, R>(n: usize,
17-
map: &mut M,
18-
b: &mut Bencher,
19-
mut insert: I,
20-
mut remove: R) where
21-
I: FnMut(&mut M, usize),
22-
R: FnMut(&mut M, usize),
23-
{
24-
// setup
25-
let mut rng = rand::weak_rng();
26-
27-
for _ in 0..n {
28-
insert(map, rng.gen::<usize>() % n);
29-
}
30-
31-
// measure
32-
b.iter(|| {
33-
let k = rng.gen::<usize>() % n;
34-
insert(map, k);
35-
remove(map, k);
36-
});
37-
black_box(map);
11+
macro_rules! map_insert_rand_bench {
12+
($name: ident, $n: expr, $map: ident) => (
13+
#[bench]
14+
pub fn $name(b: &mut ::test::Bencher) {
15+
use std::rand;
16+
use std::rand::Rng;
17+
use test::black_box;
18+
19+
let n: usize = $n;
20+
let mut map = $map::new();
21+
// setup
22+
let mut rng = rand::weak_rng();
23+
24+
for _ in 0..n {
25+
let i = rng.gen() % n;
26+
map.insert(i, i);
27+
}
28+
29+
// measure
30+
b.iter(|| {
31+
let k = rng.gen() % n;
32+
map.insert(k, k);
33+
map.remove(&k);
34+
});
35+
black_box(map);
36+
}
37+
)
3838
}
3939

40-
pub fn insert_seq_n<M, I, R>(n: usize,
41-
map: &mut M,
42-
b: &mut Bencher,
43-
mut insert: I,
44-
mut remove: R) where
45-
I: FnMut(&mut M, usize),
46-
R: FnMut(&mut M, usize),
47-
{
48-
// setup
49-
for i in 0..n {
50-
insert(map, i * 2);
51-
}
52-
53-
// measure
54-
let mut i = 1;
55-
b.iter(|| {
56-
insert(map, i);
57-
remove(map, i);
58-
i = (i + 2) % n;
59-
});
60-
black_box(map);
40+
macro_rules! map_insert_seq_bench {
41+
($name: ident, $n: expr, $map: ident) => (
42+
#[bench]
43+
pub fn $name(b: &mut ::test::Bencher) {
44+
use test::black_box;
45+
46+
let mut map = $map::new();
47+
let n: usize = $n;
48+
// setup
49+
for i in 0..n {
50+
map.insert(i * 2, i * 2);
51+
}
52+
53+
// measure
54+
let mut i = 1;
55+
b.iter(|| {
56+
map.insert(i, i);
57+
map.remove(&i);
58+
i = (i + 2) % n;
59+
});
60+
black_box(map);
61+
}
62+
)
6163
}
6264

63-
pub fn find_rand_n<M, T, I, F>(n: usize,
64-
map: &mut M,
65-
b: &mut Bencher,
66-
mut insert: I,
67-
mut find: F) where
68-
I: FnMut(&mut M, usize),
69-
F: FnMut(&M, usize) -> T,
70-
{
71-
// setup
72-
let mut rng = rand::weak_rng();
73-
let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
74-
75-
for k in &keys {
76-
insert(map, *k);
77-
}
78-
79-
rng.shuffle(&mut keys);
80-
81-
// measure
82-
let mut i = 0;
83-
b.iter(|| {
84-
let t = find(map, keys[i]);
85-
i = (i + 1) % n;
86-
black_box(t);
87-
})
65+
macro_rules! map_find_rand_bench {
66+
($name: ident, $n: expr, $map: ident) => (
67+
#[bench]
68+
pub fn $name(b: &mut ::test::Bencher) {
69+
use std::rand;
70+
use std::rand::Rng;
71+
use test::black_box;
72+
73+
let mut map = $map::new();
74+
let n: usize = $n;
75+
76+
// setup
77+
let mut rng = rand::weak_rng();
78+
let mut keys: Vec<_> = (0..n).map(|_| rng.gen() % n).collect();
79+
80+
for &k in &keys {
81+
map.insert(k, k);
82+
}
83+
84+
rng.shuffle(&mut keys);
85+
86+
// measure
87+
let mut i = 0;
88+
b.iter(|| {
89+
let t = map.get(&keys[i]);
90+
i = (i + 1) % n;
91+
black_box(t);
92+
})
93+
}
94+
)
8895
}
8996

90-
pub fn find_seq_n<M, T, I, F>(n: usize,
91-
map: &mut M,
92-
b: &mut Bencher,
93-
mut insert: I,
94-
mut find: F) where
95-
I: FnMut(&mut M, usize),
96-
F: FnMut(&M, usize) -> T,
97-
{
98-
// setup
99-
for i in 0..n {
100-
insert(map, i);
101-
}
102-
103-
// measure
104-
let mut i = 0;
105-
b.iter(|| {
106-
let x = find(map, i);
107-
i = (i + 1) % n;
108-
black_box(x);
109-
})
97+
macro_rules! map_find_seq_bench {
98+
($name: ident, $n: expr, $map: ident) => (
99+
#[bench]
100+
pub fn $name(b: &mut ::test::Bencher) {
101+
use test::black_box;
102+
103+
let mut map = $map::new();
104+
let n: usize = $n;
105+
106+
// setup
107+
for i in 0..n {
108+
map.insert(i, i);
109+
}
110+
111+
// measure
112+
let mut i = 0;
113+
b.iter(|| {
114+
let x = map.get(&i);
115+
i = (i + 1) % n;
116+
black_box(x);
117+
})
118+
}
119+
)
110120
}

0 commit comments

Comments
 (0)