From 14f50b34a3ee72beca54283a61e152bb088aa8e6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Apr 2020 17:53:54 +0200 Subject: [PATCH] use pre-computed layouts some more --- src/eval.rs | 6 +++--- src/machine.rs | 22 +++++++++++++++------- src/shims/env.rs | 2 +- src/shims/panic.rs | 6 +++--- src/shims/time.rs | 4 +--- src/shims/tls.rs | 8 ++++---- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index b360b1bd8bb..1caffe26476 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -130,7 +130,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( // Store `argc` and `argv` for macOS `_NSGetArg{c,v}`. { let argc_place = - ecx.allocate(ecx.layout_of(tcx.types.isize)?, MiriMemoryKind::Machine.into()); + ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into()); ecx.write_scalar(argc, argc_place.into())?; ecx.machine.argc = Some(argc_place.ptr); @@ -168,7 +168,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( }; // Return place (in static memory so that it does not count as leak). - let ret_place = ecx.allocate(ecx.layout_of(tcx.types.isize)?, MiriMemoryKind::Machine.into()); + let ret_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into()); // Call start function. ecx.call_function( start_instance, @@ -178,7 +178,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( )?; // Set the last_error to 0 - let errno_layout = ecx.layout_of(tcx.types.u32)?; + let errno_layout = ecx.machine.layouts.u32; let errno_place = ecx.allocate(errno_layout, MiriMemoryKind::Machine.into()); ecx.write_scalar(Scalar::from_u32(0), errno_place.into())?; ecx.machine.last_error = Some(errno_place); diff --git a/src/machine.rs b/src/machine.rs index 5cf42df8268..236b31ec4af 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -168,7 +168,7 @@ pub fn init_extern_statics<'tcx, 'mir>( "linux" => { // "__cxa_thread_atexit_impl" // This should be all-zero, pointer-sized. - let layout = this.layout_of(this.tcx.types.usize)?; + let layout = this.machine.layouts.usize; let place = this.allocate(layout, MiriMemoryKind::Machine.into()); this.write_scalar(Scalar::from_machine_usize(0, this), place.into())?; Self::add_extern_static(this, "__cxa_thread_atexit_impl", place.ptr); @@ -178,7 +178,7 @@ pub fn init_extern_statics<'tcx, 'mir>( "windows" => { // "_tls_used" // This is some obscure hack that is part of the Windows TLS story. It's a `u8`. - let layout = this.layout_of(this.tcx.types.u8)?; + let layout = this.machine.layouts.u8; let place = this.allocate(layout, MiriMemoryKind::Machine.into()); this.write_scalar(Scalar::from_u8(0), place.into())?; Self::add_extern_static(this, "_tls_used", place.ptr); @@ -190,16 +190,26 @@ pub fn init_extern_statics<'tcx, 'mir>( } /// Precomputed layouts of primitive types -pub(crate) struct PrimitiveLayouts<'tcx> { - pub(crate) i32: TyAndLayout<'tcx>, - pub(crate) u32: TyAndLayout<'tcx>, +pub struct PrimitiveLayouts<'tcx> { + pub unit: TyAndLayout<'tcx>, + pub i8: TyAndLayout<'tcx>, + pub i32: TyAndLayout<'tcx>, + pub isize: TyAndLayout<'tcx>, + pub u8: TyAndLayout<'tcx>, + pub u32: TyAndLayout<'tcx>, + pub usize: TyAndLayout<'tcx>, } impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> { fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result> { Ok(Self { + unit: layout_cx.layout_of(layout_cx.tcx.mk_unit())?, + i8: layout_cx.layout_of(layout_cx.tcx.types.i8)?, i32: layout_cx.layout_of(layout_cx.tcx.types.i32)?, + isize: layout_cx.layout_of(layout_cx.tcx.types.isize)?, + u8: layout_cx.layout_of(layout_cx.tcx.types.u8)?, u32: layout_cx.layout_of(layout_cx.tcx.types.u32)?, + usize: layout_cx.layout_of(layout_cx.tcx.types.usize)?, }) } } @@ -242,8 +252,6 @@ pub struct Evaluator<'tcx> { pub(crate) time_anchor: Instant, /// Precomputed `TyLayout`s for primitive data types that are commonly used inside Miri. - /// FIXME: Search through the rest of the codebase for more layout_of() calls that - /// could be stored here. pub(crate) layouts: PrimitiveLayouts<'tcx>, } diff --git a/src/shims/env.rs b/src/shims/env.rs index 44016827229..8dd2a3ca302 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -384,7 +384,7 @@ fn update_environ(&mut self) -> InterpResult<'tcx> { } else { // No `environ` allocated yet, let's do that. // This is memory backing an extern static, hence `Machine`, not `Env`. - let layout = this.layout_of(this.tcx.types.usize)?; + let layout = this.machine.layouts.usize; let place = this.allocate(layout, MiriMemoryKind::Machine.into()); this.machine.env_vars.environ = Some(place); } diff --git a/src/shims/panic.rs b/src/shims/panic.rs index 1aec236a533..450f735ad68 100644 --- a/src/shims/panic.rs +++ b/src/shims/panic.rs @@ -14,7 +14,7 @@ use log::trace; use rustc_middle::{mir, ty}; -use rustc_target::{spec::PanicStrategy, abi::LayoutOf}; +use rustc_target::spec::PanicStrategy; use crate::*; @@ -93,7 +93,7 @@ fn handle_try( // Now we make a function call, and pass `data` as first and only argument. let f_instance = this.memory.get_fn(try_fn)?.as_instance()?; trace!("try_fn: {:?}", f_instance); - let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into(); + let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into(); this.call_function( f_instance, &[data.into()], @@ -144,7 +144,7 @@ fn handle_stack_pop( // Push the `catch_fn` stackframe. let f_instance = this.memory.get_fn(catch_unwind.catch_fn)?.as_instance()?; trace!("catch_fn: {:?}", f_instance); - let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into(); + let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into(); this.call_function( f_instance, &[catch_unwind.data.into(), payload.into()], diff --git a/src/shims/time.rs b/src/shims/time.rs index a87db987820..de9a0313b14 100644 --- a/src/shims/time.rs +++ b/src/shims/time.rs @@ -1,8 +1,6 @@ use std::time::{Duration, SystemTime, Instant}; use std::convert::TryFrom; -use rustc_target::abi::LayoutOf; - use crate::stacked_borrows::Tag; use crate::*; use helpers::{immty_from_int_checked, immty_from_uint_checked}; @@ -107,7 +105,7 @@ fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: OpTy<'tcx, Tag>) -> InterpR let dwLowDateTime = u32::try_from(duration_ticks & 0x00000000FFFFFFFF).unwrap(); let dwHighDateTime = u32::try_from((duration_ticks & 0xFFFFFFFF00000000) >> 32).unwrap(); - let DWORD_tylayout = this.layout_of(this.tcx.types.u32)?; + let DWORD_tylayout = this.machine.layouts.u32; let imms = [ immty_from_uint_checked(dwLowDateTime, DWORD_tylayout)?, immty_from_uint_checked(dwHighDateTime, DWORD_tylayout)?, diff --git a/src/shims/tls.rs b/src/shims/tls.rs index cba7dde53d8..ba072e8ffd5 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -5,7 +5,7 @@ use log::trace; use rustc_middle::ty; -use rustc_target::abi::{LayoutOf, Size, HasDataLayout}; +use rustc_target::abi::{Size, HasDataLayout}; use crate::{HelpersEvalContextExt, InterpResult, MPlaceTy, Scalar, StackPopCleanup, Tag}; @@ -172,7 +172,7 @@ fn run_tls_dtors(&mut self) -> InterpResult<'tcx> { // The signature of this function is `unsafe extern "system" fn(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID)`. let reason = this.eval_path_scalar(&["std", "sys", "windows", "c", "DLL_PROCESS_DETACH"])?; - let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into(); + let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into(); this.call_function( thread_callback, &[Scalar::null_ptr(this).into(), reason.into(), Scalar::null_ptr(this).into()], @@ -191,7 +191,7 @@ fn run_tls_dtors(&mut self) -> InterpResult<'tcx> { if let Some((instance, data)) = this.machine.tls.global_dtor { trace!("Running global dtor {:?} on {:?}", instance, data); - let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into(); + let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into(); this.call_function( instance, &[data.into()], @@ -209,7 +209,7 @@ fn run_tls_dtors(&mut self) -> InterpResult<'tcx> { trace!("Running TLS dtor {:?} on {:?}", instance, ptr); assert!(!this.is_null(ptr).unwrap(), "data can't be NULL when dtor is called!"); - let ret_place = MPlaceTy::dangling(this.layout_of(this.tcx.mk_unit())?, this).into(); + let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into(); this.call_function( instance, &[ptr.into()],