Skip to content

Commit 2bb3b63

Browse files
committed
Eliminate a copy in syntax::parse::new_parser_from_file
Fixing a FIXME turned out to be pretty involved. I added an io function that returns a unique boxed string (for the contents of a file) rather than a string, and went from there. Also made the src field of codemap a unique boxed string. This doesn't seem to make that much difference in amount of allocation according to valgrind (disappointingly), but I also had to introduce a copy somewhere else pending a new snapshot, so maybe that's it.
1 parent dc117fe commit 2bb3b63

File tree

15 files changed

+88
-43
lines changed

15 files changed

+88
-43
lines changed

src/fuzzer/fuzzer.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ fn check_variants_T<T: copy>(
271271
// testing the string for stability is easier and ok for now.
272272
let handler = diagnostic::mk_handler(none);
273273
let str3 =
274-
@as_str(bind pprust::print_crate(
274+
~as_str(bind pprust::print_crate(
275275
codemap,
276276
diagnostic::mk_span_handler(handler, codemap),
277277
crate2,
@@ -417,7 +417,7 @@ fn check_compiling(filename: str) -> happiness {
417417
}
418418

419419

420-
fn parse_and_print(code: @str) -> str {
420+
fn parse_and_print(code: ~str) -> str {
421421
let filename = "tmp.rs";
422422
let cm = codemap::new_codemap();
423423
let handler = diagnostic::mk_handler(none);
@@ -507,7 +507,7 @@ fn file_might_not_converge(filename: str) -> bool {
507507
ret false;
508508
}
509509

510-
fn check_roundtrip_convergence(code: @str, maxIters: uint) {
510+
fn check_roundtrip_convergence(+code: ~str, maxIters: uint) {
511511

512512
let mut i = 0u;
513513
let mut newv = code;
@@ -516,7 +516,7 @@ fn check_roundtrip_convergence(code: @str, maxIters: uint) {
516516
while i < maxIters {
517517
oldv = newv;
518518
if content_might_not_converge(*oldv) { ret; }
519-
newv = @parse_and_print(oldv);
519+
newv = ~parse_and_print(oldv);
520520
if oldv == newv { break; }
521521
i += 1u;
522522
}
@@ -538,7 +538,7 @@ fn check_convergence(files: [str]) {
538538
#error("pp convergence tests: %u files", vec::len(files));
539539
for files.each {|file|
540540
if !file_might_not_converge(file) {
541-
let s = @result::get(io::read_whole_file_str(file));
541+
let s = ~result::get(io::read_whole_file_str(file));
542542
if !content_might_not_converge(*s) {
543543
#error("pp converge: %s", file);
544544
// Change from 7u to 2u once
@@ -557,7 +557,7 @@ fn check_variants(files: [str], cx: context) {
557557
cont;
558558
}
559559

560-
let s = @result::get(io::read_whole_file_str(file));
560+
let s = ~result::get(io::read_whole_file_str(file));
561561
if contains(*s, "#") {
562562
cont; // Macros are confusing
563563
}

src/libcore/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ mod std {
4949

5050
#[doc = "
5151
A standard function to use to indicate unreachable code. Because the
52-
function is guaranteed to fail typestate will correctly identify
52+
function is guaranteed to fail, typestate will correctly identify
5353
any code paths following the appearance of this function as unreachable.
5454
"]
5555
fn unreachable() -> ! {

src/libcore/io.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,24 @@ fn read_whole_file_str(file: str) -> result<str, str> {
650650
})
651651
}
652652

653+
/*
654+
Returns the result as a unique boxed string rather than a string
655+
*/
656+
fn read_whole_file_ref(file: str) -> result<~str, str> {
657+
let f = os::as_c_charp(file, {|pathbuf|
658+
os::as_c_charp("r", {|modebuf|
659+
libc::fopen(pathbuf, modebuf)
660+
})
661+
});
662+
ret if f as uint == 0u { result::err("error opening " + file) }
663+
else unsafe {
664+
let buf : ~mut [const u8] = ~mut [const];
665+
let self = FILE_reader(f, true);
666+
while (!self.eof()) { *buf += self.read_bytes(2048u); }
667+
result::ok(str::unsafe::from_bytes_move(buf))
668+
}
669+
}
670+
653671
// FIXME implement this in a low-level way. Going through the abstractions is
654672
// pointless. // #2004
655673
fn read_whole_file(file: str) -> result<[u8], str> {

src/libcore/str.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ fn from_bytes(vv: [u8]) -> str unsafe {
123123
ret unsafe::from_bytes(vv);
124124
}
125125

126+
#[doc = "
127+
Convert a unique vector of bytes (passed by move)
128+
to a unique boxed UTF-8 string
129+
130+
# Failure
131+
132+
Fails if invalid UTF-8
133+
"]
134+
fn from_bytes_move(-vv: ~mut [const u8]) -> ~str unsafe {
135+
assert is_utf8(::unsafe::reinterpret_cast(vv));
136+
ret unsafe::from_bytes_move(vv);
137+
}
138+
126139
#[doc = "
127140
Convert a byte to a UTF-8 string
128141
@@ -1631,6 +1644,7 @@ mod unsafe {
16311644
from_buf,
16321645
from_c_str,
16331646
from_bytes,
1647+
from_bytes_move,
16341648
slice_bytes,
16351649
push_byte,
16361650
pop_byte,
@@ -1685,6 +1699,13 @@ mod unsafe {
16851699
ret scopy;
16861700
}
16871701

1702+
unsafe fn from_bytes_move(-v: ~mut [const u8]) -> ~str unsafe {
1703+
*v += [0u8];
1704+
let s: ~str = ::unsafe::reinterpret_cast(v);
1705+
::unsafe::forget(v);
1706+
s
1707+
}
1708+
16881709
#[doc = "
16891710
Converts a byte to a string.
16901711

src/librustsyntax/codemap.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ enum file_substr {
3838
}
3939

4040
type filemap =
41-
@{name: filename, substr: file_substr, src: @str,
41+
@{name: filename, substr: file_substr, src: ~str,
4242
start_pos: file_pos, mut lines: [file_pos]};
4343

4444
type codemap = @{mut files: [filemap]};
@@ -48,15 +48,15 @@ type loc = {file: filemap, line: uint, col: uint};
4848
fn new_codemap() -> codemap { @{mut files: [] } }
4949

5050
fn new_filemap_w_substr(filename: filename, substr: file_substr,
51-
src: @str,
51+
-src: ~str,
5252
start_pos_ch: uint, start_pos_byte: uint)
5353
-> filemap {
5454
ret @{name: filename, substr: substr, src: src,
5555
start_pos: {ch: start_pos_ch, byte: start_pos_byte},
5656
mut lines: [{ch: start_pos_ch, byte: start_pos_byte}]};
5757
}
5858

59-
fn new_filemap(filename: filename, src: @str,
59+
fn new_filemap(filename: filename, -src: ~str,
6060
start_pos_ch: uint, start_pos_byte: uint)
6161
-> filemap {
6262
ret new_filemap_w_substr(filename, fss_none, src,

src/librustsyntax/ext/expand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ fn expand_crate(parse_sess: parse::parse_sess,
121121
with *afp};
122122
let f = make_fold(f_pre);
123123
let cm = parse_expr_from_source_str("<core-macros>",
124-
@core_macros(),
124+
~core_macros(),
125125
cfg,
126126
parse_sess);
127127

src/librustsyntax/parse.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,22 @@ fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg,
7373
ret r;
7474
}
7575

76-
fn parse_crate_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
77-
sess: parse_sess) -> @ast::crate {
76+
fn parse_crate_from_source_str(name: str, source: ~str,
77+
cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate {
78+
// FIXME: Get rid of copy once there's a snapshot
7879
let p = new_parser_from_source_str(
79-
sess, cfg, name, codemap::fss_none, source);
80+
sess, cfg, name, codemap::fss_none, @(*source));
8081
let r = parser::parse_crate_mod(p, cfg);
8182
sess.chpos = p.reader.chpos;
8283
sess.byte_pos = sess.byte_pos + p.reader.pos;
8384
ret r;
8485
}
8586

86-
fn parse_expr_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
87-
sess: parse_sess) -> @ast::expr {
87+
fn parse_expr_from_source_str(name: str, source: ~str,
88+
cfg: ast::crate_cfg, sess: parse_sess) -> @ast::expr {
89+
// FIXME: Get rid of copy once there's a snapshot
8890
let p = new_parser_from_source_str(
89-
sess, cfg, name, codemap::fss_none, source);
91+
sess, cfg, name, codemap::fss_none, @(*source));
9092
let r = parser::parse_expr(p);
9193
sess.chpos = p.reader.chpos;
9294
sess.byte_pos = sess.byte_pos + p.reader.pos;
@@ -134,12 +136,15 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
134136
restricted_keywords: token::restricted_keyword_table()}
135137
}
136138

139+
/* FIXME: still taking an @ b/c #ast using this.
140+
Fix when there's a snapshot */
137141
fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
138142
name: str, ss: codemap::file_substr,
139143
source: @str) -> parser {
140144
let ftype = parser::SOURCE_FILE;
141145
let filemap = codemap::new_filemap_w_substr
142-
(name, ss, source, sess.chpos, sess.byte_pos);
146+
// FIXME: remove copy once there's a new snap
147+
(name, ss, ~(*source), sess.chpos, sess.byte_pos);
143148
sess.cm.files += [filemap];
144149
let itr = @interner::mk(str::hash, str::eq);
145150
let rdr = lexer::new_reader(sess.span_diagnostic,
@@ -148,12 +153,10 @@ fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
148153
}
149154

150155
fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str,
151-
ftype: parser::file_type) ->
152-
parser {
153-
let src = alt io::read_whole_file_str(path) {
156+
ftype: parser::file_type) -> parser {
157+
let src = alt io::read_whole_file_ref(path) {
154158
result::ok(src) {
155-
// FIXME: This copy is unfortunate
156-
@src
159+
src
157160
}
158161
result::err(e) {
159162
sess.span_diagnostic.handler().fatal(e)

src/librustsyntax/parse/comments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
154154
path: str,
155155
srdr: io::reader) ->
156156
{cmnts: [cmnt], lits: [lit]} {
157-
let src = @str::from_bytes(srdr.read_whole_stream());
157+
let src = ~str::from_bytes(srdr.read_whole_stream());
158158
let itr = @interner::mk::<str>(str::hash, str::eq);
159159
let rdr = new_reader(span_diagnostic,
160160
codemap::new_filemap(path, src, 0u, 0u), itr);

src/librustsyntax/parse/lexer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export reader, new_reader, next_token, is_whitespace;
66

77
type reader = @{
88
span_diagnostic: diagnostic::span_handler,
9-
src: @str,
9+
src: ~str,
1010
mut col: uint,
1111
mut pos: uint,
1212
mut curr: char,

src/librustsyntax/parse/token.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn to_str(in: interner<str>, t: token) -> str {
124124

125125
/* Literals */
126126
LIT_INT(c, ast::ty_char) {
127-
// FIXME: escape.
127+
// FIXME: escape. (#2306)
128128
let mut tmp = "'";
129129
str::push_char(tmp, c as char);
130130
str::push_char(tmp, '\'');
@@ -140,7 +140,7 @@ fn to_str(in: interner<str>, t: token) -> str {
140140
ret interner::get::<str>(in, s) +
141141
ast_util::float_ty_to_str(t);
142142
}
143-
LIT_STR(s) { // FIXME: escape.
143+
LIT_STR(s) { // FIXME: escape. (#2306)
144144
ret "\"" + interner::get::<str>(in, s) + "\"";
145145
}
146146

src/rustc/driver/driver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fn parse_input(sess: session, cfg: ast::crate_cfg, input: str)
7878
if !input_is_stdin(input) {
7979
parse::parse_crate_from_file(input, cfg, sess.parse_sess)
8080
} else {
81-
let src = @str::from_bytes(io::stdin().read_whole_stream());
81+
let src = ~str::from_bytes(io::stdin().read_whole_stream());
8282
parse::parse_crate_from_source_str(input, src, cfg, sess.parse_sess)
8383
}
8484
}

src/rustdoc/astsrv.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ type ctxt = {
3636

3737
type srv_owner<T> = fn(srv: srv) -> T;
3838
type ctxt_handler<T> = fn~(ctxt: ctxt) -> T;
39-
type parser = fn~(session::session, str) -> @ast::crate;
39+
/* The idea is that a parser takes an input of type U,
40+
which lets us have parsers that either take unboxed or
41+
boxed strings. */
42+
type parser<U> = fn~(session::session, U) -> @ast::crate;
4043

4144
enum msg {
4245
handle_request(fn~(ctxt)),
@@ -48,14 +51,14 @@ enum srv = {
4851
};
4952

5053
fn from_str<T>(source: str, owner: srv_owner<T>) -> T {
51-
run(owner, source, parse::from_str_sess)
54+
run(owner, ~source, parse::from_str_sess)
5255
}
5356

5457
fn from_file<T>(file: str, owner: srv_owner<T>) -> T {
5558
run(owner, file, parse::from_file_sess)
5659
}
5760

58-
fn run<T>(owner: srv_owner<T>, source: str, parse: parser) -> T {
61+
fn run<T, U: send>(owner: srv_owner<T>, +source: U, parse: parser<U>) -> T {
5962

6063
let srv_ = srv({
6164
ch: task::spawn_listener {|po|
@@ -68,7 +71,7 @@ fn run<T>(owner: srv_owner<T>, source: str, parse: parser) -> T {
6871
ret res;
6972
}
7073

71-
fn act(po: comm::port<msg>, source: str, parse: parser) {
74+
fn act<U>(po: comm::port<msg>, source: U, parse: parser<U>) {
7275
let (sess, ignore_errors) = build_session();
7376

7477
let ctxt = build_ctxt(

src/rustdoc/extract.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ fn should_extract_tys() {
289289
mod test {
290290

291291
fn mk_doc(source: str) -> doc::doc {
292-
let ast = parse::from_str(source);
292+
let ast = parse::from_str(~source);
293293
extract(ast, "")
294294
}
295295

@@ -349,7 +349,7 @@ mod test {
349349

350350
#[test]
351351
fn extract_should_use_default_crate_name() {
352-
let source = "";
352+
let source = ~"";
353353
let ast = parse::from_str(source);
354354
let doc = extract(ast, "burp");
355355
assert doc.cratemod().name() == "burp";

src/rustdoc/fold.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ fn default_seq_fold_type<T>(
354354
#[test]
355355
fn default_fold_should_produce_same_doc() {
356356
let source = "mod a { fn b() { } mod c { fn d() { } } }";
357-
let ast = parse::from_str(source);
357+
let ast = parse::from_str(~source);
358358
let doc = extract::extract(ast, "");
359359
let fld = default_seq_fold(());
360360
let folded = fld.fold_doc(fld, doc);
@@ -364,7 +364,7 @@ fn default_fold_should_produce_same_doc() {
364364
#[test]
365365
fn default_fold_should_produce_same_consts() {
366366
let source = "const a: int = 0;";
367-
let ast = parse::from_str(source);
367+
let ast = parse::from_str(~source);
368368
let doc = extract::extract(ast, "");
369369
let fld = default_seq_fold(());
370370
let folded = fld.fold_doc(fld, doc);
@@ -374,7 +374,7 @@ fn default_fold_should_produce_same_consts() {
374374
#[test]
375375
fn default_fold_should_produce_same_enums() {
376376
let source = "enum a { b }";
377-
let ast = parse::from_str(source);
377+
let ast = parse::from_str(~source);
378378
let doc = extract::extract(ast, "");
379379
let fld = default_seq_fold(());
380380
let folded = fld.fold_doc(fld, doc);
@@ -384,7 +384,7 @@ fn default_fold_should_produce_same_enums() {
384384
#[test]
385385
fn default_parallel_fold_should_produce_same_doc() {
386386
let source = "mod a { fn b() { } mod c { fn d() { } } }";
387-
let ast = parse::from_str(source);
387+
let ast = parse::from_str(~source);
388388
let doc = extract::extract(ast, "");
389389
let fld = default_par_fold(());
390390
let folded = fld.fold_doc(fld, doc);

src/rustdoc/parse.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ fn from_file(file: str) -> @ast::crate {
2727
file, [], new_parse_sess())
2828
}
2929

30-
fn from_str(source: str) -> @ast::crate {
30+
fn from_str(source: ~str) -> @ast::crate {
3131
parse::parse_crate_from_source_str(
32-
"-", @source, [], new_parse_sess())
32+
"-", source, [], new_parse_sess())
3333
}
3434

35-
fn from_file_sess(sess: session::session, file: str) -> @ast::crate {
35+
fn from_file_sess(sess: session::session, &&file: str) -> @ast::crate {
3636
parse::parse_crate_from_file(file, cfg(sess), sess.parse_sess)
3737
}
3838

39-
fn from_str_sess(sess: session::session, source: str) -> @ast::crate {
39+
fn from_str_sess(sess: session::session, &&source: ~str) -> @ast::crate {
4040
parse::parse_crate_from_source_str(
41-
"-", @source, cfg(sess), sess.parse_sess)
41+
"-", source, cfg(sess), sess.parse_sess)
4242
}
4343

4444
fn cfg(sess: session::session) -> ast::crate_cfg {

0 commit comments

Comments
 (0)