rustc: Make unique boxes self-describing
This commit is contained in:
parent
429f7e9e08
commit
654f7e3086
@ -117,7 +117,9 @@ class irc : public shape::data<irc,shape::ptr> {
|
||||
}
|
||||
|
||||
void walk_uniq2() {
|
||||
shape::data<irc,shape::ptr>::walk_uniq_contents1();
|
||||
rust_opaque_box *box = *(rust_opaque_box**)dp;
|
||||
if (box)
|
||||
shape::data<irc,shape::ptr>::walk_uniq_contents1();
|
||||
}
|
||||
|
||||
void walk_rptr2() {
|
||||
@ -373,7 +375,9 @@ class mark : public shape::data<mark,shape::ptr> {
|
||||
}
|
||||
|
||||
void walk_uniq2() {
|
||||
shape::data<mark,shape::ptr>::walk_uniq_contents1();
|
||||
rust_opaque_box *box = *(rust_opaque_box**)dp;
|
||||
if (box)
|
||||
shape::data<mark,shape::ptr>::walk_uniq_contents1();
|
||||
}
|
||||
|
||||
void walk_rptr2() {
|
||||
|
@ -783,6 +783,11 @@ public:
|
||||
return box->td;
|
||||
}
|
||||
|
||||
inline const type_desc *uniq_body_td() const {
|
||||
rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p);
|
||||
return box->td;
|
||||
}
|
||||
|
||||
inline ptr box_body() const {
|
||||
rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p);
|
||||
return make((uint8_t*)::box_body(box));
|
||||
@ -881,6 +886,11 @@ public:
|
||||
return box_fst->td;
|
||||
}
|
||||
|
||||
inline const type_desc *uniq_body_td() const {
|
||||
rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst);
|
||||
return box_fst->td;
|
||||
}
|
||||
|
||||
inline ptr_pair box_body() const {
|
||||
rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst);
|
||||
rust_opaque_box *box_snd = *reinterpret_cast<rust_opaque_box**>(snd);
|
||||
@ -1067,10 +1077,16 @@ data<T,U>::walk_box_contents1() {
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_uniq_contents1() {
|
||||
typename U::template data<uint8_t *>::t box_ptr = bump_dp<uint8_t *>(dp);
|
||||
U data_ptr(box_ptr);
|
||||
T sub(*static_cast<T *>(this), data_ptr);
|
||||
static_cast<T *>(this)->walk_uniq_contents2(sub);
|
||||
const type_desc *body_td = dp.uniq_body_td();
|
||||
if (body_td) {
|
||||
U body_dp(dp.box_body());
|
||||
arena arena;
|
||||
type_param *params = type_param::from_tydesc(body_td, arena);
|
||||
T sub(*static_cast<T *>(this), body_td->shape, params,
|
||||
body_td->shape_tables, body_dp);
|
||||
sub.align = true;
|
||||
static_cast<T *>(this)->walk_uniq_contents2(sub);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
|
@ -471,7 +471,8 @@ fn compile_submatch(bcx: block, m: match, vals: [ValueRef],
|
||||
}
|
||||
|
||||
if any_uniq_pat(m, col) {
|
||||
let unboxed = Load(bcx, val);
|
||||
let box = Load(bcx, val);
|
||||
let unboxed = GEPi(bcx, box, [0u, abi::box_field_body]);
|
||||
compile_submatch(bcx, enter_uniq(dm, m, col, val),
|
||||
[unboxed] + vals_left, chk, exits);
|
||||
ret;
|
||||
@ -762,8 +763,10 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
|
||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
||||
}
|
||||
ast::pat_uniq(inner) {
|
||||
let val = Load(bcx, val);
|
||||
bcx = bind_irrefutable_pat(bcx, inner, val, true);
|
||||
let box = Load(bcx, val);
|
||||
let unboxed =
|
||||
GEPi(bcx, box, [0u, abi::box_field_body]);
|
||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
||||
}
|
||||
ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) { }
|
||||
}
|
||||
|
@ -243,6 +243,13 @@ fn trans_shared_free(cx: block, v: ValueRef) -> block {
|
||||
ret cx;
|
||||
}
|
||||
|
||||
fn trans_unique_free(cx: block, v: ValueRef) -> block {
|
||||
let _icx = cx.insn_ctxt("trans_shared_free");
|
||||
Call(cx, cx.ccx().upcalls.exchange_free,
|
||||
[PointerCast(cx, v, T_ptr(T_i8()))]);
|
||||
ret cx;
|
||||
}
|
||||
|
||||
fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
|
||||
let _icx = cx.insn_ctxt("umax");
|
||||
let cond = ICmp(cx, lib::llvm::IntULT, a, b);
|
||||
@ -1780,7 +1787,7 @@ fn autoderef(cx: block, e_id: ast::node_id,
|
||||
v1 = PointerCast(cx, body, T_ptr(llty));
|
||||
}
|
||||
ty::ty_uniq(_) {
|
||||
let derefed = uniq::autoderef(v1, t1);
|
||||
let derefed = uniq::autoderef(cx, v1, t1);
|
||||
t1 = derefed.t;
|
||||
v1 = derefed.v;
|
||||
}
|
||||
@ -2662,6 +2669,9 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
|
||||
let non_gc_val = non_gc_box_cast(sub.bcx, sub.val, t);
|
||||
GEPi(sub.bcx, non_gc_val, [0u, abi::box_field_body])
|
||||
}
|
||||
ty::ty_uniq(_) {
|
||||
GEPi(sub.bcx, sub.val, [0u, abi::box_field_body])
|
||||
}
|
||||
ty::ty_res(_, _, _) {
|
||||
GEPi(sub.bcx, sub.val, [0u, 1u])
|
||||
}
|
||||
@ -2670,7 +2680,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
|
||||
let ellty = T_ptr(type_of(ccx, ety));
|
||||
PointerCast(sub.bcx, sub.val, ellty)
|
||||
}
|
||||
ty::ty_ptr(_) | ty::ty_uniq(_) | ty::ty_rptr(_,_) { sub.val }
|
||||
ty::ty_ptr(_) | ty::ty_rptr(_,_) { sub.val }
|
||||
};
|
||||
ret lval_owned(sub.bcx, val);
|
||||
}
|
||||
@ -2946,7 +2956,15 @@ fn adapt_borrowed_value(lv: lval_result, _arg: ty::arg,
|
||||
}
|
||||
|
||||
ty::ty_uniq(_) {
|
||||
ret lv; // no change needed at runtime (I think)
|
||||
let box_ptr = {
|
||||
alt lv.kind {
|
||||
temporary { lv.val }
|
||||
owned { Load(bcx, lv.val) }
|
||||
owned_imm { lv.val }
|
||||
}
|
||||
};
|
||||
let body_ptr = GEPi(bcx, box_ptr, [0u, abi::box_field_body]);
|
||||
ret lval_temp(bcx, body_ptr);
|
||||
}
|
||||
|
||||
ty::ty_str | ty::ty_vec(_) |
|
||||
|
@ -686,6 +686,15 @@ fn T_opaque_box_ptr(cx: @crate_ctxt) -> TypeRef {
|
||||
ret T_box_ptr(T_opaque_box(cx));
|
||||
}
|
||||
|
||||
fn T_unique(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
|
||||
ret T_struct(T_box_header_fields(cx) + [t]);
|
||||
}
|
||||
|
||||
fn T_unique_ptr(t: TypeRef) -> TypeRef {
|
||||
const unique_addrspace: uint = 0u;
|
||||
ret llvm::LLVMPointerType(t, unique_addrspace as c_uint);
|
||||
}
|
||||
|
||||
fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef {
|
||||
ret T_struct([cx.int_type]); // Refcount
|
||||
|
||||
|
@ -91,7 +91,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
ty::ty_evec(mt, ty::vstore_box) |
|
||||
ty::ty_box(mt) { T_box_ptr(T_box(cx, type_of(cx, mt.ty))) }
|
||||
ty::ty_opaque_box { T_box_ptr(T_box(cx, T_i8())) }
|
||||
ty::ty_uniq(mt) { T_ptr(type_of(cx, mt.ty)) }
|
||||
ty::ty_uniq(mt) { T_unique_ptr(T_unique(cx, type_of(cx, mt.ty))) }
|
||||
ty::ty_evec(mt, ty::vstore_uniq) |
|
||||
ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) }
|
||||
ty::ty_ptr(mt) { T_ptr(type_of(cx, mt.ty)) }
|
||||
|
@ -11,11 +11,12 @@ fn trans_uniq(bcx: block, contents: @ast::expr,
|
||||
node_id: ast::node_id, dest: dest) -> block {
|
||||
let _icx = bcx.insn_ctxt("uniq::trans_uniq");
|
||||
let uniq_ty = node_id_type(bcx, node_id);
|
||||
let llptr = alloc_uniq(bcx, uniq_ty);
|
||||
add_clean_free(bcx, llptr, true);
|
||||
let bcx = trans_expr_save_in(bcx, contents, llptr);
|
||||
revoke_clean(bcx, llptr);
|
||||
ret store_in_dest(bcx, llptr, dest);
|
||||
let contents_ty = content_ty(uniq_ty);
|
||||
let {box, body} = malloc_unique(bcx, contents_ty);
|
||||
add_clean_free(bcx, box, true);
|
||||
let bcx = trans_expr_save_in(bcx, contents, body);
|
||||
revoke_clean(bcx, box);
|
||||
ret store_in_dest(bcx, box, dest);
|
||||
}
|
||||
|
||||
fn alloc_uniq(bcx: block, uniq_ty: ty::t) -> ValueRef {
|
||||
@ -31,8 +32,10 @@ fn make_free_glue(bcx: block, vptr: ValueRef, t: ty::t)
|
||||
-> block {
|
||||
let _icx = bcx.insn_ctxt("uniq::make_free_glue");
|
||||
with_cond(bcx, IsNotNull(bcx, vptr)) {|bcx|
|
||||
let bcx = drop_ty(bcx, vptr, content_ty(t));
|
||||
trans_shared_free(bcx, vptr)
|
||||
let content_ty = content_ty(t);
|
||||
let body_ptr = opaque_box_body(bcx, content_ty, vptr);
|
||||
let bcx = drop_ty(bcx, body_ptr, content_ty);
|
||||
trans_unique_free(bcx, vptr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,18 +46,31 @@ fn content_ty(t: ty::t) -> ty::t {
|
||||
}
|
||||
}
|
||||
|
||||
fn autoderef(v: ValueRef, t: ty::t) -> {v: ValueRef, t: ty::t} {
|
||||
fn autoderef(bcx: block, v: ValueRef, t: ty::t) -> {v: ValueRef, t: ty::t} {
|
||||
let content_ty = content_ty(t);
|
||||
let v = opaque_box_body(bcx, content_ty, v);
|
||||
ret {v: v, t: content_ty};
|
||||
}
|
||||
|
||||
fn duplicate(bcx: block, v: ValueRef, t: ty::t) -> result {
|
||||
let _icx = bcx.insn_ctxt("uniq::duplicate");
|
||||
let content_ty = content_ty(t);
|
||||
let llptr = alloc_uniq(bcx, t);
|
||||
let {box: dst_box, body: dst_body} = malloc_unique(bcx, content_ty);
|
||||
|
||||
let src = load_if_immediate(bcx, v, content_ty);
|
||||
let dst = llptr;
|
||||
let bcx = copy_val(bcx, INIT, dst, src, content_ty);
|
||||
ret rslt(bcx, dst);
|
||||
let src_box = v;
|
||||
let src_body = opaque_box_body(bcx, content_ty, src_box);
|
||||
let src_body = load_if_immediate(bcx, src_body, content_ty);
|
||||
#debug("ST: %?", val_str(bcx.ccx().tn, src_body));
|
||||
#debug("DT: %?", val_str(bcx.ccx().tn, dst_body));
|
||||
let bcx = copy_val(bcx, INIT, dst_body, src_body, content_ty);
|
||||
|
||||
let src_tydesc_ptr = GEPi(bcx, src_box,
|
||||
[0u, back::abi::box_field_tydesc]);
|
||||
let dst_tydesc_ptr = GEPi(bcx, dst_box,
|
||||
[0u, back::abi::box_field_tydesc]);
|
||||
|
||||
let td = Load(bcx, src_tydesc_ptr);
|
||||
Store(bcx, td, dst_tydesc_ptr);
|
||||
|
||||
ret rslt(bcx, dst_box);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user