mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-25 14:13:38 +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 = ~[];
|
let s = ~[];
|
||||||
|
|
||||||
alt ty::struct(ccx.tcx, t) {
|
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];
|
s += ~[shape_u8];
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_bot. { fail "bot ty in shape_of"; }
|
|
||||||
|
|
||||||
ty::ty_int. { s += ~[s_int(ccx.tcx)]; }
|
ty::ty_int. { s += ~[s_int(ccx.tcx)]; }
|
||||||
ty::ty_float. { s += ~[s_float(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_i16.) { s += ~[shape_i16]; }
|
||||||
ty::ty_machine(ast::ty_u32.) | ty::ty_char. { s += ~[shape_u32]; }
|
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_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_str. { s += ~[shape_evec, 1u8, 1u8, 0u8, shape_u8]; }
|
||||||
ty::ty_istr. { s += ~[shape_ivec, 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 driver::session;
|
||||||
import middle::ty;
|
import middle::ty;
|
||||||
import middle::freevars::*;
|
import middle::freevars::*;
|
||||||
|
import middle::gc;
|
||||||
import back::link;
|
import back::link;
|
||||||
import back::x86;
|
import back::x86;
|
||||||
import back::abi;
|
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 {
|
fn alloc_ty(cx: &@block_ctxt, t: &ty::t) -> result {
|
||||||
|
let bcx = cx;
|
||||||
let val = C_int(0);
|
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
|
// NB: we have to run this particular 'size_of' in a
|
||||||
// block_ctxt built on the llderivedtydescs block for the fn,
|
// block_ctxt built on the llderivedtydescs block for the fn,
|
||||||
// so that the size dominates the array_alloca that
|
// so that the size dominates the array_alloca that
|
||||||
// comes next.
|
// comes next.
|
||||||
|
|
||||||
let n = size_of(llderivedtydescs_block_ctxt(cx.fcx), t);
|
let n = size_of(llderivedtydescs_block_ctxt(bcx.fcx), t);
|
||||||
cx.fcx.llderivedtydescs = n.bcx.llbb;
|
bcx.fcx.llderivedtydescs = n.bcx.llbb;
|
||||||
val = array_alloca(cx, T_i8(), n.val);
|
val = array_alloca(bcx, T_i8(), n.val);
|
||||||
} else { val = alloca(cx, type_of(bcx_ccx(cx), cx.sp, t)); }
|
} else {
|
||||||
|
val = alloca(bcx, type_of(bcx_ccx(cx), cx.sp, t));
|
||||||
|
}
|
||||||
// NB: since we've pushed all size calculations in this
|
// NB: since we've pushed all size calculations in this
|
||||||
// function up to the alloca block, we actually return the
|
// function up to the alloca block, we actually return the
|
||||||
// block passed into us unmodified; it doesn't really
|
// 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,
|
// past caller conventions and may well make sense again,
|
||||||
// so we leave it as-is.
|
// so we leave it as-is.
|
||||||
|
|
||||||
|
bcx = gc::add_gc_root(bcx, val, t);
|
||||||
|
|
||||||
ret rslt(cx, val);
|
ret rslt(cx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6756,9 +6762,6 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap[str, ValueRef] {
|
|||||||
let T_memset64_args: [TypeRef] =
|
let T_memset64_args: [TypeRef] =
|
||||||
~[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()];
|
~[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()];
|
||||||
let T_trap_args: [TypeRef] = ~[];
|
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 =
|
let gcread =
|
||||||
decl_cdecl_fn(llmod, "llvm.gcread",
|
decl_cdecl_fn(llmod, "llvm.gcread",
|
||||||
T_fn(~[T_ptr(T_i8()), T_ptr(T_ptr(T_i8()))], T_void()));
|
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()));
|
T_fn(T_memset64_args, T_void()));
|
||||||
let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, T_void()));
|
let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, T_void()));
|
||||||
let intrinsics = new_str_hash[ValueRef]();
|
let intrinsics = new_str_hash[ValueRef]();
|
||||||
intrinsics.insert("llvm.gcroot", gcroot);
|
|
||||||
intrinsics.insert("llvm.gcread", gcread);
|
intrinsics.insert("llvm.gcread", gcread);
|
||||||
intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32);
|
intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32);
|
||||||
intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64);
|
intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64);
|
||||||
|
@ -31,6 +31,7 @@ mod middle {
|
|||||||
mod kind;
|
mod kind;
|
||||||
mod freevars;
|
mod freevars;
|
||||||
mod shape;
|
mod shape;
|
||||||
|
mod gc;
|
||||||
|
|
||||||
mod tstate {
|
mod tstate {
|
||||||
mod ck;
|
mod ck;
|
||||||
|
Loading…
Reference in New Issue
Block a user