diff options
| author | Patrick Walton <[email protected]> | 2011-03-31 18:28:32 -0700 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-03-31 18:28:59 -0700 |
| commit | bdea34387945aee7d18981a8c59f5b04beb560fc (patch) | |
| tree | faaa284bb575ade6e1f0f1b1fe415be89a088fc4 | |
| parent | rustc: Write out a path index as well (diff) | |
| download | rust-bdea34387945aee7d18981a8c59f5b04beb560fc.tar.xz rust-bdea34387945aee7d18981a8c59f5b04beb560fc.zip | |
rustc: Use the path index. Speeds up compilation a lot.
| -rw-r--r-- | src/comp/front/creader.rs | 139 |
1 files changed, 48 insertions, 91 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index f9ef70ca..22c38c31 100644 --- a/src/comp/front/creader.rs +++ b/src/comp/front/creader.rs @@ -35,7 +35,7 @@ type env = @rec( tag resolve_result { rr_ok(ast.def_id); - rr_not_found(vec[ast.ident], ast.ident); + rr_not_found(ast.ident); } // Type decoding @@ -253,94 +253,15 @@ fn parse_def_id(vec[u8] buf) -> ast.def_id { ret tup(crate_num, def_num); } -// Given a path and serialized crate metadata, returns the ID of the -// definition the path refers to. -impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result { - impure fn resolve_path_inner(vec[ast.ident] path, &ebml.reader ebml_r) - -> resolve_result { - auto i = 0u; - auto len = _vec.len[ast.ident](path); - while (i < len) { - auto name = path.(i); - auto last = i == len - 1u; - - // Search this level for the identifier. - auto found = false; - while (ebml.bytes_left(ebml_r) > 0u && !found) { - auto ebml_tag = ebml.peek(ebml_r); - if ((ebml_tag.id == metadata.tag_paths_data_item) || - (ebml_tag.id == metadata.tag_paths_data_mod)) { - ebml.move_to_first_child(ebml_r); - auto did_opt = none[ast.def_id]; - auto name_opt = none[ast.ident]; - while (ebml.bytes_left(ebml_r) > 0u) { - auto inner_tag = ebml.peek(ebml_r); - if (inner_tag.id == metadata.tag_paths_data_name) { - ebml.move_to_first_child(ebml_r); - auto name_data = ebml.read_data(ebml_r); - ebml.move_to_parent(ebml_r); - auto nm = _str.unsafe_from_bytes(name_data); - name_opt = some[ast.ident](nm); - } else if (inner_tag.id == metadata.tag_def_id) { - ebml.move_to_first_child(ebml_r); - auto did_data = ebml.read_data(ebml_r); - ebml.move_to_parent(ebml_r); - auto did = parse_def_id(did_data); - did_opt = some[ast.def_id](did); - } - ebml.move_to_next_sibling(ebml_r); - } - ebml.move_to_parent(ebml_r); - - if (_str.eq(option.get[ast.ident](name_opt), name)) { - // Matched! - if (last) { - ret rr_ok(option.get[ast.def_id](did_opt)); - } - - // Move to the module/item we found for the next - // iteration of the loop... - ebml.move_to_first_child(ebml_r); - found = true; - } - } - ebml.move_to_next_sibling(ebml_r); - } - - if (!found) { - auto prev = _vec.slice[ast.ident](path, 0u, i); - ret rr_not_found(prev, name); - } - - i += 1u; - } - - fail; // not reached - } - - auto io_r = io.new_reader_(io.new_byte_buf_reader(data)); - auto ebml_r = ebml.create_reader(io_r); - while (ebml.bytes_left(ebml_r) > 0u) { - auto ebml_tag = ebml.peek(ebml_r); - if (ebml_tag.id == metadata.tag_paths) { - ebml.move_to_first_child(ebml_r); - ret resolve_path_inner(path, ebml_r); - } - ebml.move_to_next_sibling(ebml_r); - } - - log "resolve_path(): no names in file"; - fail; -} - -impure fn move_to_item(&ebml.reader ebml_r, int item_id) { - ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items); +impure fn lookup_hash_entry(&ebml.reader ebml_r, + impure fn(&ebml.reader) -> bool eq_fn, + uint hash) -> bool { ebml.move_to_child_with_id(ebml_r, metadata.tag_index); ebml.move_to_child_with_id(ebml_r, metadata.tag_index_table); ebml.move_to_first_child(ebml_r); // Move to the bucket. - auto bucket_index = metadata.hash_def_num(item_id) % 256u; + auto bucket_index = hash % 256u; auto buf_reader = ebml_r.reader.get_buf_reader(); buf_reader.seek((bucket_index * 4u) as int, io.seek_cur); 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) { if (ebml.peek(ebml_r).id == metadata.tag_index_buckets_bucket_elt) { ebml.move_to_first_child(ebml_r); auto pos = ebml_r.reader.read_be_uint(4u); - auto this_item_id = ebml_r.reader.read_be_uint(4u) as int; - if (item_id == this_item_id) { + if (eq_fn(ebml_r)) { // Found the item. Move to its data and return. ebml.reset_reader(ebml_r, pos); - check (ebml.peek(ebml_r).id == metadata.tag_items_data_item); ebml.move_to_first_child(ebml_r); - ret; + ret true; } ebml.move_to_parent(ebml_r); } ebml.move_to_next_sibling(ebml_r); } - log #fmt("item %d not found in bucket at pos %u", item_id, bucket_pos); - fail; + ret false; +} + +// Given a path and serialized crate metadata, returns the ID of the +// definition the path refers to. +impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result { + impure fn eq_item(&ebml.reader ebml_r, str s) -> bool { + auto this_str = _str.unsafe_from_bytes(ebml.read_data(ebml_r)); + ret _str.eq(this_str, s); + } + + auto s = _str.connect(path, "."); + + auto io_r = io.new_reader_(io.new_byte_buf_reader(data)); + auto ebml_r = ebml.create_reader(io_r); + ebml.move_to_sibling_with_id(ebml_r, metadata.tag_paths); + + auto eqer = bind eq_item(_, s); + auto hash = metadata.hash_path(s); + if (!lookup_hash_entry(ebml_r, eqer, hash)) { + ret rr_not_found(s); + } + + ebml.move_to_sibling_with_id(ebml_r, metadata.tag_def_id); + ebml.move_to_first_child(ebml_r); + auto did_data = ebml.read_data(ebml_r); + ebml.move_to_parent(ebml_r); + auto did = parse_def_id(did_data); + ret rr_ok(did); +} + +impure fn move_to_item(&ebml.reader ebml_r, int item_id) { + impure fn eq_item(&ebml.reader ebml_r, int item_id) -> bool { + ret (ebml_r.reader.read_be_uint(4u) as int) == item_id; + } + + auto eqer = bind eq_item(_, item_id); + auto hash = metadata.hash_def_num(item_id); + ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items); + lookup_hash_entry(ebml_r, eqer, hash); } // 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) auto did; alt (resolve_path(path, data)) { case (rr_ok(?di)) { did = di; } - case (rr_not_found(?prev, ?name)) { + case (rr_not_found(?name)) { ret none[ast.def]; } } |