cache mangle_internal_symbol results
This commit is contained in:
parent
ab8836f548
commit
024c8c3063
3 changed files with 41 additions and 34 deletions
|
@ -17,6 +17,7 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
|
use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
|
||||||
use rustc_session::config::CrateType;
|
use rustc_session::config::CrateType;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||||
use rustc_target::callconv::{Conv, FnAbi};
|
use rustc_target::callconv::{Conv, FnAbi};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
@ -1258,6 +1259,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
|
|
||||||
interp_ok(array)
|
interp_ok(array)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mangle_internal_symbol<'a>(&'a mut self, name: &'static str) -> &'a str
|
||||||
|
where
|
||||||
|
'tcx: 'a,
|
||||||
|
{
|
||||||
|
let this = self.eval_context_mut();
|
||||||
|
let tcx = *this.tcx;
|
||||||
|
this.machine
|
||||||
|
.mangle_internal_symbol_cache
|
||||||
|
.entry(name)
|
||||||
|
.or_insert_with(|| mangle_internal_symbol(tcx, name))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> MiriMachine<'tcx> {
|
impl<'tcx> MiriMachine<'tcx> {
|
||||||
|
|
|
@ -611,6 +611,9 @@ pub struct MiriMachine<'tcx> {
|
||||||
pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
|
pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
|
||||||
/// Remembers which int2ptr casts we have already warned about.
|
/// Remembers which int2ptr casts we have already warned about.
|
||||||
pub(crate) int2ptr_warned: RefCell<FxHashSet<Span>>,
|
pub(crate) int2ptr_warned: RefCell<FxHashSet<Span>>,
|
||||||
|
|
||||||
|
/// Cache for `mangle_internal_symbol`.
|
||||||
|
pub(crate) mangle_internal_symbol_cache: FxHashMap<&'static str, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> MiriMachine<'tcx> {
|
impl<'tcx> MiriMachine<'tcx> {
|
||||||
|
@ -757,6 +760,7 @@ impl<'tcx> MiriMachine<'tcx> {
|
||||||
native_call_mem_warned: Cell::new(false),
|
native_call_mem_warned: Cell::new(false),
|
||||||
reject_in_isolation_warned: Default::default(),
|
reject_in_isolation_warned: Default::default(),
|
||||||
int2ptr_warned: Default::default(),
|
int2ptr_warned: Default::default(),
|
||||||
|
mangle_internal_symbol_cache: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,6 +934,7 @@ impl VisitProvenance for MiriMachine<'_> {
|
||||||
native_call_mem_warned: _,
|
native_call_mem_warned: _,
|
||||||
reject_in_isolation_warned: _,
|
reject_in_isolation_warned: _,
|
||||||
int2ptr_warned: _,
|
int2ptr_warned: _,
|
||||||
|
mangle_internal_symbol_cache: _,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
threads.visit_provenance(visit);
|
threads.visit_provenance(visit);
|
||||||
|
|
|
@ -9,10 +9,9 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::CrateNum;
|
use rustc_hir::def_id::CrateNum;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::mir::interpret::AllocInit;
|
use rustc_middle::mir::interpret::AllocInit;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::{Instance, Ty};
|
||||||
use rustc_middle::{mir, ty};
|
use rustc_middle::{mir, ty};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
|
||||||
use rustc_target::callconv::{Conv, FnAbi};
|
use rustc_target::callconv::{Conv, FnAbi};
|
||||||
|
|
||||||
use self::helpers::{ToHost, ToSoft};
|
use self::helpers::{ToHost, ToSoft};
|
||||||
|
@ -52,7 +51,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
|
|
||||||
// Some shims forward to other MIR bodies.
|
// Some shims forward to other MIR bodies.
|
||||||
match link_name.as_str() {
|
match link_name.as_str() {
|
||||||
name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_error_handler") => {
|
name if name == this.mangle_internal_symbol("__rust_alloc_error_handler") => {
|
||||||
// Forward to the right symbol that implements this function.
|
// Forward to the right symbol that implements this function.
|
||||||
let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else {
|
let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else {
|
||||||
// in real code, this symbol does not exist without an allocator
|
// in real code, this symbol does not exist without an allocator
|
||||||
|
@ -60,11 +59,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
"`__rust_alloc_error_handler` cannot be called when no alloc error handler is set"
|
"`__rust_alloc_error_handler` cannot be called when no alloc error handler is set"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
let name =
|
let name = Symbol::intern(
|
||||||
mangle_internal_symbol(*this.tcx, alloc_error_handler_name(handler_kind));
|
this.mangle_internal_symbol(alloc_error_handler_name(handler_kind)),
|
||||||
let handler = this
|
);
|
||||||
.lookup_exported_symbol(Symbol::intern(&name))?
|
let handler =
|
||||||
.expect("missing alloc error handler symbol");
|
this.lookup_exported_symbol(name)?.expect("missing alloc error handler symbol");
|
||||||
return interp_ok(Some(handler));
|
return interp_ok(Some(handler));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -138,30 +137,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
// Find it if it was not cached.
|
// Find it if it was not cached.
|
||||||
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
|
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
|
||||||
helpers::iter_exported_symbols(tcx, |cnum, def_id| {
|
helpers::iter_exported_symbols(tcx, |cnum, def_id| {
|
||||||
|
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||||
|
// Skip over imports of items.
|
||||||
if tcx.is_foreign_item(def_id) {
|
if tcx.is_foreign_item(def_id) {
|
||||||
// Skip over imports of items
|
return interp_ok(());
|
||||||
|
}
|
||||||
|
// Skip over items without an explicitly defined symbol name.
|
||||||
|
if !(attrs.export_name.is_some()
|
||||||
|
|| attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|
||||||
|
|| attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL))
|
||||||
|
{
|
||||||
return interp_ok(());
|
return interp_ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
let instance = Instance::mono(tcx, def_id);
|
||||||
// FIXME use tcx.symbol_name(instance) instead
|
let symbol_name = tcx.symbol_name(instance).name;
|
||||||
let symbol_name = if let Some(export_name) = attrs.export_name {
|
if symbol_name == link_name.as_str() {
|
||||||
export_name
|
|
||||||
} else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|
|
||||||
|| attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
|
||||||
{
|
|
||||||
tcx.item_name(def_id)
|
|
||||||
} else {
|
|
||||||
// Skip over items without an explicitly defined symbol name.
|
|
||||||
return interp_ok(());
|
|
||||||
};
|
|
||||||
let symbol_name =
|
|
||||||
if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
|
|
||||||
Symbol::intern(&mangle_internal_symbol(tcx, symbol_name.as_str()))
|
|
||||||
} else {
|
|
||||||
symbol_name
|
|
||||||
};
|
|
||||||
if symbol_name == link_name {
|
|
||||||
if let Some((original_instance, original_cnum)) = instance_and_crate {
|
if let Some((original_instance, original_cnum)) = instance_and_crate {
|
||||||
// Make sure we are consistent wrt what is 'first' and 'second'.
|
// Make sure we are consistent wrt what is 'first' and 'second'.
|
||||||
let original_span = tcx.def_span(original_instance.def_id()).data();
|
let original_span = tcx.def_span(original_instance.def_id()).data();
|
||||||
|
@ -505,9 +496,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rust allocation
|
// Rust allocation
|
||||||
name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc")
|
name if name == this.mangle_internal_symbol("__rust_alloc") || name == "miri_alloc" => {
|
||||||
|| name == "miri_alloc" =>
|
|
||||||
{
|
|
||||||
let default = |ecx: &mut MiriInterpCx<'tcx>| {
|
let default = |ecx: &mut MiriInterpCx<'tcx>| {
|
||||||
// Only call `check_shim` when `#[global_allocator]` isn't used. When that
|
// Only call `check_shim` when `#[global_allocator]` isn't used. When that
|
||||||
// macro is used, we act like no shim exists, so that the exported function can run.
|
// macro is used, we act like no shim exists, so that the exported function can run.
|
||||||
|
@ -540,7 +529,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
_ => return this.emulate_allocator(default),
|
_ => return this.emulate_allocator(default),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_zeroed") => {
|
name if name == this.mangle_internal_symbol("__rust_alloc_zeroed") => {
|
||||||
return this.emulate_allocator(|this| {
|
return this.emulate_allocator(|this| {
|
||||||
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
||||||
// default case.
|
// default case.
|
||||||
|
@ -559,7 +548,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
this.write_pointer(ptr, dest)
|
this.write_pointer(ptr, dest)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
name if name == mangle_internal_symbol(*this.tcx, "__rust_dealloc")
|
name if name == this.mangle_internal_symbol("__rust_dealloc")
|
||||||
|| name == "miri_dealloc" =>
|
|| name == "miri_dealloc" =>
|
||||||
{
|
{
|
||||||
let default = |ecx: &mut MiriInterpCx<'tcx>| {
|
let default = |ecx: &mut MiriInterpCx<'tcx>| {
|
||||||
|
@ -592,7 +581,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
_ => return this.emulate_allocator(default),
|
_ => return this.emulate_allocator(default),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name if name == mangle_internal_symbol(*this.tcx, "__rust_realloc") => {
|
name if name == this.mangle_internal_symbol("__rust_realloc") => {
|
||||||
return this.emulate_allocator(|this| {
|
return this.emulate_allocator(|this| {
|
||||||
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
||||||
// default case.
|
// default case.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue