rustc: Stub stack map generation machinery
This commit is contained in:
parent
51af43f192
commit
117d21d6c2
5 changed files with 124 additions and 46 deletions
|
@ -1,32 +1,96 @@
|
||||||
// Routines useful for garbage collection.
|
// Routines useful for garbage collection.
|
||||||
|
|
||||||
|
import lib::llvm::False;
|
||||||
|
import lib::llvm::True;
|
||||||
import lib::llvm::llvm::ValueRef;
|
import lib::llvm::llvm::ValueRef;
|
||||||
import middle::trans::get_tydesc;
|
import middle::trans::get_tydesc;
|
||||||
import middle::trans_common::*;
|
import middle::trans_common::*;
|
||||||
import middle::ty;
|
import middle::ty;
|
||||||
import std::option::none;
|
import std::option::none;
|
||||||
|
import std::option::some;
|
||||||
import std::ptr;
|
import std::ptr;
|
||||||
import std::str;
|
import std::str;
|
||||||
import std::unsafe;
|
import std::unsafe;
|
||||||
|
import std::vec;
|
||||||
|
|
||||||
import lll = lib::llvm::llvm;
|
import lll = lib::llvm::llvm;
|
||||||
|
|
||||||
|
type ctxt = @{ mutable next_tydesc_num: uint };
|
||||||
|
|
||||||
|
fn mk_ctxt() -> ctxt {
|
||||||
|
ret @{ mutable next_tydesc_num: 0u };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_global(ccx: &@crate_ctxt, llval: ValueRef, name: str) -> ValueRef {
|
||||||
|
let llglobal = lll::LLVMAddGlobal(ccx.llmod, val_ty(llval),
|
||||||
|
str::buf(name));
|
||||||
|
lll::LLVMSetInitializer(llglobal, llval);
|
||||||
|
lll::LLVMSetGlobalConstant(llglobal, True);
|
||||||
|
ret llglobal;
|
||||||
|
}
|
||||||
|
|
||||||
fn add_gc_root(cx: &@block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
fn add_gc_root(cx: &@block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
||||||
let bcx = cx;
|
let bcx = cx;
|
||||||
if !type_is_gc_relevant(bcx_tcx(cx), ty) { ret bcx; }
|
if !type_is_gc_relevant(bcx_tcx(cx), ty) ||
|
||||||
|
ty::type_has_dynamic_size(bcx_tcx(cx), ty) {
|
||||||
|
ret bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let md_kind_name = "rusttydesc";
|
let gc_cx = bcx_ccx(cx).gc_cx;
|
||||||
let md_kind = lll::LLVMGetMDKindID(str::buf(md_kind_name),
|
|
||||||
str::byte_len(md_kind_name));
|
|
||||||
|
|
||||||
let ti = none;
|
let ti = none;
|
||||||
let r = get_tydesc(bcx, ty, false, ti);
|
let td_r = get_tydesc(bcx, ty, false, ti);
|
||||||
bcx = r.bcx;
|
bcx = td_r.result.bcx;
|
||||||
let lltydesc = r.val;
|
let lltydesc = td_r.result.val;
|
||||||
|
|
||||||
|
let gcroot = bcx_ccx(bcx).intrinsics.get("llvm.gcroot");
|
||||||
|
let llvalptr = bcx.build.PointerCast(llval, T_ptr(T_ptr(T_i8())));
|
||||||
|
|
||||||
|
alt td_r.kind {
|
||||||
|
tk_derived. {
|
||||||
|
// It's a derived type descriptor. First, spill it.
|
||||||
|
let lltydescptr = trans::alloca(bcx, val_ty(lltydesc));
|
||||||
|
bcx.build.Store(lltydesc, lltydescptr);
|
||||||
|
|
||||||
|
let number = gc_cx.next_tydesc_num;
|
||||||
|
gc_cx.next_tydesc_num += 1u;
|
||||||
|
|
||||||
|
let lldestindex = add_global(bcx_ccx(bcx),
|
||||||
|
C_struct(~[C_int(0),
|
||||||
|
C_uint(number)]),
|
||||||
|
"rust_gc_tydesc_dest_index");
|
||||||
|
let llsrcindex = add_global(bcx_ccx(bcx),
|
||||||
|
C_struct(~[C_int(1), C_uint(number)]),
|
||||||
|
"rust_gc_tydesc_src_index");
|
||||||
|
|
||||||
|
lldestindex = lll::LLVMConstPointerCast(lldestindex,
|
||||||
|
T_ptr(T_i8()));
|
||||||
|
llsrcindex = lll::LLVMConstPointerCast(llsrcindex,
|
||||||
|
T_ptr(T_i8()));
|
||||||
|
|
||||||
|
lltydescptr = bcx.build.PointerCast(lltydescptr,
|
||||||
|
T_ptr(T_ptr(T_i8())));
|
||||||
|
|
||||||
|
bcx.build.Call(gcroot, ~[ lltydescptr, lldestindex ]);
|
||||||
|
bcx.build.Call(gcroot, ~[ llvalptr, llsrcindex ]);
|
||||||
|
}
|
||||||
|
tk_param. {
|
||||||
|
bcx_tcx(cx).sess.bug("we should never be trying to root values " +
|
||||||
|
"of a type parameter");
|
||||||
|
}
|
||||||
|
tk_static. {
|
||||||
|
// Static type descriptor.
|
||||||
|
|
||||||
|
let llstaticgcmeta = add_global(bcx_ccx(bcx),
|
||||||
|
C_struct(~[C_int(2), lltydesc]),
|
||||||
|
"rust_gc_tydesc_static_gc_meta");
|
||||||
|
let llstaticgcmetaptr = lll::LLVMConstPointerCast(llstaticgcmeta,
|
||||||
|
T_ptr(T_i8()));
|
||||||
|
|
||||||
|
bcx.build.Call(gcroot, ~[ llvalptr, llstaticgcmetaptr ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let llmdnode =
|
|
||||||
lll::LLVMMDNode(unsafe::reinterpret_cast(ptr::addr_of(lltydesc)), 1u);
|
|
||||||
lll::LLVMSetMetadata(llval, md_kind, llmdnode);
|
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +121,7 @@ fn type_is_gc_relevant(cx: &ty::ctxt, ty: &ty::t) -> bool {
|
||||||
for variant in variants {
|
for variant in variants {
|
||||||
for aty in variant.args {
|
for aty in variant.args {
|
||||||
let arg_ty = ty::substitute_type_params(cx, tps, aty);
|
let arg_ty = ty::substitute_type_params(cx, tps, aty);
|
||||||
if type_is_gc_relevant(cx, arg_ty) {
|
if type_is_gc_relevant(cx, arg_ty) { ret true; }
|
||||||
ret true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret false;
|
ret false;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import std::option::some;
|
||||||
import std::option::none;
|
import std::option::none;
|
||||||
import std::fs;
|
import std::fs;
|
||||||
import std::time;
|
import std::time;
|
||||||
|
import std::vec;
|
||||||
import syntax::ast;
|
import syntax::ast;
|
||||||
import driver::session;
|
import driver::session;
|
||||||
import middle::ty;
|
import middle::ty;
|
||||||
|
@ -901,7 +902,7 @@ fn trans_malloc_boxed(cx: &@block_ctxt, t: ty::t) ->
|
||||||
fn field_of_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool, field: int) ->
|
fn field_of_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool, field: int) ->
|
||||||
result {
|
result {
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let tydesc = get_tydesc(cx, t, escapes, ti);
|
let tydesc = get_tydesc(cx, t, escapes, ti).result;
|
||||||
ret rslt(tydesc.bcx,
|
ret rslt(tydesc.bcx,
|
||||||
tydesc.bcx.build.GEP(tydesc.val, ~[C_int(0), C_int(field)]));
|
tydesc.bcx.build.GEP(tydesc.val, ~[C_int(0), C_int(field)]));
|
||||||
}
|
}
|
||||||
|
@ -1028,16 +1029,19 @@ fn get_derived_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool,
|
||||||
ret rslt(cx, v);
|
ret rslt(cx, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type get_tydesc_result = { kind: tydesc_kind, result: result };
|
||||||
|
|
||||||
fn get_tydesc(cx: &@block_ctxt, orig_t: &ty::t, escapes: bool,
|
fn get_tydesc(cx: &@block_ctxt, orig_t: &ty::t, escapes: bool,
|
||||||
static_ti: &mutable option::t<@tydesc_info>) -> result {
|
static_ti: &mutable option::t<@tydesc_info>)
|
||||||
|
-> get_tydesc_result {
|
||||||
|
|
||||||
let t = ty::strip_cname(bcx_tcx(cx), orig_t);
|
let t = ty::strip_cname(bcx_tcx(cx), orig_t);
|
||||||
|
|
||||||
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
||||||
alt ty::type_param(bcx_tcx(cx), t) {
|
alt ty::type_param(bcx_tcx(cx), t) {
|
||||||
some(id) {
|
some(id) {
|
||||||
if id < std::vec::len(cx.fcx.lltydescs) {
|
if id < vec::len(cx.fcx.lltydescs) {
|
||||||
ret rslt(cx, cx.fcx.lltydescs.(id));
|
ret { kind: tk_param, result: rslt(cx, cx.fcx.lltydescs.(id)) };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bcx_tcx(cx).sess.span_bug(cx.sp, "Unbound typaram in get_tydesc: "
|
bcx_tcx(cx).sess.span_bug(cx.sp, "Unbound typaram in get_tydesc: "
|
||||||
|
@ -1050,13 +1054,16 @@ fn get_tydesc(cx: &@block_ctxt, orig_t: &ty::t, escapes: bool,
|
||||||
|
|
||||||
// Does it contain a type param? If so, generate a derived tydesc.
|
// Does it contain a type param? If so, generate a derived tydesc.
|
||||||
if ty::type_contains_params(bcx_tcx(cx), t) {
|
if ty::type_contains_params(bcx_tcx(cx), t) {
|
||||||
ret get_derived_tydesc(cx, t, escapes, static_ti);
|
ret {
|
||||||
|
kind: tk_derived,
|
||||||
|
result: get_derived_tydesc(cx, t, escapes, static_ti)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, generate a tydesc if necessary, and return it.
|
// Otherwise, generate a tydesc if necessary, and return it.
|
||||||
let info = get_static_tydesc(cx, t, ~[]);
|
let info = get_static_tydesc(cx, t, ~[]);
|
||||||
static_ti = some::<@tydesc_info>(info);
|
static_ti = some::<@tydesc_info>(info);
|
||||||
ret rslt(cx, info.tydesc);
|
ret { kind: tk_static, result: rslt(cx, info.tydesc) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_static_tydesc(cx: &@block_ctxt, orig_t: &ty::t, ty_params: &[uint]) ->
|
fn get_static_tydesc(cx: &@block_ctxt, orig_t: &ty::t, ty_params: &[uint]) ->
|
||||||
|
@ -1484,9 +1491,9 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: &ast::def_id,
|
||||||
cx.build.Load(cx.build.GEP(dtor_pair,
|
cx.build.Load(cx.build.GEP(dtor_pair,
|
||||||
~[C_int(0), C_int(abi::fn_field_box)]));
|
~[C_int(0), C_int(abi::fn_field_box)]));
|
||||||
let args = ~[cx.fcx.llretptr, cx.fcx.lltaskptr, dtor_env];
|
let args = ~[cx.fcx.llretptr, cx.fcx.lltaskptr, dtor_env];
|
||||||
for tp: ty::t in tps {
|
for tp: ty::t in tps {
|
||||||
let ti: option::t<@tydesc_info> = none;
|
let ti: option::t<@tydesc_info> = none;
|
||||||
let td = get_tydesc(cx, tp, false, ti);
|
let td = get_tydesc(cx, tp, false, ti).result;
|
||||||
args += ~[td.val];
|
args += ~[td.val];
|
||||||
cx = td.bcx;
|
cx = td.bcx;
|
||||||
}
|
}
|
||||||
|
@ -2130,7 +2137,7 @@ fn call_tydesc_glue_full(cx: &@block_ctxt, v: ValueRef, tydesc: ValueRef,
|
||||||
fn call_tydesc_glue(cx: &@block_ctxt, v: ValueRef, t: &ty::t, field: int) ->
|
fn call_tydesc_glue(cx: &@block_ctxt, v: ValueRef, t: &ty::t, field: int) ->
|
||||||
result {
|
result {
|
||||||
let ti: option::t<@tydesc_info> = none::<@tydesc_info>;
|
let ti: option::t<@tydesc_info> = none::<@tydesc_info>;
|
||||||
let td = get_tydesc(cx, t, false, ti);
|
let td = get_tydesc(cx, t, false, ti).result;
|
||||||
call_tydesc_glue_full(td.bcx, spill_if_immediate(td.bcx, v, t), td.val,
|
call_tydesc_glue_full(td.bcx, spill_if_immediate(td.bcx, v, t), td.val,
|
||||||
field, ti);
|
field, ti);
|
||||||
ret rslt(td.bcx, C_nil());
|
ret rslt(td.bcx, C_nil());
|
||||||
|
@ -2146,7 +2153,7 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t,
|
||||||
let llrawlhsptr = cx.build.BitCast(lllhs, T_ptr(T_i8()));
|
let llrawlhsptr = cx.build.BitCast(lllhs, T_ptr(T_i8()));
|
||||||
let llrawrhsptr = cx.build.BitCast(llrhs, T_ptr(T_i8()));
|
let llrawrhsptr = cx.build.BitCast(llrhs, T_ptr(T_i8()));
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let r = get_tydesc(cx, t, false, ti);
|
let r = get_tydesc(cx, t, false, ti).result;
|
||||||
lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, ti);
|
lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, ti);
|
||||||
let lltydesc = r.val;
|
let lltydesc = r.val;
|
||||||
let lltydescs =
|
let lltydescs =
|
||||||
|
@ -2561,10 +2568,10 @@ fn trans_vec_append(cx: &@block_ctxt, t: &ty::t, lhs: ValueRef, rhs: ValueRef)
|
||||||
}
|
}
|
||||||
let bcx = cx;
|
let bcx = cx;
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let llvec_tydesc = get_tydesc(bcx, t, false, ti);
|
let llvec_tydesc = get_tydesc(bcx, t, false, ti).result;
|
||||||
bcx = llvec_tydesc.bcx;
|
bcx = llvec_tydesc.bcx;
|
||||||
ti = none::<@tydesc_info>;
|
ti = none::<@tydesc_info>;
|
||||||
let llelt_tydesc = get_tydesc(bcx, elt_ty, false, ti);
|
let llelt_tydesc = get_tydesc(bcx, elt_ty, false, ti).result;
|
||||||
lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, ti);
|
lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, ti);
|
||||||
lazily_emit_tydesc_glue(cx, abi::tydesc_field_drop_glue, ti);
|
lazily_emit_tydesc_glue(cx, abi::tydesc_field_drop_glue, ti);
|
||||||
lazily_emit_tydesc_glue(cx, abi::tydesc_field_free_glue, ti);
|
lazily_emit_tydesc_glue(cx, abi::tydesc_field_free_glue, ti);
|
||||||
|
@ -2819,9 +2826,9 @@ mod ivec {
|
||||||
// FIXME (issue #511): This is needed to prevent a leak.
|
// FIXME (issue #511): This is needed to prevent a leak.
|
||||||
let no_tydesc_info = none;
|
let no_tydesc_info = none;
|
||||||
|
|
||||||
rs = get_tydesc(bcx, t, false, no_tydesc_info);
|
rs = get_tydesc(bcx, t, false, no_tydesc_info).result;
|
||||||
bcx = rs.bcx;
|
bcx = rs.bcx;
|
||||||
rs = get_tydesc(bcx, unit_ty, false, no_tydesc_info);
|
rs = get_tydesc(bcx, unit_ty, false, no_tydesc_info).result;
|
||||||
bcx = rs.bcx;
|
bcx = rs.bcx;
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_copy_glue, none);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_copy_glue, none);
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, none);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, none);
|
||||||
|
@ -3527,7 +3534,7 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
|
||||||
if copying {
|
if copying {
|
||||||
let bound_tydesc = GEPi(bcx, closure, ~[0, abi::closure_elt_tydesc]);
|
let bound_tydesc = GEPi(bcx, closure, ~[0, abi::closure_elt_tydesc]);
|
||||||
let ti = none;
|
let ti = none;
|
||||||
let bindings_tydesc = get_tydesc(bcx, bindings_ty, true, ti);
|
let bindings_tydesc = get_tydesc(bcx, bindings_ty, true, ti).result;
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
||||||
bcx = bindings_tydesc.bcx;
|
bcx = bindings_tydesc.bcx;
|
||||||
|
@ -3848,7 +3855,7 @@ fn lval_generic_fn(cx: &@block_ctxt, tpt: &ty::ty_param_kinds_and_ty,
|
||||||
// TODO: Doesn't always escape.
|
// TODO: Doesn't always escape.
|
||||||
|
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let td = get_tydesc(bcx, t, true, ti);
|
let td = get_tydesc(bcx, t, true, ti).result;
|
||||||
tis += ~[ti];
|
tis += ~[ti];
|
||||||
bcx = td.bcx;
|
bcx = td.bcx;
|
||||||
tydescs += ~[td.val];
|
tydescs += ~[td.val];
|
||||||
|
@ -5254,7 +5261,7 @@ fn trans_log(lvl: int, cx: &@block_ctxt, e: &@ast::expr) -> result {
|
||||||
let log_bcx = sub.bcx;
|
let log_bcx = sub.bcx;
|
||||||
|
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let r = get_tydesc(log_bcx, e_ty, false, ti);
|
let r = get_tydesc(log_bcx, e_ty, false, ti).result;
|
||||||
log_bcx = r.bcx;
|
log_bcx = r.bcx;
|
||||||
|
|
||||||
// Call the polymorphic log function.
|
// Call the polymorphic log function.
|
||||||
|
@ -6926,6 +6933,9 @@ 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()));
|
||||||
|
@ -6943,6 +6953,7 @@ 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);
|
||||||
|
@ -7142,7 +7153,8 @@ fn trans_crate(sess: &session::session, crate: &@ast::crate, tcx: &ty::ctxt,
|
||||||
rust_object_type: T_rust_object(),
|
rust_object_type: T_rust_object(),
|
||||||
tydesc_type: tydesc_type,
|
tydesc_type: tydesc_type,
|
||||||
task_type: task_type,
|
task_type: task_type,
|
||||||
shape_cx: shape::mk_ctxt(llmod)};
|
shape_cx: shape::mk_ctxt(llmod),
|
||||||
|
gc_cx: gc::mk_ctxt()};
|
||||||
let cx = new_local_ctxt(ccx);
|
let cx = new_local_ctxt(ccx);
|
||||||
collect_items(ccx, crate);
|
collect_items(ccx, crate);
|
||||||
collect_tag_ctors(ccx, crate);
|
collect_tag_ctors(ccx, crate);
|
||||||
|
|
|
@ -70,6 +70,12 @@ type derived_tydesc_info = {lltydesc: ValueRef, escapes: bool};
|
||||||
|
|
||||||
type glue_fns = {no_op_type_glue: ValueRef};
|
type glue_fns = {no_op_type_glue: ValueRef};
|
||||||
|
|
||||||
|
tag tydesc_kind {
|
||||||
|
tk_static; // Static (monomorphic) type descriptor.
|
||||||
|
tk_param; // Type parameter.
|
||||||
|
tk_derived; // Derived from a typaram or another derived tydesc.
|
||||||
|
}
|
||||||
|
|
||||||
type tydesc_info =
|
type tydesc_info =
|
||||||
{ty: ty::t,
|
{ty: ty::t,
|
||||||
tydesc: ValueRef,
|
tydesc: ValueRef,
|
||||||
|
@ -142,7 +148,8 @@ type crate_ctxt = {
|
||||||
rust_object_type: TypeRef,
|
rust_object_type: TypeRef,
|
||||||
tydesc_type: TypeRef,
|
tydesc_type: TypeRef,
|
||||||
task_type: TypeRef,
|
task_type: TypeRef,
|
||||||
shape_cx: shape::ctxt
|
shape_cx: shape::ctxt,
|
||||||
|
gc_cx: gc::ctxt
|
||||||
};
|
};
|
||||||
|
|
||||||
type local_ctxt =
|
type local_ctxt =
|
||||||
|
|
|
@ -133,7 +133,7 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
||||||
~[0, abi::obj_body_elt_tydesc]);
|
~[0, abi::obj_body_elt_tydesc]);
|
||||||
bcx = body_tydesc.bcx;
|
bcx = body_tydesc.bcx;
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let body_td = get_tydesc(bcx, body_ty, true, ti);
|
let body_td = get_tydesc(bcx, body_ty, true, ti).result;
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
||||||
bcx = body_td.bcx;
|
bcx = body_td.bcx;
|
||||||
|
@ -327,7 +327,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
||||||
~[0, abi::obj_body_elt_tydesc]);
|
~[0, abi::obj_body_elt_tydesc]);
|
||||||
bcx = body_tydesc.bcx;
|
bcx = body_tydesc.bcx;
|
||||||
let ti = none::<@tydesc_info>;
|
let ti = none::<@tydesc_info>;
|
||||||
let body_td = get_tydesc(bcx, body_ty, true, ti);
|
let body_td = get_tydesc(bcx, body_ty, true, ti).result;
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
||||||
bcx = body_td.bcx;
|
bcx = body_td.bcx;
|
||||||
|
|
|
@ -16,19 +16,16 @@
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
class RustGCStrategy : public GCStrategy {
|
||||||
class RustGCStrategy : public GCStrategy {
|
public:
|
||||||
public:
|
RustGCStrategy() {
|
||||||
RustGCStrategy();
|
NeededSafePoints = 1 << GC::PostCall;
|
||||||
};
|
UsesMetadata = true;
|
||||||
}
|
InitRoots = false; // LLVM crashes with this on due to bitcasts.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static GCRegistry::Add<RustGCStrategy>
|
static GCRegistry::Add<RustGCStrategy>
|
||||||
X("rust", "Rust GC");
|
RustGCStrategyRegistration("rust", "Rust GC");
|
||||||
|
|
||||||
RustGCStrategy::RustGCStrategy() {
|
|
||||||
NeededSafePoints = 1 << GC::PostCall;
|
|
||||||
UsesMetadata = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue