Skip to content

Commit bdea343

Browse files
committed
rustc: Use the path index. Speeds up compilation a lot.
1 parent fffc5d3 commit bdea343

File tree

1 file changed

+48
-91
lines changed

1 file changed

+48
-91
lines changed

src/comp/front/creader.rs

Lines changed: 48 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type env = @rec(
3535

3636
tag resolve_result {
3737
rr_ok(ast.def_id);
38-
rr_not_found(vec[ast.ident], ast.ident);
38+
rr_not_found(ast.ident);
3939
}
4040

4141
// Type decoding
@@ -253,94 +253,15 @@ fn parse_def_id(vec[u8] buf) -> ast.def_id {
253253
ret tup(crate_num, def_num);
254254
}
255255

256-
// Given a path and serialized crate metadata, returns the ID of the
257-
// definition the path refers to.
258-
impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result {
259-
impure fn resolve_path_inner(vec[ast.ident] path, &ebml.reader ebml_r)
260-
-> resolve_result {
261-
auto i = 0u;
262-
auto len = _vec.len[ast.ident](path);
263-
while (i < len) {
264-
auto name = path.(i);
265-
auto last = i == len - 1u;
266-
267-
// Search this level for the identifier.
268-
auto found = false;
269-
while (ebml.bytes_left(ebml_r) > 0u && !found) {
270-
auto ebml_tag = ebml.peek(ebml_r);
271-
if ((ebml_tag.id == metadata.tag_paths_data_item) ||
272-
(ebml_tag.id == metadata.tag_paths_data_mod)) {
273-
ebml.move_to_first_child(ebml_r);
274-
auto did_opt = none[ast.def_id];
275-
auto name_opt = none[ast.ident];
276-
while (ebml.bytes_left(ebml_r) > 0u) {
277-
auto inner_tag = ebml.peek(ebml_r);
278-
if (inner_tag.id == metadata.tag_paths_data_name) {
279-
ebml.move_to_first_child(ebml_r);
280-
auto name_data = ebml.read_data(ebml_r);
281-
ebml.move_to_parent(ebml_r);
282-
auto nm = _str.unsafe_from_bytes(name_data);
283-
name_opt = some[ast.ident](nm);
284-
} else if (inner_tag.id == metadata.tag_def_id) {
285-
ebml.move_to_first_child(ebml_r);
286-
auto did_data = ebml.read_data(ebml_r);
287-
ebml.move_to_parent(ebml_r);
288-
auto did = parse_def_id(did_data);
289-
did_opt = some[ast.def_id](did);
290-
}
291-
ebml.move_to_next_sibling(ebml_r);
292-
}
293-
ebml.move_to_parent(ebml_r);
294-
295-
if (_str.eq(option.get[ast.ident](name_opt), name)) {
296-
// Matched!
297-
if (last) {
298-
ret rr_ok(option.get[ast.def_id](did_opt));
299-
}
300-
301-
// Move to the module/item we found for the next
302-
// iteration of the loop...
303-
ebml.move_to_first_child(ebml_r);
304-
found = true;
305-
}
306-
}
307-
ebml.move_to_next_sibling(ebml_r);
308-
}
309-
310-
if (!found) {
311-
auto prev = _vec.slice[ast.ident](path, 0u, i);
312-
ret rr_not_found(prev, name);
313-
}
314-
315-
i += 1u;
316-
}
317-
318-
fail; // not reached
319-
}
320-
321-
auto io_r = io.new_reader_(io.new_byte_buf_reader(data));
322-
auto ebml_r = ebml.create_reader(io_r);
323-
while (ebml.bytes_left(ebml_r) > 0u) {
324-
auto ebml_tag = ebml.peek(ebml_r);
325-
if (ebml_tag.id == metadata.tag_paths) {
326-
ebml.move_to_first_child(ebml_r);
327-
ret resolve_path_inner(path, ebml_r);
328-
}
329-
ebml.move_to_next_sibling(ebml_r);
330-
}
331-
332-
log "resolve_path(): no names in file";
333-
fail;
334-
}
335-
336-
impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
337-
ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items);
256+
impure fn lookup_hash_entry(&ebml.reader ebml_r,
257+
impure fn(&ebml.reader) -> bool eq_fn,
258+
uint hash) -> bool {
338259
ebml.move_to_child_with_id(ebml_r, metadata.tag_index);
339260
ebml.move_to_child_with_id(ebml_r, metadata.tag_index_table);
340261
ebml.move_to_first_child(ebml_r);
341262

342263
// Move to the bucket.
343-
auto bucket_index = metadata.hash_def_num(item_id) % 256u;
264+
auto bucket_index = hash % 256u;
344265
auto buf_reader = ebml_r.reader.get_buf_reader();
345266
buf_reader.seek((bucket_index * 4u) as int, io.seek_cur);
346267
auto bucket_pos = ebml_r.reader.read_be_uint(4u);
@@ -353,21 +274,57 @@ impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
353274
if (ebml.peek(ebml_r).id == metadata.tag_index_buckets_bucket_elt) {
354275
ebml.move_to_first_child(ebml_r);
355276
auto pos = ebml_r.reader.read_be_uint(4u);
356-
auto this_item_id = ebml_r.reader.read_be_uint(4u) as int;
357-
if (item_id == this_item_id) {
277+
if (eq_fn(ebml_r)) {
358278
// Found the item. Move to its data and return.
359279
ebml.reset_reader(ebml_r, pos);
360-
check (ebml.peek(ebml_r).id == metadata.tag_items_data_item);
361280
ebml.move_to_first_child(ebml_r);
362-
ret;
281+
ret true;
363282
}
364283
ebml.move_to_parent(ebml_r);
365284
}
366285
ebml.move_to_next_sibling(ebml_r);
367286
}
368287

369-
log #fmt("item %d not found in bucket at pos %u", item_id, bucket_pos);
370-
fail;
288+
ret false;
289+
}
290+
291+
// Given a path and serialized crate metadata, returns the ID of the
292+
// definition the path refers to.
293+
impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result {
294+
impure fn eq_item(&ebml.reader ebml_r, str s) -> bool {
295+
auto this_str = _str.unsafe_from_bytes(ebml.read_data(ebml_r));
296+
ret _str.eq(this_str, s);
297+
}
298+
299+
auto s = _str.connect(path, ".");
300+
301+
auto io_r = io.new_reader_(io.new_byte_buf_reader(data));
302+
auto ebml_r = ebml.create_reader(io_r);
303+
ebml.move_to_sibling_with_id(ebml_r, metadata.tag_paths);
304+
305+
auto eqer = bind eq_item(_, s);
306+
auto hash = metadata.hash_path(s);
307+
if (!lookup_hash_entry(ebml_r, eqer, hash)) {
308+
ret rr_not_found(s);
309+
}
310+
311+
ebml.move_to_sibling_with_id(ebml_r, metadata.tag_def_id);
312+
ebml.move_to_first_child(ebml_r);
313+
auto did_data = ebml.read_data(ebml_r);
314+
ebml.move_to_parent(ebml_r);
315+
auto did = parse_def_id(did_data);
316+
ret rr_ok(did);
317+
}
318+
319+
impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
320+
impure fn eq_item(&ebml.reader ebml_r, int item_id) -> bool {
321+
ret (ebml_r.reader.read_be_uint(4u) as int) == item_id;
322+
}
323+
324+
auto eqer = bind eq_item(_, item_id);
325+
auto hash = metadata.hash_def_num(item_id);
326+
ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items);
327+
lookup_hash_entry(ebml_r, eqer, hash);
371328
}
372329

373330
// Looks up an item in the given metadata and returns an EBML reader pointing
@@ -573,7 +530,7 @@ fn lookup_def(session.session sess, int cnum, vec[ast.ident] path)
573530
auto did;
574531
alt (resolve_path(path, data)) {
575532
case (rr_ok(?di)) { did = di; }
576-
case (rr_not_found(?prev, ?name)) {
533+
case (rr_not_found(?name)) {
577534
ret none[ast.def];
578535
}
579536
}

0 commit comments

Comments
 (0)