Skip to content

Commit

Permalink
Replace TyDesc and its uses with trait vtables and a type_name intrin…
Browse files Browse the repository at this point in the history
…sic.
  • Loading branch information
eddyb committed Mar 17, 2015
1 parent 3e98ab5 commit e256b7f
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 306 deletions.
24 changes: 23 additions & 1 deletion src/libarena/lib.rs
Expand Up @@ -42,8 +42,9 @@ extern crate alloc;

use std::cell::{Cell, RefCell};
use std::cmp;
use std::intrinsics::{TyDesc, get_tydesc};
use std::intrinsics;
#[cfg(stage0)] // SNAP 270a677
use std::intrinsics::{get_tydesc, TyDesc};
use std::marker;
use std::mem;
#[cfg(stage0)]
Expand Down Expand Up @@ -186,6 +187,27 @@ fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
((p & !1) as *const TyDesc, p & 1 == 1)
}

// HACK(eddyb) TyDesc replacement using a trait object vtable.
// This could be replaced in the future with a custom DST layout,
// or `&'static (drop_glue, size, align)` created by a `const fn`.
#[cfg(not(stage0))] // SNAP 270a677
struct TyDesc {
drop_glue: fn(*const i8),
size: usize,
align: usize
}

#[cfg(not(stage0))] // SNAP 270a677
unsafe fn get_tydesc<T>() -> *const TyDesc {
use std::raw::TraitObject;

let ptr = &*(1 as *const T);

// Can use any trait that is implemented for all types.
let obj = mem::transmute::<&marker::MarkerTrait, TraitObject>(ptr);
obj.vtable as *const TyDesc
}

