auto merge of #8361 : alexcrichton/rust/fix-node-hashes-in-crates, 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.
This commit is contained in:
commit
2fe2e59c67
@ -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 {
|
||||
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
@ -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');
|
||||
@ -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 = ~[];
|
||||
@ -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);
|
||||
@ -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));
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
@ -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,
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
@ -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,
|
||||
@ -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);
|
||||
}
|
||||
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user