Skip to content

Commit 2fe2e59

Browse files
committed
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.
2 parents 094e426 + 0b47b4c commit 2fe2e59

File tree

2 files changed

+29
-26
lines changed

2 files changed

+29
-26
lines changed

src/librustc/metadata/decoder.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,20 @@ type cmd = @crate_metadata;
5151
// what crate that's in and give us a def_id that makes sense for the current
5252
// build.
5353

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

6262
let belt = tag_index_buckets_bucket_elt;
6363

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

9090
fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {

src/librustc/metadata/encoder.rs

+23-20
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
319319
id: NodeId,
320320
variants: &[variant],
321321
path: &[ast_map::path_elt],
322-
index: @mut ~[entry<int>],
322+
index: @mut ~[entry<i64>],
323323
generics: &ast::Generics) {
324324
debug!("encode_enum_variant_info(id=%?)", id);
325325

@@ -329,7 +329,8 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
329329
ast::def_id { crate: LOCAL_CRATE, node: id });
330330
for variant in variants.iter() {
331331
let def_id = local_def(variant.node.id);
332-
index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()});
332+
index.push(entry {val: variant.node.id as i64,
333+
pos: ebml_w.writer.tell()});
333334
ebml_w.start_tag(tag_items_data_item);
334335
encode_def_id(ebml_w, def_id);
335336
encode_family(ebml_w, 'v');
@@ -677,8 +678,8 @@ fn encode_info_for_struct(ecx: &EncodeContext,
677678
ebml_w: &mut writer::Encoder,
678679
path: &[ast_map::path_elt],
679680
fields: &[@struct_field],
680-
global_index: @mut ~[entry<int>])
681-
-> ~[entry<int>] {
681+
global_index: @mut ~[entry<i64>])
682+
-> ~[entry<i64>] {
682683
/* Each class has its own index, since different classes
683684
may have fields with the same name */
684685
let mut index = ~[];
@@ -692,8 +693,8 @@ fn encode_info_for_struct(ecx: &EncodeContext,
692693
};
693694

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

718719
ebml_w.start_tag(tag_items_data_item);
719720
encode_def_id(ebml_w, local_def(ctor_id));
@@ -815,13 +816,13 @@ fn should_inline(attrs: &[Attribute]) -> bool {
815816
fn encode_info_for_item(ecx: &EncodeContext,
816817
ebml_w: &mut writer::Encoder,
817818
item: @item,
818-
index: @mut ~[entry<int>],
819+
index: @mut ~[entry<i64>],
819820
path: &[ast_map::path_elt]) {
820821
let tcx = ecx.tcx;
821822

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

@@ -969,7 +970,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
969970

970971
/* Each class has its own index -- encode it */
971972
let bkts = create_index(idx);
972-
encode_index(ebml_w, bkts, write_int);
973+
encode_index(ebml_w, bkts, write_i64);
973974
ebml_w.end_tag();
974975

975976
// 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,
10401041
Some(ast_methods[i])
10411042
} else { None };
10421043

1043-
index.push(entry {val: m.def_id.node, pos: ebml_w.writer.tell()});
1044+
index.push(entry {val: m.def_id.node as i64,
1045+
pos: ebml_w.writer.tell()});
10441046
encode_info_for_method(ecx,
10451047
ebml_w,
10461048
*m,
@@ -1086,7 +1088,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
10861088

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

1089-
index.push(entry {val: method_def_id.node, pos: ebml_w.writer.tell()});
1091+
index.push(entry {val: method_def_id.node as i64,
1092+
pos: ebml_w.writer.tell()});
10901093

10911094
ebml_w.start_tag(tag_items_data_item);
10921095

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

11531156
ebml_w.start_tag(tag_items_data_item);
11541157
match nitem.node {
@@ -1184,10 +1187,10 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
11841187
fn encode_info_for_items(ecx: &EncodeContext,
11851188
ebml_w: &mut writer::Encoder,
11861189
crate: &Crate)
1187-
-> ~[entry<int>] {
1190+
-> ~[entry<i64>] {
11881191
let index = @mut ~[];
11891192
ebml_w.start_tag(tag_items_data);
1190-
index.push(entry { val: CRATE_NODE_ID, pos: ebml_w.writer.tell() });
1193+
index.push(entry { val: CRATE_NODE_ID as i64, pos: ebml_w.writer.tell() });
11911194
encode_info_for_mod(ecx,
11921195
ebml_w,
11931196
&crate.module,
@@ -1304,7 +1307,7 @@ fn write_str(writer: @io::Writer, s: ~str) {
13041307
writer.write_str(s);
13051308
}
13061309

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

16241627
i = *wr.pos;
16251628
let items_buckets = create_index(items_index);
1626-
encode_index(&mut ebml_w, items_buckets, write_int);
1629+
encode_index(&mut ebml_w, items_buckets, write_i64);
16271630
ecx.stats.index_bytes = *wr.pos - i;
16281631
ebml_w.end_tag();
16291632

0 commit comments

Comments
 (0)