Skip to content

Commit 491bc35

Browse files
committed
auto merge of #8745 : brson/rust/metadata, r=cmr
This does two things: 1) stops compressing metadata, 2) stops copying the metadata section, instead holding a reference to the buffer returned by the LLVM section iterator. Not compressing metadata requires something like 7x the storage space, but makes running tests about 9% faster. This has been a time improvement on all platforms I've tested, including windows. I considered leaving compression as an option but it doesn't seem to be worth the complexity since we don't currently have any use cases where we need to save that space. In order to avoid copying the metadata section I had to hack up extra::ebml a bit to support unsafe buffers. We should probably move it into librustc so that it can evolve to support the compiler without worrying about having a crummy interface. r? @graydon
2 parents 05f1bbb + 022f188 commit 491bc35

File tree

10 files changed

+133
-90
lines changed

10 files changed

+133
-90
lines changed

configure

+2-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,8 @@ opt mingw-cross 0 "cross-compile for win32 using mingw"
381381
opt clang 0 "prefer clang to gcc for building the runtime"
382382
opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
383383
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
384-
opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)"
384+
opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched
385+
kernels)"
385386
valopt prefix "/usr/local" "set installation prefix"
386387
valopt local-rust-root "/usr/local" "set prefix for local rust binary"
387388
valopt llvm-root "" "set LLVM root"

src/libextra/ebml.rs

+57-20
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313

1414
use std::str;
15+
use std::cast;
16+
use std::vec;
1517

1618
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
1719
// cursor model. See the specification here:
@@ -29,9 +31,42 @@ struct EbmlState {
2931
data_pos: uint,
3032
}
3133

34+
#[deriving(Clone)]
35+
pub enum EbmlData {
36+
SafeData(@~[u8]),
37+
UnsafeData(*u8, uint)
38+
}
39+
40+
impl EbmlData {
41+
#[inline]
42+
pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [u8] {
43+
match *self {
44+
SafeData(@ref v) => v.slice(start, end),
45+
UnsafeData(buf, len) => unsafe {
46+
do vec::raw::buf_as_slice(buf, len) |s| {
47+
cast::transmute(s.slice(start, end))
48+
}
49+
}
50+
}
51+
}
52+
53+
#[inline]
54+
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
55+
self.slice(0, self.len())
56+
}
57+
58+
#[inline]
59+
pub fn len(&self) -> uint {
60+
match *self {
61+
SafeData(@ref v) => v.len(),
62+
UnsafeData(_, len) => len
63+
}
64+
}
65+
}
66+
3267
#[deriving(Clone)]
3368
pub struct Doc {
34-
data: @~[u8],
69+
data: EbmlData,
3570
start: uint,
3671
end: uint,
3772
}
@@ -185,24 +220,28 @@ pub mod reader {
185220
}
186221

187222
pub fn Doc(data: @~[u8]) -> Doc {
188-
Doc { data: data, start: 0u, end: data.len() }
223+
Doc { data: SafeData(data), start: 0u, end: data.len() }
224+
}
225+
226+
pub fn unsafe_Doc(buf: *u8, len: uint) -> Doc {
227+
Doc { data: UnsafeData(buf, len), start: 0u, end: len }
189228
}
190229

191-
pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
192-
let elt_tag = vuint_at(*data, start);
193-
let elt_size = vuint_at(*data, elt_tag.next);
230+
pub fn doc_at(data: &EbmlData, start: uint) -> TaggedDoc {
231+
let elt_tag = vuint_at(data.as_slice(), start);
232+
let elt_size = vuint_at(data.as_slice(), elt_tag.next);
194233
let end = elt_size.next + elt_size.val;
195234
TaggedDoc {
196235
tag: elt_tag.val,
197-
doc: Doc { data: data, start: elt_size.next, end: end }
236+
doc: Doc { data: data.clone(), start: elt_size.next, end: end }
198237
}
199238
}
200239

