Skip to content

Commit d89074c

Browse files
committed
std: Remove lots of allocations from log settings
Most of these are unnecessary because we're only looking at static strings. This also moves to Vec in a few places instead of ~[T]. This didn't end up getting much of a code size win (update_log_settings is the third largest function in the executables I'm looking at), but this seems like a generally nice improvement regardless.
1 parent d5aa795 commit d89074c

File tree

2 files changed

+96
-102
lines changed

2 files changed

+96
-102
lines changed

src/libstd/rt/crate_map.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fn version(crate_map: &CrateMap) -> i32 {
123123

124124
fn do_iter_crate_map<'a>(
125125
crate_map: &'a CrateMap<'a>,
126-
f: |&ModEntry|,
126+
f: |&'a ModEntry<'a>|,
127127
visited: &mut ~[*CrateMap<'a>]) {
128128
let raw = crate_map as *CrateMap<'a>;
129129
if visited.bsearch(|a| (*a as uint).cmp(&(raw as uint))).is_some() {
@@ -149,7 +149,7 @@ fn do_iter_crate_map<'a>(
149149
}
150150

151151
/// Iterates recursively over `crate_map` and all child crate maps
152-
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&ModEntry|) {
152+
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&'a ModEntry<'a>|) {
153153
let mut v = ~[];
154154
do_iter_crate_map(crate_map, f, &mut v);
155155
}

src/libstd/rt/logging.rs

Lines changed: 94 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ use from_str::from_str;
1313
use iter::Iterator;
1414
use libc::exit;
1515
use option::{Some, None, Option};
16+
use os;
1617
use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
17-
use str::StrSlice;
18+
use str::{Str, StrSlice};
1819
use vec::{ImmutableVector, MutableTotalOrdVector, OwnedVector};
19-
#[cfg(test)] use cast::transmute;
20+
use vec_ng::Vec;
2021

21-
struct LogDirective {
22-
name: Option<~str>,
22+
struct LogDirective<'a> {
23+
name: Option<&'a str>,
2324
level: u32
2425
}
2526

@@ -58,36 +59,39 @@ fn parse_log_level(level: &str) -> Option<u32> {
5859
/// and return a vector with log directives.
5960
/// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in std::).
6061
/// Also supports string log levels of error, warn, info, and debug
61-
fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
62-
let mut dirs = ~[];
62+
fn parse_logging_spec<'a>(spec: &'a str) -> Vec<LogDirective<'a>> {
63+
let mut dirs = Vec::new();
6364
for s in spec.split(',') {
64-
let parts: ~[&str] = s.split('=').collect();
65-
let mut log_level;
66-
let mut name = Some(parts[0].to_owned());
67-
match parts.len() {
68-
1 => {
65+
if s.len() == 0 { continue }
66+
let mut parts = s.split('=');
67+
let log_level;
68+
let name;
69+
match (parts.next(), parts.next(), parts.next()) {
70+
(Some(part0), None, None) => {
6971
//if the single argument is a log-level string or number,
7072
//treat that as a global fallback
71-
let possible_log_level = parse_log_level(parts[0]);
73+
let possible_log_level = parse_log_level(part0);
7274
match possible_log_level {
7375
Some(num) => {
7476
name = None;
7577
log_level = num;
7678
},
77-
_ => {
78-
log_level = MAX_LOG_LEVEL
79+
None => {
80+
log_level = MAX_LOG_LEVEL;
81+
name = Some(part0);
7982
}
8083
}
8184
}
82-
2 => {
83-
let possible_log_level = parse_log_level(parts[1]);
85+
(Some(part0), Some(part1), None) => {
86+
let possible_log_level = parse_log_level(part1);
8487
match possible_log_level {
8588
Some(num) => {
89+
name = Some(part0);
8690
log_level = num;
8791
},
8892
_ => {
8993
rterrln!("warning: invalid logging spec '{}', \
90-
ignoring it", parts[1]);
94+
ignoring it", part1);
9195
continue
9296
}
9397
}
@@ -98,8 +102,7 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
98102
continue
99103
}
100104
}
101-
let dir = LogDirective {name: name, level: log_level};
102-
dirs.push(dir);
105+
dirs.push(LogDirective { name: name, level: log_level });
103106
}
104107
return dirs;
105108
}
@@ -134,27 +137,24 @@ fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
134137

135138
/// Set log level for every entry in crate_map according to the sepecification
136139
/// in settings
137-
fn update_log_settings(crate_map: &CrateMap, settings: ~str) {
138-
let mut dirs = ~[];
139-
if settings.len() > 0 {
140-
if settings == ~"::help" || settings == ~"?" {
141-
rterrln!("\nCrate log map:\n");
140+
fn update_log_settings(crate_map: &CrateMap, settings: &str) {
141+
if settings == "::help" || settings == "?" {
142+
rterrln!("\nCrate log map:\n");
142143

143-
let mut entries = ~[];
144-
iter_crate_map(crate_map, |entry| entries.push(entry.name.to_owned()));
145-
entries.sort();
144+
let mut entries = Vec::new();
145+
iter_crate_map(crate_map, |entry| entries.push(entry.name));
146+
entries.as_mut_slice().sort();
146147

147-
for name in entries.iter() {
148-
rterrln!(" {}", *name);
149-
}
150-
unsafe { exit(1); }
148+
for name in entries.iter() {
149+
rterrln!(" {}", *name);
151150
}
152-
dirs = parse_logging_spec(settings);
151+
unsafe { exit(1); }
153152
}
153+
let dirs = parse_logging_spec(settings);
154154

155155
let mut n_matches: u32 = 0;
156156
iter_crate_map(crate_map, |entry| {
157-
let m = update_entry(dirs, entry);
157+
let m = update_entry(dirs.as_slice(), entry);
158158
n_matches += m;
159159
});
160160

@@ -169,18 +169,12 @@ fn update_log_settings(crate_map: &CrateMap, settings: ~str) {
169169
/// Configure logging by traversing the crate map and setting the
170170
/// per-module global logging flags based on the logging spec
171171
pub fn init() {
172-
use os;
173-
174172
let log_spec = os::getenv("RUST_LOG");
175173
match get_crate_map() {
176174
Some(crate_map) => {
177175
match log_spec {
178-
Some(spec) => {
179-
update_log_settings(crate_map, spec);
180-
}
181-
None => {
182-
update_log_settings(crate_map, ~"");
183-
}
176+
Some(spec) => update_log_settings(crate_map, spec.as_slice()),
177+
None => update_log_settings(crate_map, ""),
184178
}
185179
},
186180
_ => {
@@ -197,124 +191,124 @@ pub fn init() {
197191
// Tests for parse_logging_spec()
198192
#[test]
199193
fn parse_logging_spec_valid() {
200-
let dirs = parse_logging_spec(~"crate1::mod1=1,crate1::mod2,crate2=4");
194+
let dirs = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4");
195+
let dirs = dirs.as_slice();
201196
assert_eq!(dirs.len(), 3);
202-
assert!(dirs[0].name == Some(~"crate1::mod1"));
197+
assert_eq!(dirs[0].name, Some("crate1::mod1"));
203198
assert_eq!(dirs[0].level, 1);
204199

205-
assert!(dirs[1].name == Some(~"crate1::mod2"));
200+
assert_eq!(dirs[1].name, Some("crate1::mod2"));
206201
assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
207202

208-
assert!(dirs[2].name == Some(~"crate2"));
203+
assert_eq!(dirs[2].name, Some("crate2"));
209204
assert_eq!(dirs[2].level, 4);
210205
}
211206

212207
#[test]
213208
fn parse_logging_spec_invalid_crate() {
214209
// test parse_logging_spec with multiple = in specification
215-
let dirs = parse_logging_spec(~"crate1::mod1=1=2,crate2=4");
210+
let dirs = parse_logging_spec("crate1::mod1=1=2,crate2=4");
211+
let dirs = dirs.as_slice();
216212
assert_eq!(dirs.len(), 1);
217-
assert!(dirs[0].name == Some(~"crate2"));
213+
assert_eq!(dirs[0].name, Some("crate2"));
218214
assert_eq!(dirs[0].level, 4);
219215
}
220216

221217
#[test]
222218
fn parse_logging_spec_invalid_log_level() {
223219
// test parse_logging_spec with 'noNumber' as log level
224-
let dirs = parse_logging_spec(~"crate1::mod1=noNumber,crate2=4");
220+
let dirs = parse_logging_spec("crate1::mod1=noNumber,crate2=4");
221+
let dirs = dirs.as_slice();
225222
assert_eq!(dirs.len(), 1);
226-
assert!(dirs[0].name == Some(~"crate2"));
223+
assert_eq!(dirs[0].name, Some("crate2"));
227224
assert_eq!(dirs[0].level, 4);
228225
}
229226

230227
#[test]
231228
fn parse_logging_spec_string_log_level() {
232229
// test parse_logging_spec with 'warn' as log level
233-
let dirs = parse_logging_spec(~"crate1::mod1=wrong,crate2=warn");
230+
let dirs = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
231+
let dirs = dirs.as_slice();
234232
assert_eq!(dirs.len(), 1);
235-
assert!(dirs[0].name == Some(~"crate2"));
233+
assert_eq!(dirs[0].name, Some("crate2"));
236234
assert_eq!(dirs[0].level, 2);
237235
}
238236

239237
#[test]
240238
fn parse_logging_spec_global() {
241239
// test parse_logging_spec with no crate
242-
let dirs = parse_logging_spec(~"warn,crate2=4");
240+
let dirs = parse_logging_spec("warn,crate2=4");
241+
let dirs = dirs.as_slice();
243242
assert_eq!(dirs.len(), 2);
244-
assert!(dirs[0].name == None);
243+
assert_eq!(dirs[0].name, None);
245244
assert_eq!(dirs[0].level, 2);
246-
assert!(dirs[1].name == Some(~"crate2"));
245+
assert_eq!(dirs[1].name, Some("crate2"));
247246
assert_eq!(dirs[1].level, 4);
248247
}
249248

250249
// Tests for update_entry
251250
#[test]
252251
fn update_entry_match_full_path() {
253-
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
254-
LogDirective {name: Some(~"crate2"), level: 3}];
255-
let level = &mut 0;
256-
unsafe {
257-
let entry= &ModEntry {name:"crate1::mod1", log_level: level};
258-
let m = update_entry(dirs, transmute(entry));
259-
assert!(*entry.log_level == 2);
260-
assert!(m == 1);
252+
let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
253+
LogDirective { name: Some("crate2"), level: 3 }];
254+
let mut level = 0;
255+
{
256+
let entry = &ModEntry { name: "crate1::mod1", log_level: &mut level };
257+
assert_eq!(update_entry(dirs, entry), 1);
261258
}
259+
assert_eq!(level, 2);
262260
}
263261

264262
#[test]
265263
fn update_entry_no_match() {
266-
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
267-
LogDirective {name: Some(~"crate2"), level: 3}];
268-
let level = &mut 0;
269-
unsafe {
270-
let entry= &ModEntry {name: "crate3::mod1", log_level: level};
271-
let m = update_entry(dirs, transmute(entry));
272-
assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
273-
assert!(m == 0);
264+
let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
265+
LogDirective { name: Some("crate2"), level: 3 }];
266+
let mut level = 0;
267+
{
268+
let entry = &ModEntry { name: "crate3::mod1", log_level: &mut level };
269+
assert_eq!(update_entry(dirs, entry), 0);
274270
}
271+
assert_eq!(level, DEFAULT_LOG_LEVEL);
275272
}
276273

277274
#[test]
278275
fn update_entry_match_beginning() {
279-
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
280-
LogDirective {name: Some(~"crate2"), level: 3}];
281-
let level = &mut 0;
282-
unsafe {
283-
let entry= &ModEntry {name: "crate2::mod1", log_level: level};
284-
let m = update_entry(dirs, transmute(entry));
285-
assert!(*entry.log_level == 3);
286-
assert!(m == 1);
276+
let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
277+
LogDirective { name: Some("crate2"), level: 3 }];
278+
let mut level = 0;
279+
{
280+
let entry= &ModEntry {name: "crate2::mod1", log_level: &mut level};
281+
assert_eq!(update_entry(dirs, entry), 1);
287282
}
283+
assert_eq!(level, 3);
288284
}
289285

290286
#[test]
291287
fn update_entry_match_beginning_longest_match() {
292-
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
293-
LogDirective {name: Some(~"crate2"), level: 3},
294-
LogDirective {name: Some(~"crate2::mod"), level: 4}];
295-
let level = &mut 0;
296-
unsafe {
297-
let entry = &ModEntry {name: "crate2::mod1", log_level: level};
298-
let m = update_entry(dirs, transmute(entry));
299-
assert!(*entry.log_level == 4);
300-
assert!(m == 1);
288+
let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
289+
LogDirective { name: Some("crate2"), level: 3 },
290+
LogDirective { name: Some("crate2::mod"), level: 4 }];
291+
let mut level = 0;
292+
{
293+
let entry = &ModEntry { name: "crate2::mod1", log_level: &mut level };
294+
assert_eq!(update_entry(dirs, entry), 1);
301295
}
296+
assert_eq!(level, 4);
302297
}
303298

304299
#[test]
305300
fn update_entry_match_default() {
306-
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
307-
LogDirective {name: None, level: 3}
308-
];
309-
let level = &mut 0;
310-
unsafe {
311-
let entry= &ModEntry {name: "crate1::mod1", log_level: level};
312-
let m = update_entry(dirs, transmute(entry));
313-
assert!(*entry.log_level == 2);
314-
assert!(m == 1);
315-
let entry= &ModEntry {name: "crate2::mod2", log_level: level};
316-
let m = update_entry(dirs, transmute(entry));
317-
assert!(*entry.log_level == 3);
318-
assert!(m == 1);
301+
let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
302+
LogDirective { name: None, level: 3 }];
303+
let mut level = 0;
304+
{
305+
let entry = &ModEntry { name: "crate1::mod1", log_level: &mut level };
306+
assert_eq!(update_entry(dirs, entry), 1);
307+
}
308+
assert_eq!(level, 2);
309+
{
310+
let entry = &ModEntry { name: "crate2::mod2", log_level: &mut level };
311+
assert_eq!(update_entry(dirs, entry), 1);
319312
}
313+
assert_eq!(level, 3);
320314
}

0 commit comments

Comments
 (0)