The compiler has previously been producing binaries on the order of 1.8MB for
hello world programs "fn main() {}". This is largely a result of the compilation
model used by compiling entire libraries into a single object file and because
static linking is favored by default.
When linking, linkers will pull in the entire contents of an object file if any
symbol from the object file is used. This means that if any symbol from a rust
library is used, the entire library is pulled in unconditionally, regardless of
whether the library is used or not.
Traditional C/C++ projects do not normally encounter these large executable
problems because their archives (rust's rlibs) are composed of many objects.
Because of this, linkers can eliminate entire objects from being in the final
executable. With rustc, however, the linker does not have the opportunity to
leave out entire object files.
In order to get similar benefits from dead code stripping at link time, this
commit enables the -ffunction-sections and -fdata-sections flags in LLVM, as
well as passing --gc-sections to the linker *by default*. This means that each
function and each global will be placed into its own section, allowing the
linker to GC all unused functions and data symbols.
By enabling these flags, rust is able to generate much smaller binaries default.
On linux, a hello world binary went from 1.8MB to 597K (a 67% reduction in
size). The output size of dynamic libraries remained constant, but the output
size of rlibs increased, as seen below:
libarena - 2.27% bigger ( 292872 => 299508)
libcollections - 0.64% bigger ( 6765884 => 6809076)
libflate - 0.83% bigger ( 186516 => 188060)
libfourcc - 14.71% bigger ( 307290 => 352498)
libgetopts - 4.42% bigger ( 761468 => 795102)
libglob - 2.73% bigger ( 899932 => 924542)
libgreen - 9.63% bigger ( 1281718 => 1405124)
libhexfloat - 13.88% bigger ( 333738 => 380060)
liblibc - 10.79% bigger ( 551280 => 610736)
liblog - 10.93% bigger ( 218208 => 242060)
libnative - 8.26% bigger ( 1362096 => 1474658)
libnum - 2.34% bigger ( 2583400 => 2643916)
librand - 1.72% bigger ( 1608684 => 1636394)
libregex - 6.50% bigger ( 1747768 => 1861398)
librustc - 4.21% bigger (151820192 => 158218924)
librustdoc - 8.96% bigger ( 13142604 => 14320544)
librustuv - 4.13% bigger ( 4366896 => 4547304)
libsemver - 2.66% bigger ( 396166 => 406686)
libserialize - 1.91% bigger ( 6878396 => 7009822)
libstd - 3.59% bigger ( 39485286 => 40902218)
libsync - 3.95% bigger ( 1386390 => 1441204)
libsyntax - 4.96% bigger ( 35757202 => 37530798)
libterm - 13.99% bigger ( 924580 => 1053902)
libtest - 6.04% bigger ( 2455720 => 2604092)
libtime - 2.84% bigger ( 1075708 => 1106242)
liburl - 6.53% bigger ( 590458 => 629004)
libuuid - 4.63% bigger ( 326350 => 341466)
libworkcache - 8.45% bigger ( 1230702 => 1334750)
This increase in size is a result of encoding many more section names into each
object file (rlib). These increases are moderate enough that this change seems
worthwhile to me, due to the drastic improvements seen in the final artifacts.
The overall increase of the stage2 target folder (not the size of an install)
went from 337MB to 348MB (3% increase).
Additionally, linking is generally slower when executed with all these new
sections plus the --gc-sections flag. The stage0 compiler takes 1.4s to link the
`rustc` binary, where the stage1 compiler takes 1.9s to link the binary. Three
megabytes are shaved off the binary. I found this increase in link time to be
acceptable relative to the benefits of code size gained.
This commit only enables --gc-sections for *executables*, not dynamic libraries.
LLVM does all the heavy lifting when producing an object file for a dynamic
library, so there is little else for the linker to do (remember that we only
have one object file).
I conducted similar experiments by putting a *module's* functions and data
symbols into its own section (granularity moved to a module level instead of a
function/static level). The size benefits of a hello world were seen to be on
the order of 400K rather than 1.2MB. It seemed that enough benefit was gained
using ffunction-sections that this route was less desirable, despite the lesser
increases in binary rlib size.
This PR is primarily motivated by (and fixes) #12926.
We currently only have a span for the individual item itself and not for the referred contents. This normally does not cause a problem since both are located in the same file; it *is* possible that the contained statement or item is located in the other file (the syntax extension can do that), but even in that case the syntax extension should be located in the same file as the item. The module item (i.e. `mod foo;`) is the only exception here, and thus warrants a special treatment.
Rustdoc would now distinguish `mod foo;` from `mod foo {...}` by checking if the span for the module item and module contents is in different files. If it's the case, we'd prefer module contents over module item. There are alternative strategies, but as noted above we will have some corner cases if we don't record the contents span explicitly.
As of cc6ec8df, the Owned closures example uses println! instead of
debug!, making a note about seeing debug seem out-of-place in this
section.
Since debug! is not used elsewhere in the tutorial, remove the note
entirely.
Hello,
With the latest version of Rust, calling to the function [`std::io::standard_error()`](http://static.rust-lang.org/doc/master/std/io/fn.standard_error.html) succeeds only if the value of the argument is `EndOfFile`, `IoUnavailable` or `InvalidInput`. If the function is called with another value as argument, it fails without message.
Here is a piece of code that reproduces the problem:
```rust
use std::io::{standard_error,EndOfFile,FileNotFound,PermissionDenied};
fn main() {
println!("Error 1: {}", standard_error(EndOfFile)); // does not fail
println!("Error 2: {}", standard_error(FileNotFound)); // fails
println!("Error 3: {}", standard_error(PermissionDenied)); //fails
}
```
This was because the `IoErrorKind` passed as argument wasn't matched against all the possible values.
I added the missing branches in the `match` statement inside the function, and i removed the call to the `fail!()` macro. I rebuilt the crate with the latest `rustc` version and it seems to works.
As of cc6ec8df, the Owned closures example uses println! instead of
debug!, making a note about seeing debug seem out-of-place in this
section.
Since debug! is not used elsewhere in the tutorial, remove the note
entirely.
Just modified the documentation for parse_bytes to make it more clear how the bytes were parsed (big endian) and to show an example of what it returned. I also added documentation for the to_str_bytes which previously had no documentation (besides one stackoverflow post).
the basic strategy is to distinguish `mod foo;` from `mod foo {...}`
by checking if the span for the module item and module contents is
in different files. if it's the case, we prefer module contents.
it is technically possible to fix#12926 without changing the AST,
probably by checking the individual items' span. this is not without
a problem though, since it is possible that some items inside
`mod foo {...}` may have originated from other file (e.g. `include!`).
therefore it is better to record both spans explicitly.
I filed bugs #13734 and #13759 recently, and then realized I could probably fix them myself. This does exactly that, with a couple additional modifications and additions to the test-suite to pick up on that.
I've never done this before, so please feel free to tell me all the things I'm doing wrong or could be doing better.
this is useful when the module item and module contents are defined
from different files (like rustdoc). in most cases the original span
for the module item would be used; in other cases, the span for
module contents is available separately at the `inner` field.
It reflected the obsolete syntax `use a, b, c;` and did not make past the parser (though it was a non-fatal error so we can continue). This legacy affected many portions of rustc and rustdoc as well, so this PR cleans them up altogether.
As a side effect of cleanup, we now have `SCHEMA_VERSION` in `rustdoc::clean` (instead of the crate root), so it has a better chance to be updated when `rustdoc::clean` gets updated.
This addresses the ICE from #13763, but it does not allow the test to compile,
due to #13768. An alternate test was checked in in the meantime.
Closes#13763
it reflected the obsolete syntax `use a, b, c;` and did not make
past the parser (though it was a non-fatal error so we can continue).
this legacy affected many portions of rustc and rustdoc as well,
so this commit cleans them up altogether.
Before, tests for dynamic regexes ran during stage1 and tests for
native regexes ran during stage2. But the buildbots don't test stage1,
so now both dynamic and native tests are run during stage2.
Closes#13740.
Clarifies the interaction of `is_dir`, `is_file` and `exists` with
symbolic links. Adds a convenience `lstat` function alongside of
`stat`. Removes references to conditions.
Closes issue #12583.
Clarifies the interaction of `is_dir`, `is_file` and `exists` with
symbolic links. Adds a convenience `lstat` function alongside of
`stat`. Removes references to conditions.
Closes issue #12583.
This addresses the ICE from #13763, but it does not allow the test to compile,
due to #13768. An alternate test was checked in in the meantime.
Closes#13763
Before, tests for dynamic regexes ran during stage1 and tests for
native regexes ran during stage2. But the buildbots don't test stage1,
so now both dynamic and native tests are run during stage2.
Closes#13740.
Follow-up on issue #13297 and PR #13710. Instead of following the (confusing) C/C++ approach
of using `MIN_VALUE` for the smallest *positive* number, we introduce `MIN_POS_VALUE` (and
in the Float trait, `min_pos_value`) to represent this number.
This patch also removes a few remaining redundantly-defined constants that were missed last
time around.
It didn't work because it tried to call itself but symbols are not
exported as default in executables.
Note that `fun5` is not internal anymore since it is in library.
Second commit removes/updates some old tests.
It didn't work because it tried to call itself but symbols are not
exported as default in executables.
Note that `fun5` is not internal anymore since it is in library.
Implements [RFC 7](https://github.com/rust-lang/rfcs/blob/master/active/0007-regexps.md) and will hopefully resolve#3591. The crate is marked as experimental. It includes a syntax extension for compiling regexps to native Rust code.
Embeds and passes the `basic`, `nullsubexpr` and `repetition` tests from [Glenn Fowler's (slightly modified by Russ Cox for leftmost-first semantics) testregex test suite](http://www2.research.att.com/~astopen/testregex/testregex.html). I've also hand written a plethora of other tests that exercise Unicode support, the parser, public API, etc. Also includes a `regex-dna` benchmark for the shootout.
I know the addition looks huge at first, but consider these things:
1. More than half the number of lines is dedicated to Unicode character classes.
2. Of the ~4,500 lines remaining, 1,225 of them are comments.
3. Another ~800 are tests.
4. That leaves 2500 lines for the meat. The parser is ~850 of them. The public API, compiler, dynamic VM and code generator (for `regexp!`) make up the rest.
I decided to put architecture constants in another mod. They are not used, so a part of me is thinking of just getting rid of them altogether. The rest should be similar to what @brson wants.
Fixes#13536