trans: Make names of internal symbols independent of CGU translation order.

Every codegen unit gets its own local counter for generating new symbol
names. This makes bitcode and object files reproducible at the binary
level even when incremental compilation is used.
This commit is contained in:
Michael Woerister 2016-10-21 12:41:20 -04:00
parent da5b6467c3
commit e6aa92c432
3 changed files with 16 additions and 8 deletions

View File

@ -799,9 +799,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
s.as_ptr() as *const c_char,
s.len() as c_uint,
!null_terminated as Bool);
let gsym = token::gensym("str");
let sym = format!("str{}", gsym.0);
let sym = cx.generate_local_symbol_name("str");
let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
bug!("symbol `{}` is already defined", sym);
});

View File

@ -30,7 +30,6 @@ use rustc::hir;
use std::ffi::{CStr, CString};
use syntax::ast;
use syntax::attr;
use syntax::parse::token;
pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
unsafe {
@ -44,10 +43,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
kind: &str)
-> ValueRef {
unsafe {
// FIXME: this totally needs a better name generation scheme, perhaps a simple global
// counter? Also most other uses of gensym in trans.
let gsym = token::gensym("_");
let name = format!("{}{}", kind, gsym.0);
let name = ccx.generate_local_symbol_name(kind);
let gv = declare::define_global(ccx, &name[..], val_ty(cv)).unwrap_or_else(||{
bug!("symbol `{}` is already defined", name);
});

View File

@ -166,6 +166,9 @@ pub struct LocalCrateContext<'tcx> {
type_of_depth: Cell<usize>,
symbol_map: Rc<SymbolMap<'tcx>>,
/// A counter that is used for generating local symbol names
local_gen_sym_counter: Cell<usize>,
}
// Implement DepTrackingMapConfig for `trait_cache`
@ -688,6 +691,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
n_llvm_insns: Cell::new(0),
type_of_depth: Cell::new(0),
symbol_map: symbol_map,
local_gen_sym_counter: Cell::new(0),
};
let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = {
@ -1021,6 +1025,16 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
self.shared().empty_substs_for_def_id(item_def_id)
}
/// Generate a new symbol name with the given prefix. This symbol name must
/// only be used for definitions with `internal` or `private` linkage.
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
let idx = self.local().local_gen_sym_counter.get();
self.local().local_gen_sym_counter.set(idx + 1);
// Include a '.' character, so there can be no accidental conflicts with
// user defined names
format!("{}.{}", prefix, idx)
}
}
pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);