about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-31 18:28:32 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-03-31 18:28:59 -0700
commitbdea34387945aee7d18981a8c59f5b04beb560fc (patch)
treefaaa284bb575ade6e1f0f1b1fe415be89a088fc4
parentfffc5d3b3dd495d2301304cab1100df6f89b6aa7 (diff)
rustc: Use the path index. Speeds up compilation a lot.
-rw-r--r--src/comp/front/creader.rs139
1 files changed, 48 insertions, 91 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index f9ef70ca740..22c38c3172c 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];
         }
     }