Skip to content

Commit

Permalink
auto merge of rust-lang#8361 : alexcrichton/rust/fix-node-hashes-in-c…
Browse files Browse the repository at this point in the history
…rates, r=thestinger

When running rusti 32-bit tests from a 64-bit host, these errors came up frequently. My best idea as to what was happening is:

1. First, if you hash the same `int` value on 32-bit and 64-bit, you will get two different hashes.
2. In a cross-compile situation, let's say x86_64 is building an i686 library, all of the hashes will be 64-bit hashes.
3. Then let's say you use the i686 libraries and then attempt to link against the same i686 libraries, because you're calculating hashes with a 32-bit int instead of a 64-bit one, you'll have different hashes and you won't be able to find items in the metadata (the items were generated with a 64-bit int).

This patch changes the items to always be hashed as an `i64` to preserve the hash value across architectures. Here's a nice before/after for this patch of the state of rusti tests

```
host   target  before  after
64     64      yes     yes
64     32      no      no (llvm assertion)
32     64      no      yes
32     32      no      no (llvm assertion)
```

Basically one case started working, but currently when the target is 32-bit LLVM is having a lot of problems generating code. That's another separate issue though.
  • Loading branch information
bors committed Aug 9, 2013
2 parents 094e426 + 0b47b4c commit 2fe2e59
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 26 deletions.
12 changes: 6 additions & 6 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,20 @@ type cmd = @crate_metadata;
// what crate that's in and give us a def_id that makes sense for the current
// build.

fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: uint) ->
fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: u64) ->
Option<ebml::Doc> {
let index = reader::get_doc(d, tag_index);
let table = reader::get_doc(index, tag_index_table);
let hash_pos = table.start + hash % 256u * 4u;
let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4u) as uint;
let hash_pos = table.start + (hash % 256 * 4) as uint;
let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4) as uint;
let tagged_doc = reader::doc_at(d.data, pos);

let belt = tag_index_buckets_bucket_elt;

let mut ret = None;
do reader::tagged_docs(tagged_doc.doc, belt) |elt| {
let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint;
if eq_fn(elt.data.slice(elt.start + 4u, elt.end)) {
let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4) as uint;
if eq_fn(elt.data.slice(elt.start + 4, elt.end)) {
ret = Some(reader::doc_at(d.data, pos).doc);
false
} else {
Expand All @@ -84,7 +84,7 @@ pub fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option<ebml::Doc> {
}
lookup_hash(items,
|a| eq_item(a, item_id),
item_id.hash() as uint)
(item_id as i64).hash())
}

fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {
Expand Down
43 changes: 23 additions & 20 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
id: NodeId,
variants: &[variant],
path: &[ast_map::path_elt],
index: @mut ~[entry<int>],
index: @mut ~[entry<i64>],
generics: &ast::Generics) {
debug!("encode_enum_variant_info(id=%?)", id);

Expand All @@ -329,7 +329,8 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
ast::def_id { crate: LOCAL_CRATE, node: id });
for variant in variants.iter() {
let def_id = local_def(variant.node.id);
index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()});
index.push(entry {val: variant.node.id as i64,
pos: ebml_w.writer.tell()});
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, def_id);
encode_family(ebml_w, 'v');
Expand Down Expand Up @@ -677,8 +678,8 @@ fn encode_info_for_struct(ecx: &EncodeContext,
ebml_w: &mut writer::Encoder,
path: &[ast_map::path_elt],
fields: &[@struct_field],
global_index: @mut ~[entry<int>])
-> ~[entry<int>] {
global_index: @mut ~[entry<i64>])
-> ~[entry<i64>] {
/* Each class has its own index, since different classes
may have fields with the same name */
let mut index = ~[];
Expand All @@ -692,8 +693,8 @@ fn encode_info_for_struct(ecx: &EncodeContext,
};

let id = field.node.id;
index.push(entry {val: id, pos: ebml_w.writer.tell()});
global_index.push(entry {val: id, pos: ebml_w.writer.tell()});
index.push(entry {val: id as i64, pos: ebml_w.writer.tell()});
global_index.push(entry {val: id as i64, pos: ebml_w.writer.tell()});
ebml_w.start_tag(tag_items_data_item);
debug!("encode_info_for_struct: doing %s %d",
tcx.sess.str_of(nm), id);
Expand All @@ -712,8 +713,8 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
path: &[ast_map::path_elt],
name: ast::ident,
ctor_id: NodeId,
index: @mut ~[entry<int>]) {
index.push(entry { val: ctor_id, pos: ebml_w.writer.tell() });
index: @mut ~[entry<i64>]) {
index.push(entry { val: ctor_id as i64, pos: ebml_w.writer.tell() });

ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(ctor_id));
Expand Down Expand Up @@ -815,13 +816,13 @@ fn should_inline(attrs: &[Attribute]) -> bool {
fn encode_info_for_item(ecx: &EncodeContext,
ebml_w: &mut writer::Encoder,
item: @item,
index: @mut ~[entry<int>],
index: @mut ~[entry<i64>],
path: &[ast_map::path_elt]) {
let tcx = ecx.tcx;

fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
index: @mut ~[entry<int>]) {
index.push(entry { val: item.id, pos: ebml_w.writer.tell() });
index: @mut ~[entry<i64>]) {
index.push(entry { val: item.id as i64, pos: ebml_w.writer.tell() });
}
let add_to_index: &fn() = || add_to_index_(item, ebml_w, index);

Expand Down Expand Up @@ -969,7 +970,7 @@ fn encode_info_for_item(ecx: &EncodeContext,

/* Each class has its own index -- encode it */
let bkts = create_index(idx);
encode_index(ebml_w, bkts, write_int);
encode_index(ebml_w, bkts, write_i64);
ebml_w.end_tag();

// If this is a tuple- or enum-like struct, encode the type of the
Expand Down Expand Up @@ -1040,7 +1041,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
Some(ast_methods[i])
} else { None };

index.push(entry {val: m.def_id.node, pos: ebml_w.writer.tell()});
index.push(entry {val: m.def_id.node as i64,
pos: ebml_w.writer.tell()});
encode_info_for_method(ecx,
ebml_w,
*m,
Expand Down Expand Up @@ -1086,7 +1088,8 @@ fn encode_info_for_item(ecx: &EncodeContext,

let method_ty = ty::method(tcx, method_def_id);

index.push(entry {val: method_def_id.node, pos: ebml_w.writer.tell()});
index.push(entry {val: method_def_id.node as i64,
pos: ebml_w.writer.tell()});

ebml_w.start_tag(tag_items_data_item);

Expand Down Expand Up @@ -1145,10 +1148,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
fn encode_info_for_foreign_item(ecx: &EncodeContext,
ebml_w: &mut writer::Encoder,
nitem: @foreign_item,
index: @mut ~[entry<int>],
index: @mut ~[entry<i64>],
path: &ast_map::path,
abi: AbiSet) {
index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
index.push(entry { val: nitem.id as i64, pos: ebml_w.writer.tell() });

ebml_w.start_tag(tag_items_data_item);
match nitem.node {
Expand Down Expand Up @@ -1184,10 +1187,10 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
fn encode_info_for_items(ecx: &EncodeContext,
ebml_w: &mut writer::Encoder,
crate: &Crate)
-> ~[entry<int>] {
-> ~[entry<i64>] {
let index = @mut ~[];
ebml_w.start_tag(tag_items_data);
index.push(entry { val: CRATE_NODE_ID, pos: ebml_w.writer.tell() });
index.push(entry { val: CRATE_NODE_ID as i64, pos: ebml_w.writer.tell() });
encode_info_for_mod(ecx,
ebml_w,
&crate.module,
Expand Down Expand Up @@ -1304,7 +1307,7 @@ fn write_str(writer: @io::Writer, s: ~str) {
writer.write_str(s);
}

fn write_int(writer: @io::Writer, &n: &int) {
fn write_i64(writer: @io::Writer, &n: &i64) {
assert!(n < 0x7fff_ffff);
writer.write_be_u32(n as u32);
}
Expand Down Expand Up @@ -1623,7 +1626,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {

i = *wr.pos;
let items_buckets = create_index(items_index);
encode_index(&mut ebml_w, items_buckets, write_int);
encode_index(&mut ebml_w, items_buckets, write_i64);
ecx.stats.index_bytes = *wr.pos - i;
ebml_w.end_tag();

Expand Down

0 comments on commit 2fe2e59

Please sign in to comment.