bors [Sat, 15 Feb 2014 23:21:28 +0000 (15:21 -0800)]
auto merge of #12235 : huonw/rust/raii-lock, r=alexcrichton
- adds a `LockGuard` type returned by `.lock` and `.trylock` that unlocks the mutex in the destructor
- renames `mutex::Mutex` to `StaticNativeMutex`
- adds a `NativeMutex` type with a destructor
- removes `LittleLock`
- adds `#[must_use]` to `sync::mutex::Guard` to remind people to use it
Steven Fackler [Sat, 15 Feb 2014 21:51:37 +0000 (13:51 -0800)]
Add a method to LimitReader to return the limit
This is useful in contexts like this:
let size = rdr.read_be_i32() as uint;
let mut limit = LimitReader::new(rdr.by_ref(), size);
let thing = read_a_thing(&mut limit);
assert!(limit.limit() == 0);
bors [Sat, 15 Feb 2014 20:46:23 +0000 (12:46 -0800)]
auto merge of #12296 : dotdash/rust/byval_noalias, r=cmr
Function parameters that are to be passed by value but don't fit into a
single register are currently passed by creating a copy on the stack and
passing a pointer to that copy to the callee. Since the copy is made
just for the function call, there are no aliases.
For example, this sometimes allows LLVM to eliminate unnecessary calls
to drop glue. Given
````rust
struct Foo {
a: int,
b: Option<~str>,
}
extern {
fn eat(eat: Option<~str>);
}
pub fn foo(v: Foo) {
match v {
Foo { a: _, b } => unsafe { eat(b) }
}
}
````
LLVM currently can't eliminate the drop call for the string, because it
only sees a _pointer_ to Foo, for which it has to expect an alias. So we
get:
Björn Steinbrink [Sat, 15 Feb 2014 20:31:20 +0000 (21:31 +0100)]
Declare by-value on-stack parameters to be noalias
Function parameters that are to be passed by value but don't fit into a
single register are currently passed by creating a copy on the stack and
passing a pointer to that copy to the callee. Since the copy is made
just for the function call, there are no aliases.
For example, this sometimes allows LLVM to eliminate unnecessary calls
to drop glue. Given
````rust
struct Foo {
a: int,
b: Option<~str>,
}
extern {
fn eat(eat: Option<~str>);
}
pub fn foo(v: Foo) {
match v {
Foo { a: _, b } => unsafe { eat(b) }
}
}
````
LLVM currently can't eliminate the drop call for the string, because it
only sees a _pointer_ to Foo, for which it has to expect an alias. So we
get:
bors [Sat, 15 Feb 2014 10:36:27 +0000 (02:36 -0800)]
auto merge of #12283 : kballard/rust/env-args-bytes, r=erickt
Change `os::args()` and `os::env()` to use `str::from_utf8_lossy()`.
Add new functions `os::args_as_bytes()` and `os::env_as_bytes()` to retrieve the args/env as byte vectors instead.
The existing methods were left returning strings because I expect that the common use-case is to want string handling.
bors [Sat, 15 Feb 2014 07:46:29 +0000 (23:46 -0800)]
auto merge of #12230 : DaGenix/rust/io-decorator-changes, r=sfackler
I created RefReader and RefWriter structs that wrap a mutable reference to a Reader or Writer value. This works exactly like the ByRef struct in the iter module and allows passing a reference to a Reader or Writer to function expecting a Reader or Writer by value with the caller retaining ownership to the original value.
I also modified LimitReader to take the wrapped Reader by value instead of by reference.
Alex Crichton [Sat, 15 Feb 2014 07:30:10 +0000 (23:30 -0800)]
Update rustdoc testing to test all code blocks
It's too easy to forget the `rust` tag to have a code example tested, and it's
far more common to have testable code than untestable code.
This alters rustdoc to have only two directives, `ignore` and `should_fail`. The
`ignore` directive ignores the code block entirely, and the `should_fail`
directive has been fixed to only fail the test if the code execution fails, not
also compilation.
Kevin Ballard [Fri, 14 Feb 2014 23:18:51 +0000 (15:18 -0800)]
Use str::from_utf8_lossy() for os::env() and friends
Parse the environment by default with from_utf8_lossy. Also provide
byte-vector equivalents (e.g. os::env_as_bytes()).
Unfortunately, setenv() can't have a byte-vector equivalent because of
Windows support, unless we want to define a setenv_bytes() that fails
under Windows for non-UTF8 (or non-UTF16).
Kevin Ballard [Fri, 14 Feb 2014 22:42:40 +0000 (14:42 -0800)]
Use str::from_utf8_lossy() in os::args(), add os::args_as_bytes()
os::args() was using str::raw::from_c_str(), which would assert if the
C-string wasn't valid UTF-8. Switch to using from_utf8_lossy() instead,
and add a separate function os::args_as_bytes() that returns the ~[u8]
byte-vectors instead.
bors [Sat, 15 Feb 2014 04:51:26 +0000 (20:51 -0800)]
auto merge of #12274 : brson/rust/mkfiles, r=alexcrichton
I've been working on binary installers and ended up taking this detour, which does a few things:
* It expands the documentation on the build system with new comments in Makefile.in
* It displays some of that documentation via `make help`
* Removes some unused and broken snapshot code
* Adds `NO_MKFILE_DEPS` to convenience makefile hacking
* Moves almost all of Makefile.in to files in `mk/`
The documentation provided by `make help` and its implementation are somewhat quirky.
bors [Sat, 15 Feb 2014 01:51:29 +0000 (17:51 -0800)]
auto merge of #12277 : alexcrichton/rust/fix-rustdoc-render, r=huonw
The std macros used to be injected with a filename of "<std-macros>", but macros
are now injected with a filename of "<{} macros>" where `{}` is filled in with
the crate name. This updates rustdoc to understand this new system so it'll
render source more frequently.
Brian Anderson [Fri, 14 Feb 2014 07:55:49 +0000 (23:55 -0800)]
mk: Move most of Makefile.in to .mk files
Because the build system treats Makefile.in and the .mk files slightly
differently (.in is copied, .mk are included), this makes the system
more uniform. Fewer build system changes will require a complete
reconfigure.
bors [Fri, 14 Feb 2014 21:36:35 +0000 (13:36 -0800)]
auto merge of #12195 : kballard/rust/rustdoc-strip-impls-of-stripped, r=cmr
Strip trait impls for types that are stripped either due to the strip-hidden or strip-private passes.
This fixes the search index including trait methods on stripped structs (which breaks searching), and it also removes private types from the implementors list of a trait.
Alex Crichton [Fri, 14 Feb 2014 21:11:36 +0000 (13:11 -0800)]
Update restrictions on rustdoc source rendering
The std macros used to be injected with a filename of "<std-macros>", but macros
are now injected with a filename of "<{} macros>" where `{}` is filled in with
the crate name. This updates rustdoc to understand this new system so it'll
render source more frequently.
Kevin Ballard [Tue, 11 Feb 2014 22:29:23 +0000 (14:29 -0800)]
rustdoc: Strip impls of stripped private types
In strip-private, also strip impls of traits for private types. This
fixes the search index so searching for "drop", "eq", etc doesn't throw
an exception.
Alex Crichton [Fri, 14 Feb 2014 16:13:19 +0000 (08:13 -0800)]
Add MKFILE_DEPS to compiler-rt target
Currently when you run `make -jN` it's likely that you'll remove compiler-rt and
then it won't get cp'd back into the right place. I believe the reason for this
is that the compiler-rt library target never got updated so make decided it
never needed to copy the files back into place. The files were all there at the
beginning of `make`, but then we may clean out the stage0 versions if we unzip
the snapshot again.
bors [Fri, 14 Feb 2014 18:41:45 +0000 (10:41 -0800)]
auto merge of #12205 : alexcrichton/rust/nodefaultlibs, r=brson
This will hopefully bring us closer to #11937. We're still using gcc's idea of
"startup files", but this should prevent us from leaking in dependencies that we
don't quite want (libgcc for example once compiler-rt is what we use).
Alex Crichton [Tue, 4 Feb 2014 16:37:07 +0000 (08:37 -0800)]
Invoke gcc with -nodefaultlibs
This will hopefully bring us closer to #11937. We're still using gcc's idea of
"startup files", but this should prevent us from leaking in dependencies that we
don't quite want (libgcc for example once compiler-rt is what we use).
Steven Fackler [Fri, 14 Feb 2014 06:57:43 +0000 (22:57 -0800)]
Expand ItemDecorator extensions in all contexts
Now that fold_item can return multiple items, this is pretty trivial. It
also recursively expands generated items so ItemDecorators can generate
items that are tagged with ItemDecorators!
Alex Crichton [Wed, 12 Feb 2014 18:25:09 +0000 (10:25 -0800)]
extra: Capture stdout/stderr of tests by default
When tests fail, their stdout and stderr is printed as part of the summary, but
this helps suppress failure messages from #[should_fail] tests and generally
clean up the output of the test runner.
bors [Fri, 14 Feb 2014 15:26:40 +0000 (07:26 -0800)]
auto merge of #12207 : alexcrichton/rust/up-llvm, r=sfackler
Includes an upstream commit by pcwalton to improve codegen of our enums getting
moved around.
This also introduces a new commit on top of our stack of patches to fix a mingw32 build issue. I have submitted the patch upstream: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140210/204653.html
I verified that this builds on the try bots, which amazes me because I think that c++11 is turned on now, but I guess we're still lucky!
Closes #10613 (pcwalton's patch landed)
Closes #11992 (llvm has removed these options)
bors [Fri, 14 Feb 2014 14:11:43 +0000 (06:11 -0800)]
auto merge of #12234 : sfackler/rust/restructure-item-decorator, r=huonw
The old method of building up a list of items and threading it through
all of the decorators was unwieldy and not really scalable as
non-deriving ItemDecorators become possible. The API is now that the
decorator gets an immutable reference to the item it's attached to, and
a callback that it can pass new items to. If we want to add syntax
extensions that can modify the item they're attached to, we can add that
later, but I think it'll have to be separate from ItemDecorator to avoid
strange ordering issues.
bors [Fri, 14 Feb 2014 08:26:47 +0000 (00:26 -0800)]
auto merge of #12186 : alexcrichton/rust/no-sleep-2, r=brson
Any single-threaded task benchmark will spend a good chunk of time in `kqueue()` on osx and `epoll()` on linux, and the reason for this is that each time a task is terminated it will hit the syscall. When a task terminates, it context switches back to the scheduler thread, and the scheduler thread falls out of `run_sched_once` whenever it figures out that it did some work.
If we know that `epoll()` will return nothing, then we can continue to do work locally (only while there's work to be done). We must fall back to `epoll()` whenever there's active I/O in order to check whether it's ready or not, but without that (which is largely the case in benchmarks), we can prevent the costly syscall and can get a nice speedup.
I've separated the commits into preparation for this change and then the change itself, the last commit message has more details.
Steven Fackler [Thu, 13 Feb 2014 07:53:52 +0000 (23:53 -0800)]
Tweak ItemDecorator API
The old method of building up a list of items and threading it through
all of the decorators was unwieldy and not really scalable as
non-deriving ItemDecorators become possible. The API is now that the
decorator gets an immutable reference to the item it's attached to, and
a callback that it can pass new items to. If we want to add syntax
extensions that can modify the item they're attached to, we can add that
later, but I think it'll have to be separate from ItemDecorator to avoid
strange ordering issues.
bors [Fri, 14 Feb 2014 04:36:55 +0000 (20:36 -0800)]
auto merge of #12172 : alexcrichton/rust/green-improvements, r=brson
These commits pick off some low-hanging fruit which were slowing down spawning green threads. The major speedup comes from fixing a bug in stack caching where we never used any cached stacks!
The program I used to benchmark is at the end. It was compiled with `rustc --opt-level=3 bench.rs --test` and run as `RUST_THREADS=1 ./bench --bench`. I chose to use `RUST_THREADS=1` due to #11730 as the profiles I was getting interfered too much when all the schedulers were in play (and shouldn't be after #11730 is fixed). All of the units below are in ns/iter as reported by `--bench` (lower is better).
| | green | native | raw |
| ------------- | ----- | ------ | ------ |
| osx before | 12699 | 24030 | 19734 |
| linux before | 10223 | 125983 | 122647 |
| osx after | 3847 | 25771 | 20835 |
| linux after | 2631 | 135398 | 122765 |
Note that this is *not* a benchmark of spawning green tasks vs native tasks. I put in the native numbers just to get a ballpark of where green tasks are. This is benchmark is *clearly* benefiting from stack caching. Also, OSX is clearly not 5x faster than linux, I think my VM is just much slower.
All in all, this ended up being a nice 4x speedup for spawning a green task when you're using a cached stack.
```rust
extern mod extra;
extern mod native;
use std::rt::thread::Thread;
#[bench]
fn green(bh: &mut extra::test::BenchHarness) {
let (p, c) = SharedChan::new();
bh.iter(|| {
let c = c.clone();
spawn(proc() {
c.send(());
});
p.recv();
});
}
#[bench]
fn native(bh: &mut extra::test::BenchHarness) {
let (p, c) = SharedChan::new();
bh.iter(|| {
let c = c.clone();
native::task::spawn(proc() {
c.send(());
});
p.recv();
});
}
Alex Crichton [Tue, 11 Feb 2014 00:13:50 +0000 (16:13 -0800)]
Remove two allocations from spawning a green task
Two unfortunate allocations were wrapping a proc() in a proc() with
GreenTask::build_start_wrapper, and then boxing this proc in a ~proc() inside of
Context::new(). Both of these allocations were a direct result from two
conditions:
1. The Context::new() function has a nice api of taking a procedure argument to
start up a new context with. This inherently required an allocation by
build_start_wrapper because extra code needed to be run around the edges of a
user-provided proc() for a new task.
2. The initial bootstrap code only understood how to pass one argument to the
next function. By modifying the assembly and entry points to understand more
than one argument, more information is passed through in registers instead of
allocating a pointer-sized context.
This is sadly where I end up throwing mips under a bus because I have no idea
what's going on in the mips context switching code and don't know how to modify
it.
Alex Crichton [Mon, 10 Feb 2014 22:49:56 +0000 (14:49 -0800)]
Don't require an allocation for on_exit messages
Instead, use an enum to allow running both a procedure and sending the task
result over a channel. I expect the common case to be sending on a channel (e.g.
task::try), so don't require an extra allocation in the common case.
Alex Crichton [Mon, 10 Feb 2014 22:17:10 +0000 (14:17 -0800)]
Fix a bug where cached stacks weren't re-used
The condition was the wrong direction and it also didn't take equality into
account. Tests were added for both cases.
For the small benchmark of `task::try(proc() {}).unwrap()`, this takes the
iteration time on OSX from 15119 ns/iter to 6179 ns/iter (timed with
RUST_THREADS=1)
bors [Fri, 14 Feb 2014 00:32:01 +0000 (16:32 -0800)]
auto merge of #12017 : FlaPer87/rust/replace-mod-crate, r=alexcrichton
The first setp for #9880 is to add a new `crate` keyword. This PR does exactly that. I took a chance to refactor `parse_item_foreign_mod` and I broke it down into 2 separate methods to isolate each feature.
The next step will be to push a new stage0 snapshot and then get rid of all `extern mod` around the code.
Alex Crichton [Thu, 13 Feb 2014 12:31:19 +0000 (04:31 -0800)]
Lift $dst outside the closure in write!
If you were writing to something along the lines of `self.foo` then with the new
closure rules it meant that you were borrowing `self` for the entirety of the
closure, meaning that you couldn't format other fields of `self` at the same
time as writing to a buffer contained in `self`.
By lifting the borrow outside of the closure the borrow checker can better
understand that you're only borrowing one of the fields at a time. This had to
use type ascription as well in order to preserve trait object coercions.
Huon Wilson [Thu, 13 Feb 2014 08:35:43 +0000 (19:35 +1100)]
mk: make NO_REBUILD more forceful and more general.
Previously crates like `green` and `native` would still depend on their
parents when running `make check-stage2-green NO_REBUILD=1`, this
ensures that they only depend on their source files.
Also, apply NO_REBUILD to the crate doc tests, so, for example,
`check-stage2-doc-std` will use an already compiled `rustdoc` directly.
Alex Crichton [Thu, 13 Feb 2014 04:51:42 +0000 (20:51 -0800)]
Relax an assertion in start_selection()
It asserted that the previous count was always nonnegative, but DISCONNECTED is
a valid value for it to see. In order to continue to remember to store
DISCONNECTED after DISCONNECTED was seen, I also added a helper method.
Remove a source of O(n^2) running time in bigints.
::num::bigint, Remove a source of O(n^2) running time in `fn shr_bits`.
I'll cut to the chase: On my laptop, this brings the running time on
`pidigits 2000` (from src/test/bench/shootout-pidigits.rs) from this:
```
% time ./pidigits 2000 > /dev/null
real 0m7.695s
user 0m7.690s
sys 0m0.005s
```
to this:
```
% time ./pidigits 2000 > /dev/null
real 0m0.322s
user 0m0.318s
sys 0m0.004s
```
The previous code was building up a vector by repeatedly making a
fresh copy for each element that was unshifted onto the front,
yielding quadratic running time. This fixes that by building up the
vector in reverse order (pushing elements onto the end) and then
reversing it.
(Another option would be to build up a zero-initialized vector of the
desired length and then installing all of the shifted result elements
into their target index, but this was easier to hack up quickly, and
yields the desired asymptotic improvement. I have been thinking of
adding a `vec::from_fn_rev` to handle this case, maybe I will try that
this weekend.)