Skip to content

Commit 39e8cb6

Browse files
committed
Don't copy metadata after loading
1 parent 041d8e8 commit 39e8cb6

File tree

7 files changed

+132
-83
lines changed

7 files changed

+132
-83
lines changed

src/libextra/ebml.rs

Lines changed: 57 additions & 20 deletions
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/metadata/creader.rs

Lines changed: 2 additions & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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)