mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 14:57:14 +00:00
rustc: Associate type descriptors with allocas as metadata
This commit is contained in:
parent
4b22243416
commit
5079f51386
73
src/comp/middle/gc.rs
Normal file
73
src/comp/middle/gc.rs
Normal file
@ -0,0 +1,73 @@
|
||||
// Routines useful for garbage collection.
|
||||
|
||||
import lib::llvm::llvm::ValueRef;
|
||||
import middle::trans::get_tydesc;
|
||||
import middle::trans_common::*;
|
||||
import middle::ty;
|
||||
import std::option::none;
|
||||
import std::ptr;
|
||||
import std::str;
|
||||
import std::unsafe;
|
||||
|
||||
import lll = lib::llvm::llvm;
|
||||
|
||||
fn add_gc_root(cx: &@block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
||||
let bcx = cx;
|
||||
if !type_is_gc_relevant(bcx_tcx(cx), ty) { ret bcx; }
|
||||
|
||||
let md_kind_name = "rusttydesc";
|
||||
let md_kind = lll::LLVMGetMDKindID(str::buf(md_kind_name),
|
||||
str::byte_len(md_kind_name));
|
||||
|
||||
let ti = none;
|
||||
let r = get_tydesc(bcx, ty, false, ti);
|
||||
bcx = r.bcx;
|
||||
let lltydesc = r.val;
|
||||
|
||||
let llmdnode =
|
||||
lll::LLVMMDNode(unsafe::reinterpret_cast(ptr::addr_of(lltydesc)), 1u);
|
||||
lll::LLVMSetMetadata(llval, md_kind, llmdnode);
|
||||
ret bcx;
|
||||
}
|
||||
|
||||
fn type_is_gc_relevant(cx: &ty::ctxt, ty: &ty::t) -> bool {
|
||||
alt ty::struct(cx, ty) {
|
||||
ty::ty_nil. | ty::ty_bot. | ty::ty_bool. | ty::ty_int. |
|
||||
ty::ty_float. | ty::ty_uint. | ty::ty_machine(_) | ty::ty_char. |
|
||||
ty::ty_istr. | ty::ty_type. | ty::ty_native(_) | ty::ty_ptr(_) |
|
||||
ty::ty_port(_) | ty::ty_chan(_) | ty::ty_task. | ty::ty_type. |
|
||||
ty::ty_native(_) {
|
||||
ret false;
|
||||
}
|
||||
|
||||
ty::ty_rec(fields) {
|
||||
for f in fields {
|
||||
if type_is_gc_relevant(cx, f.mt.ty) { ret true; }
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
|
||||
ty::ty_tag(did, tps) {
|
||||
let variants = ty::tag_variants(cx, did);
|
||||
for variant in variants {
|
||||
for aty in variant.args {
|
||||
let arg_ty = ty::substitute_type_params(cx, tps, aty);
|
||||
if type_is_gc_relevant(cx, arg_ty) {
|
||||
ret true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
|
||||
ty::ty_ivec(tm) { ret type_is_gc_relevant(cx, tm.ty); }
|
||||
ty::ty_constr(sub, _) { ret type_is_gc_relevant(cx, sub); }
|
||||
|
||||
ty::ty_str. | ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_vec(_) |
|
||||
ty::ty_fn(_,_,_,_,_) | ty::ty_native_fn(_,_,_) | ty::ty_obj(_) |
|
||||
ty::ty_param(_,_) | ty::ty_res(_,_,_) { ret true; }
|
||||
|
||||
ty::ty_var(_) { fail "ty_var in type_is_gc_relevant"; }
|
||||
}
|
||||
}
|
||||
|
@ -281,12 +281,10 @@ fn shape_of(ccx : &@crate_ctxt, t : ty::t) -> [u8] {
|
||||
let s = ~[];
|
||||
|
||||
alt ty::struct(ccx.tcx, t) {
|
||||
ty::ty_nil. | ty::ty_bool. | ty::ty_machine(ast::ty_u8.) {
|
||||
ty::ty_nil. | ty::ty_bool. | ty::ty_machine(ast::ty_u8.) | ty::ty_bot. {
|
||||
s += ~[shape_u8];
|
||||
}
|
||||
|
||||
ty::ty_bot. { fail "bot ty in shape_of"; }
|
||||
|
||||
ty::ty_int. { s += ~[s_int(ccx.tcx)]; }
|
||||
ty::ty_float. { s += ~[s_float(ccx.tcx)]; }
|
||||
|
||||
@ -299,6 +297,8 @@ fn shape_of(ccx : &@crate_ctxt, t : ty::t) -> [u8] {
|
||||
ty::ty_machine(ast::ty_i16.) { s += ~[shape_i16]; }
|
||||
ty::ty_machine(ast::ty_u32.) | ty::ty_char. { s += ~[shape_u32]; }
|
||||
ty::ty_machine(ast::ty_i32.) { s += ~[shape_i32]; }
|
||||
ty::ty_machine(ast::ty_u64.) { s += ~[shape_u64]; }
|
||||
ty::ty_machine(ast::ty_i64.) { s += ~[shape_i64]; }
|
||||
|
||||
ty::ty_str. { s += ~[shape_evec, 1u8, 1u8, 0u8, shape_u8]; }
|
||||
ty::ty_istr. { s += ~[shape_ivec, 1u8, 1u8, 0u8, shape_u8]; }
|
||||
|
@ -27,6 +27,7 @@ import syntax::ast;
|
||||
import driver::session;
|
||||
import middle::ty;
|
||||
import middle::freevars::*;
|
||||
import middle::gc;
|
||||
import back::link;
|
||||
import back::x86;
|
||||
import back::abi;
|
||||
@ -5634,17 +5635,20 @@ fn lldynamicallocas_block_ctxt(fcx: &@fn_ctxt) -> @block_ctxt {
|
||||
|
||||
|
||||
fn alloc_ty(cx: &@block_ctxt, t: &ty::t) -> result {
|
||||
let bcx = cx;
|
||||
let val = C_int(0);
|
||||
if ty::type_has_dynamic_size(bcx_tcx(cx), t) {
|
||||
if ty::type_has_dynamic_size(bcx_tcx(bcx), t) {
|
||||
// NB: we have to run this particular 'size_of' in a
|
||||
// block_ctxt built on the llderivedtydescs block for the fn,
|
||||
// so that the size dominates the array_alloca that
|
||||
// comes next.
|
||||
|
||||
let n = size_of(llderivedtydescs_block_ctxt(cx.fcx), t);
|
||||
cx.fcx.llderivedtydescs = n.bcx.llbb;
|
||||
val = array_alloca(cx, T_i8(), n.val);
|
||||
} else { val = alloca(cx, type_of(bcx_ccx(cx), cx.sp, t)); }
|
||||
let n = size_of(llderivedtydescs_block_ctxt(bcx.fcx), t);
|
||||
bcx.fcx.llderivedtydescs = n.bcx.llbb;
|
||||
val = array_alloca(bcx, T_i8(), n.val);
|
||||
} else {
|
||||
val = alloca(bcx, type_of(bcx_ccx(cx), cx.sp, t));
|
||||
}
|
||||
// NB: since we've pushed all size calculations in this
|
||||
// function up to the alloca block, we actually return the
|
||||
// block passed into us unmodified; it doesn't really
|
||||
@ -5652,6 +5656,8 @@ fn alloc_ty(cx: &@block_ctxt, t: &ty::t) -> result {
|
||||
// past caller conventions and may well make sense again,
|
||||
// so we leave it as-is.
|
||||
|
||||
bcx = gc::add_gc_root(bcx, val, t);
|
||||
|
||||
ret rslt(cx, val);
|
||||
}
|
||||
|
||||
@ -6756,9 +6762,6 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap[str, ValueRef] {
|
||||
let T_memset64_args: [TypeRef] =
|
||||
~[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()];
|
||||
let T_trap_args: [TypeRef] = ~[];
|
||||
let gcroot =
|
||||
decl_cdecl_fn(llmod, "llvm.gcroot",
|
||||
T_fn(~[T_ptr(T_ptr(T_i8())), T_ptr(T_i8())], T_void()));
|
||||
let gcread =
|
||||
decl_cdecl_fn(llmod, "llvm.gcread",
|
||||
T_fn(~[T_ptr(T_i8()), T_ptr(T_ptr(T_i8()))], T_void()));
|
||||
@ -6776,7 +6779,6 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap[str, ValueRef] {
|
||||
T_fn(T_memset64_args, T_void()));
|
||||
let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, T_void()));
|
||||
let intrinsics = new_str_hash[ValueRef]();
|
||||
intrinsics.insert("llvm.gcroot", gcroot);
|
||||
intrinsics.insert("llvm.gcread", gcread);
|
||||
intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32);
|
||||
intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64);
|
||||
|
@ -31,6 +31,7 @@ mod middle {
|
||||
mod kind;
|
||||
mod freevars;
|
||||
mod shape;
|
||||
mod gc;
|
||||
|
||||
mod tstate {
|
||||
mod ck;
|
||||
|
Loading…
Reference in New Issue
Block a user