From: Vytautas Astrauskas Date: Wed, 15 Apr 2020 00:21:52 +0000 (-0700) Subject: Generate fresh allocation ids for thread locals in eval_maybe_thread_local_static_const. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=963e9698f9ab959de06f42047ef1979bde0aac84;hp=0c4303cd7f903d2c05e70c05800dddefd7ccb7c6;p=rust.git Generate fresh allocation ids for thread locals in eval_maybe_thread_local_static_const. --- diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 114f1d9be36..b7c96dd7e98 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -139,7 +139,7 @@ fn report_msg<'tcx, 'mir>( mut helps: Vec, error: bool, ) { - let span = if let Some(frame) = ecx.machine.stack.last() { + let span = if let Some(frame) = ecx.active_thread_stack().last() { frame.current_source_info().unwrap().span } else { DUMMY_SP @@ -171,7 +171,7 @@ fn report_msg<'tcx, 'mir>( err.emit(); - for (i, frame) in ecx.machine.stack.iter().enumerate() { + for (i, frame) in ecx.active_thread_stack().iter().enumerate() { trace!("-------------------"); trace!("Frame {}", i); trace!(" return: {:?}", frame.return_place.map(|p| *p)); diff --git a/src/machine.rs b/src/machine.rs index b56755083f4..a9582f595ff 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -22,7 +22,7 @@ TyCtxt, }, }; -use rustc_span::{def_id::DefId, symbol::{sym, Symbol}}; +use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{LayoutOf, Size}; use crate::*; @@ -331,19 +331,6 @@ fn enforce_alignment(memory_extra: &MemoryExtra) -> bool { memory_extra.check_alignment } - #[inline(always)] - fn stack<'a>( - ecx: &'a InterpCx<'mir, 'tcx, Self> - ) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>] { - ecx.active_thread_stack() - } - - fn stack_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self> - ) -> &'a mut Vec> { - ecx.active_thread_stack_mut() - } - #[inline(always)] fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { ecx.machine.validate @@ -434,63 +421,52 @@ fn box_alloc( Ok(()) } - fn access_local( + fn eval_maybe_thread_local_static_const( ecx: &InterpCx<'mir, 'tcx, Self>, - frame: &Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>, - local: mir::Local, - ) -> InterpResult<'tcx, Operand> { - match frame.body.local_decls[local].local_info { - mir::LocalInfo::StaticRef { def_id, is_thread_local: true } => { - let static_alloc_id = ecx.tcx.alloc_map.lock().create_static_alloc(def_id); - let alloc_id = ecx.memory.extra.tls.get_or_register_allocation(*ecx.memory.tcx, static_alloc_id); - let tag = Self::tag_global_base_pointer(&ecx.memory.extra, alloc_id); - let pointer: Pointer = alloc_id.into(); - let pointer = pointer.with_tag(tag); - let scalar: Scalar<_> = pointer.into(); - let scalar: ScalarMaybeUndef<_> = scalar.into(); - let immediate: Immediate<_> = scalar.into(); - Ok( - Operand::Immediate(immediate) - ) - }, - _ => frame.locals[local].access(), + mut val: mir::interpret::ConstValue<'tcx> + )-> InterpResult<'tcx, mir::interpret::ConstValue<'tcx>> { + match &mut val { + mir::interpret::ConstValue::Scalar(Scalar::Ptr(ptr)) => { + let alloc_id = ptr.alloc_id; + let alloc = ecx.tcx.alloc_map.lock().get(alloc_id); + match alloc { + Some(GlobalAlloc::Static(def_id)) + if ecx.tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) => { + // We have a thread-local static. + let new_alloc_id = ecx.memory.extra.tls.get_or_register_allocation( + *ecx.memory.tcx, alloc_id); + ptr.alloc_id = new_alloc_id; + }, + _ => {}, + } + } + _ => {}, } + Ok(val) } fn canonical_alloc_id(mem: &Memory<'mir, 'tcx, Self>, id: AllocId) -> AllocId { let tcx = mem.tcx; - let alloc = tcx.alloc_map.lock().get(id); - fn is_thread_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { - tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) - } - match alloc { - Some(GlobalAlloc::Static(def_id)) if tcx.is_foreign_item(def_id) => { - if is_thread_local(*tcx, def_id) { - unimplemented!("Foreign thread local statics are not supported yet."); - } - // Figure out if this is an extern static, and if yes, which one. - let attrs = tcx.get_attrs(def_id); - let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) { - Some(name) => name, - None => tcx.item_name(def_id), - }; - // Check if we know this one. - if let Some(canonical_id) = mem.extra.extern_statics.get(&link_name) { - trace!("canonical_alloc_id: {:?} ({}) -> {:?}", id, link_name, canonical_id); - *canonical_id - } else { - // Return original id; `Memory::get_static_alloc` will throw an error. - id - } - }, - Some(GlobalAlloc::Static(def_id)) if is_thread_local(*tcx, def_id) => { - // We have a thread local, so we need to get a unique allocation id for it. - mem.extra.tls.get_or_register_allocation(*tcx, id) - }, + // Figure out if this is an extern static, and if yes, which one. + let def_id = match tcx.alloc_map.lock().get(id) { + Some(GlobalAlloc::Static(def_id)) if tcx.is_foreign_item(def_id) => def_id, _ => { // No need to canonicalize anything. - id + return id; } + }; + let attrs = tcx.get_attrs(def_id); + let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) { + Some(name) => name, + None => tcx.item_name(def_id), + }; + // Check if we know this one. + if let Some(canonical_id) = mem.extra.extern_statics.get(&link_name) { + trace!("canonical_alloc_id: {:?} ({}) -> {:?}", id, link_name, canonical_id); + *canonical_id + } else { + // Return original id; `Memory::get_static_alloc` will throw an error. + id } } @@ -587,6 +563,18 @@ fn init_frame_extra( Ok(frame.with_extra(extra)) } + fn stack<'a>( + ecx: &'a InterpCx<'mir, 'tcx, Self> + ) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>] { + ecx.active_thread_stack() + } + + fn stack_mut<'a>( + ecx: &'a mut InterpCx<'mir, 'tcx, Self> + ) -> &'a mut Vec> { + ecx.active_thread_stack_mut() + } + #[inline(always)] fn stack<'a>( ecx: &'a InterpCx<'mir, 'tcx, Self>, diff --git a/src/shims/tls.rs b/src/shims/tls.rs index ec8c31fe2c1..5cef3871c03 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -161,7 +161,7 @@ fn fetch_tls_dtor( Entry::Occupied(entry) => { let (thread_id, data_scalar) = entry.remove_entry(); if let Some(dtor) = dtor { - let ret = Some((dtor, thread_id, data_scalar, key)); + let ret = Some((*dtor, thread_id, data_scalar, key)); return ret; } }