impl<'longer_than_self> Arena<'longer_than_self> {
fn chunk_size(&self) -> usize {
self.copy_head.borrow().capacity()
Expand Down
7 changes: 7 additions & 0 deletions src/libcore/intrinsics.rs
Expand Up @@ -44,10 +44,12 @@

use marker::Sized;

#[cfg(stage0)] // SNAP 270a677
pub type GlueFn = extern "Rust" fn(*const i8);

#[lang="ty_desc"]
#[derive(Copy)]
#[cfg(stage0)] // SNAP 270a677
pub struct TyDesc {
// sizeof(T)
pub size: usize,
Expand Down Expand Up @@ -197,8 +199,13 @@ extern "rust-intrinsic" {
pub fn pref_align_of<T>() -> usize;

/// Get a static pointer to a type descriptor.
#[cfg(stage0)] // SNAP 270a677
pub fn get_tydesc<T: ?Sized>() -> *const TyDesc;

/// Gets a static string slice containing the name of a type.
#[cfg(not(stage0))] // SNAP 270a677
pub fn type_name<T: ?Sized>() -> &'static str;

/// Gets an identifier which is globally unique to the specified type. This
/// function will return the same value for a type regardless of whichever
/// crate it is invoked in.
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/middle/lang_items.rs
Expand Up @@ -316,9 +316,6 @@ lets_do_this! {

StartFnLangItem, "start", start_fn;

TyDescStructLangItem, "ty_desc", ty_desc;
OpaqueStructLangItem, "opaque", opaque;

EhPersonalityLangItem, "eh_personality", eh_personality;

ExchangeHeapLangItem, "exchange_heap", exchange_heap;
Expand Down
12 changes: 1 addition & 11 deletions src/librustc/middle/ty.rs
Expand Up @@ -47,8 +47,7 @@ use middle::check_const;
use middle::const_eval;
use middle::def::{self, DefMap, ExportMap};
use middle::dependency_format;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::mem_categorization as mc;
use middle::region;
use middle::resolve_lifetime;
Expand Down Expand Up @@ -723,7 +722,6 @@ pub struct ctxt<'tcx> {
pub object_cast_map: ObjectCastMap<'tcx>,

pub map: ast_map::Map<'tcx>,
pub intrinsic_defs: RefCell<DefIdMap<Ty<'tcx>>>,
pub freevars: RefCell<FreevarMap>,
pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
Expand Down Expand Up @@ -2575,7 +2573,6 @@ pub fn mk_ctxt<'tcx>(s: Session,
super_predicates: RefCell::new(DefIdMap()),
object_cast_map: RefCell::new(NodeMap()),
map: map,
intrinsic_defs: RefCell::new(DefIdMap()),
freevars: freevars,
tcache: RefCell::new(DefIdMap()),
rcache: RefCell::new(FnvHashMap()),
Expand Down Expand Up @@ -5951,13 +5948,6 @@ pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
.collect()
}

pub fn get_tydesc_ty<'tcx>(tcx: &ctxt<'tcx>) -> Result<Ty<'tcx>, String> {
tcx.lang_items.require(TyDescStructLangItem).map(|tydesc_lang_item| {
tcx.intrinsic_defs.borrow().get(&tydesc_lang_item).cloned()
.expect("Failed to resolve TyDesc")
})
}

pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
lookup_locally_or_in_crate_store(
"item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(),
Expand Down
22 changes: 1 addition & 21 deletions src/librustc_trans/trans/base.rs
Expand Up @@ -57,8 +57,7 @@ use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
use trans::common::{CrateContext, ExternMap, FunctionContext};
use trans::common::{Result, NodeIdAndSpan};
use trans::common::{node_id_type, return_type_is_void};
use trans::common::{tydesc_info, type_is_immediate};
use trans::common::{type_is_zero_size, val_ty};
use trans::common::{type_is_immediate, type_is_zero_size, val_ty};
use trans::common;
use trans::consts;
use trans::context::SharedCrateContext;
Expand Down Expand Up @@ -90,7 +89,6 @@ use std::ffi::{CStr, CString};
use std::cell::{Cell, RefCell};
use std::collections::HashSet;
use std::mem;
use std::rc::Rc;
use std::str;
use std::{i8, i16, i32, i64};
use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
Expand Down Expand Up @@ -392,22 +390,6 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
}

// Type descriptor and type glue stuff

pub fn get_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
t: Ty<'tcx>) -> Rc<tydesc_info<'tcx>> {
match ccx.tydescs().borrow().get(&t) {
Some(inf) => return inf.clone(),
_ => { }
}

ccx.stats().n_static_tydescs.set(ccx.stats().n_static_tydescs.get() + 1);
let inf = Rc::new(glue::declare_tydesc(ccx, t));

ccx.tydescs().borrow_mut().insert(t, inf.clone());
inf
}

#[allow(dead_code)] // useful
pub fn set_optimize_for_size(f: ValueRef) {
llvm::SetFunctionAttribute(f, llvm::OptimizeForSizeAttribute)
Expand Down Expand Up @@ -3137,7 +3119,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
}

for ccx in shared_ccx.iter() {
glue::emit_tydescs(&ccx);
if ccx.sess().opts.debuginfo != NoDebugInfo {
debuginfo::finalize(&ccx);
}
Expand All @@ -3149,7 +3130,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
if shared_ccx.sess().trans_stats() {
let stats = shared_ccx.stats();
println!("--- trans stats ---");
println!("n_static_tydescs: {}", stats.n_static_tydescs.get());
println!("n_glues_created: {}", stats.n_glues_created.get());
println!("n_null_glues: {}", stats.n_null_glues.get());
println!("n_real_glues: {}", stats.n_real_glues.get());
Expand Down
9 changes: 0 additions & 9 deletions src/librustc_trans/trans/common.rs
Expand Up @@ -316,15 +316,6 @@ pub fn gensym_name(name: &str) -> PathElem {
PathName(token::gensym(&format!("{}:{}", name, num)))
}

#[derive(Copy)]
pub struct tydesc_info<'tcx> {
pub ty: Ty<'tcx>,
pub tydesc: ValueRef,
pub size: ValueRef,
pub align: ValueRef,
pub name: ValueRef,
}

/*
* A note on nomenclature of linking: "extern", "foreign", and "upcall".
*
Expand Down
24 changes: 1 addition & 23 deletions src/librustc_trans/trans/context.rs
Expand Up @@ -18,7 +18,7 @@ use middle::traits;
use trans::adt;
use trans::base;
use trans::builder::Builder;
use trans::common::{ExternMap,tydesc_info,BuilderRef_res};
use trans::common::{ExternMap,BuilderRef_res};
use trans::debuginfo;
use trans::monomorphize::MonoId;
use trans::type_::{Type, TypeNames};
Expand All @@ -38,7 +38,6 @@ use syntax::ast;
use syntax::parse::token::InternedString;

pub struct Stats {
pub n_static_tydescs: Cell<uint>,
pub n_glues_created: Cell<uint>,
pub n_null_glues: Cell<uint>,
pub n_real_glues: Cell<uint>,
Expand Down Expand Up @@ -89,10 +88,6 @@ pub struct LocalCrateContext<'tcx> {
needs_unwind_cleanup_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
fn_pointer_shims: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
drop_glues: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
tydescs: RefCell<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>>,
/// Set when running emit_tydescs to enforce that no more tydescs are
/// created.
finished_tydescs: Cell<bool>,
/// Track mapping of external ids to local items imported for inlining
external: RefCell<DefIdMap<Option<ast::NodeId>>>,
/// Backwards version of the `external` map (inlined items to where they
Expand Down Expand Up @@ -264,7 +259,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
symbol_hasher: RefCell::new(symbol_hasher),
tcx: tcx,
stats: Stats {
n_static_tydescs: Cell::new(0),
n_glues_created: Cell::new(0),
n_null_glues: Cell::new(0),
n_real_glues: Cell::new(0),
Expand Down Expand Up @@ -399,8 +393,6 @@ impl<'tcx> LocalCrateContext<'tcx> {
needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()),
fn_pointer_shims: RefCell::new(FnvHashMap()),
drop_glues: RefCell::new(FnvHashMap()),
tydescs: RefCell::new(FnvHashMap()),
finished_tydescs: Cell::new(false),
external: RefCell::new(DefIdMap()),
external_srcs: RefCell::new(NodeMap()),
monomorphized: RefCell::new(FnvHashMap()),
Expand Down Expand Up @@ -442,8 +434,6 @@ impl<'tcx> LocalCrateContext<'tcx> {
str_slice_ty.set_struct_body(&[Type::i8p(&ccx), ccx.int_type()], false);
ccx.tn().associate_type("str_slice", &str_slice_ty);

ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty));

if ccx.sess().count_llvm_insns() {
base::init_insn_ctxt()
}
Expand Down Expand Up @@ -519,10 +509,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
self.local.builder.b
}

pub fn tydesc_type(&self) -> Type {
self.local.tn.find_type("tydesc").unwrap()
}

pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef {
if let Some(v) = self.intrinsics().borrow().get(key).cloned() {
return v;
Expand Down Expand Up @@ -590,14 +576,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
&self.local.drop_glues
}

pub fn tydescs<'a>(&'a self) -> &'a RefCell<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>> {
&self.local.tydescs
}

pub fn finished_tydescs<'a>(&'a self) -> &'a Cell<bool> {
&self.local.finished_tydescs
}

pub fn external<'a>(&'a self) -> &'a RefCell<DefIdMap<Option<ast::NodeId>>> {
&self.local.external
}
Expand Down

0 comments on commit e256b7f

Please sign in to comment.