201240
pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
202241
let mut pos = d.start;
203242
while pos < d.end {
204-
let elt_tag = vuint_at(*d.data, pos);
205-
let elt_size = vuint_at(*d.data, elt_tag.next);
243+
let elt_tag = vuint_at(d.data.as_slice(), pos);
244+
let elt_size = vuint_at(d.data.as_slice(), elt_tag.next);
206245
pos = elt_size.next + elt_size.val;
207246
if elt_tag.val == tg {
208247
return Some(Doc { data: d.data, start: elt_size.next,
@@ -225,8 +264,8 @@ pub mod reader {
225264
pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool {
226265
let mut pos = d.start;
227266
while pos < d.end {
228-
let elt_tag = vuint_at(*d.data, pos);
229-
let elt_size = vuint_at(*d.data, elt_tag.next);
267+
let elt_tag = vuint_at(d.data.as_slice(), pos);
268+
let elt_size = vuint_at(d.data.as_slice(), elt_tag.next);
230269
pos = elt_size.next + elt_size.val;
231270
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
232271
if !it(elt_tag.val, doc) {
@@ -239,8 +278,8 @@ pub mod reader {
239278
pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool {
240279
let mut pos = d.start;
241280
while pos < d.end {
242-
let elt_tag = vuint_at(*d.data, pos);
243-
let elt_size = vuint_at(*d.data, elt_tag.next);
281+
let elt_tag = vuint_at(d.data.as_slice(), pos);
282+
let elt_size = vuint_at(d.data.as_slice(), elt_tag.next);
244283
pos = elt_size.next + elt_size.val;
245284
if elt_tag.val == tg {
246285
let doc = Doc { data: d.data, start: elt_size.next,
@@ -260,22 +299,22 @@ pub mod reader {
260299

261300
pub fn doc_as_u8(d: Doc) -> u8 {
262301
assert_eq!(d.end, d.start + 1u);
263-
(*d.data)[d.start]
302+
d.data.as_slice()[d.start]
264303
}
265304

266305
pub fn doc_as_u16(d: Doc) -> u16 {
267306
assert_eq!(d.end, d.start + 2u);
268-
io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
307+
io::u64_from_be_bytes(d.data.as_slice(), d.start, 2u) as u16
269308
}
270309

271310
pub fn doc_as_u32(d: Doc) -> u32 {
272311
assert_eq!(d.end, d.start + 4u);
273-
io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
312+
io::u64_from_be_bytes(d.data.as_slice(), d.start, 4u) as u32
274313
}
275314

276315
pub fn doc_as_u64(d: Doc) -> u64 {
277316
assert_eq!(d.end, d.start + 8u);
278-
io::u64_from_be_bytes(*d.data, d.start, 8u)
317+
io::u64_from_be_bytes(d.data.as_slice(), d.start, 8u)
279318
}
280319

281320
pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
@@ -298,8 +337,7 @@ pub mod reader {
298337
impl Decoder {
299338
fn _check_label(&mut self, lbl: &str) {
300339
if self.pos < self.parent.end {
301-
let TaggedDoc { tag: r_tag, doc: r_doc } =
302-
doc_at(self.parent.data, self.pos);
340+
let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(&self.parent.data, self.pos);
303341

304342
if r_tag == (EsLabel as uint) {
305343
self.pos = r_doc.end;
@@ -316,8 +354,7 @@ pub mod reader {
316354
if self.pos >= self.parent.end {
317355
fail!("no more documents in current node!");
318356
}
319-
let TaggedDoc { tag: r_tag, doc: r_doc } =
320-
doc_at(self.parent.data, self.pos);
357+
let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(&self.parent.data, self.pos);
321358
debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
322359
self.parent.start,
323360
self.parent.end,

src/librustc/driver/driver.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ pub fn build_session_options(binary: @str,
763763
parse_only: parse_only,
764764
no_trans: no_trans,
765765
debugging_opts: debugging_opts,
766-
android_cross_path: android_cross_path
766+
android_cross_path: android_cross_path,
767767
};
768768
return sopts;
769769
}

src/librustc/metadata/creader.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use metadata::cstore;
1515
use metadata::decoder;
1616
use metadata::filesearch::FileSearch;
1717
use metadata::loader;
18+
use metadata::loader::MetadataSection;
1819

1920
use std::hashmap::HashMap;
2021
use syntax::ast;
@@ -308,7 +309,7 @@ fn resolve_crate(e: @mut Env,
308309
}
309310

310311
// Go through the crate metadata and load any crates that it references
311-
fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
312+
fn resolve_crate_deps(e: @mut Env, cdata: MetadataSection) -> cstore::cnum_map {
312313
debug!("resolving deps of external crate");
313314
// The map from crate numbers in the crate we're resolving to local crate
314315
// numbers

src/librustc/metadata/csearch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
188188
def: ast::def_id) -> ty::ty_param_bounds_and_ty {
189189
let cstore = tcx.cstore;
190190
let cdata = cstore::get_crate_data(cstore, class_id.crate);
191-
let all_items = reader::get_doc(reader::Doc(cdata.data), tag_items);
191+
let all_items = reader::get_doc(decoder::section_to_ebml_doc(cdata.data), tag_items);
192192
debug!("Looking up %?", class_id);
193193
let class_doc = expect(tcx.diag,
194194
decoder::maybe_find_item(class_id.node, all_items),

src/librustc/metadata/cstore.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use metadata::cstore;
1717
use metadata::decoder;
18+
use metadata::loader::MetadataSection;
1819

1920
use std::hashmap::HashMap;
2021
use extra;
@@ -29,7 +30,7 @@ pub type cnum_map = @mut HashMap<ast::CrateNum, ast::CrateNum>;
2930

3031
pub struct crate_metadata {
3132
name: @str,
32-
data: @~[u8],
33+
data: MetadataSection,
3334
cnum_map: cnum_map,
3435
cnum: ast::CrateNum
3536
}

0 commit comments

Comments
 (0)