diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-24 20:30:20 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-24 20:30:20 +0200 |
| commit | fa97793139a6b055eb0fba91ef7d64f6a545ca99 (patch) | |
| tree | 1dec35c744ab29903926a7e2465f4415995a7161 /src/comp | |
| parent | 60547f6500b0bf726e675b058ad0bdfe21455c11 (diff) | |
| download | rust-fa97793139a6b055eb0fba91ef7d64f6a545ca99.tar.gz rust-fa97793139a6b055eb0fba91ef7d64f6a545ca99.zip | |
Revert "Back out copy-glue"
This reverts commit 629ee94a0b360e2df1a1bbf7bf61ef346adf36ad.
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/back/abi.rs | 2 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 85 | ||||
| -rw-r--r-- | src/comp/middle/trans_common.rs | 14 | ||||
| -rw-r--r-- | src/comp/middle/trans_ivec.rs | 1 | ||||
| -rw-r--r-- | src/comp/middle/ty.rs | 12 |
5 files changed, 108 insertions, 6 deletions
diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index 68ca5160e95..2e2bddba592 100644 --- a/src/comp/back/abi.rs +++ b/src/comp/back/abi.rs @@ -52,7 +52,7 @@ const tydesc_field_align: int = 2; const tydesc_field_take_glue: int = 3; const tydesc_field_drop_glue: int = 4; const tydesc_field_free_glue: int = 5; -const tydesc_field_unused: int = 6; +const tydesc_field_copy_glue: int = 6; const tydesc_field_sever_glue: int = 7; const tydesc_field_mark_glue: int = 8; const tydesc_field_is_stateful: int = 9; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 1f37f81e52e..7d41a1e6bd7 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1122,6 +1122,7 @@ fn declare_tydesc(cx: &@local_ctxt, sp: &span, t: ty::t, ty_params: &[uint]) mutable drop_glue: none::<ValueRef>, mutable free_glue: none::<ValueRef>, mutable cmp_glue: none::<ValueRef>, + mutable copy_glue: none::<ValueRef>, ty_params: ty_params}; log "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t); ret info; @@ -1215,6 +1216,7 @@ fn emit_tydescs(ccx: &@crate_ctxt) { for each pair: @{key: ty::t, val: @tydesc_info} in ccx.tydescs.items() { let glue_fn_ty = T_ptr(T_glue_fn(*ccx)); let cmp_fn_ty = T_ptr(T_cmp_glue_fn(*ccx)); + let copy_fn_ty = T_ptr(T_copy_glue_fn(*ccx)); let ti = pair.val; let take_glue = alt { ti.take_glue } { @@ -1236,6 +1238,11 @@ fn emit_tydescs(ccx: &@crate_ctxt) { none. { ccx.stats.n_null_glues += 1u; C_null(cmp_fn_ty) } some(v) { ccx.stats.n_real_glues += 1u; v } }; + let copy_glue = + alt { ti.copy_glue } { + none. { ccx.stats.n_null_glues += 1u; C_null(copy_fn_ty) } + some(v) { ccx.stats.n_real_glues += 1u; v } + }; let shape = shape::shape_of(ccx, pair.key); let shape_tables = @@ -1250,7 +1257,7 @@ fn emit_tydescs(ccx: &@crate_ctxt) { take_glue, // take_glue drop_glue, // drop_glue free_glue, // free_glue - C_null(T_ptr(T_i8())), // unused + copy_glue, // copy_glue C_null(glue_fn_ty), // sever_glue C_null(glue_fn_ty), // mark_glue C_null(glue_fn_ty), // is_stateful @@ -1267,6 +1274,14 @@ fn emit_tydescs(ccx: &@crate_ctxt) { } } +// NOTE this is currently just a complicated way to do memmove. I'm working on +// a representation of ivecs that will need pointers into itself, which must +// be adjusted when copying. Will flesh this out when the time comes. +fn make_copy_glue(cx: &@block_ctxt, src: ValueRef, dst: ValueRef, t: ty::t) { + let bcx = memmove_ty(cx, dst, src, t).bcx; + build_return(bcx); +} + fn make_take_glue(cx: &@block_ctxt, v: ValueRef, t: ty::t) { // NB: v is an *alias* of type t here, not a direct value. @@ -1988,6 +2003,7 @@ fn lazily_emit_all_tydesc_glue(cx: &@block_ctxt, lazily_emit_tydesc_glue(cx, abi::tydesc_field_drop_glue, static_ti); lazily_emit_tydesc_glue(cx, abi::tydesc_field_free_glue, static_ti); lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, static_ti); + lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, static_ti); } fn lazily_emit_all_generic_info_tydesc_glues(cx: &@block_ctxt, @@ -2067,6 +2083,20 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int, ty_to_str(bcx_tcx(cx), ti.ty)]; } } + } else if field == abi::tydesc_field_copy_glue { + alt { ti.copy_glue } { + some(_) {} + none. { + let lcx = cx.fcx.lcx; + let glue_fn = + declare_generic_glue(lcx, ti.ty, T_copy_glue_fn(*lcx.ccx), + "copy"); + ti.copy_glue = some(glue_fn); + make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, + copy_helper(make_copy_glue), + ti.ty_params, "copy"); + } + } } } } @@ -2156,6 +2186,45 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: ty::t, ret rslt(r.bcx, bld::Load(r.bcx, llcmpresultptr)); } +fn call_copy_glue(cx: &@block_ctxt, dst: ValueRef, src: ValueRef, t: ty::t, + take: bool) -> @block_ctxt { + // You can't call this on immediate types. Those are simply copied with + // Load/Store. + assert !type_is_immediate(bcx_ccx(cx), t); + let srcptr = bld::BitCast(cx, src, T_ptr(T_i8())); + let dstptr = bld::BitCast(cx, dst, T_ptr(T_i8())); + let ti = none; + let {bcx, val: lltydesc} = get_tydesc(cx, t, false, ti).result; + lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, ti); + let lltydescs = bld::GEP + (bcx, lltydesc, [C_int(0), C_int(abi::tydesc_field_first_param)]); + lltydescs = bld::Load(bcx, lltydescs); + + let llfn = alt ti { + none. { + bld::Load(bcx, bld::GEP + (bcx, lltydesc, [C_int(0), C_int(abi::tydesc_field_copy_glue)])) + } + some(sti) { option::get(sti.copy_glue) } + }; + bld::Call(bcx, llfn, [C_null(T_ptr(T_nil())), bcx.fcx.lltaskptr, + C_null(T_ptr(T_nil())), lltydescs, srcptr, dstptr]); + if take { + lazily_emit_tydesc_glue(cx, abi::tydesc_field_take_glue, ti); + llfn = alt ti { + none. { + bld::Load(bcx, bld::GEP(bcx, lltydesc, + [C_int(0), + C_int(abi::tydesc_field_take_glue)])) + } + some(sti) { option::get(sti.take_glue) } + }; + bld::Call(bcx, llfn, [C_null(T_ptr(T_nil())), bcx.fcx.lltaskptr, + C_null(T_ptr(T_nil())), lltydescs, dstptr]); + } + ret bcx; +} + // Compares two values. Performs the simple scalar comparison if the types are // scalar and calls to comparison glue otherwise. @@ -2310,8 +2379,12 @@ fn copy_val_no_check(cx: &@block_ctxt, action: copy_action, dst: ValueRef, let bcx = if action == DROP_EXISTING { drop_ty(cx, dst, t).bcx } else { cx }; - bcx = memmove_ty(bcx, dst, src, t).bcx; - ret take_ty(bcx, dst, t).bcx; + if ty::type_needs_copy_glue(ccx.tcx, t) { + ret call_copy_glue(bcx, dst, src, t, true); + } else { + bcx = memmove_ty(bcx, dst, src, t).bcx; + ret take_ty(bcx, dst, t).bcx; + } } ccx.sess.bug("unexpected type in trans::copy_val_no_check: " + ty_to_str(ccx.tcx, t)); @@ -2348,7 +2421,11 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef, ret cx; } else if type_is_structural_or_param(tcx, t) { if action == DROP_EXISTING { cx = drop_ty(cx, dst, t).bcx; } - cx = memmove_ty(cx, dst, src_val, t).bcx; + if ty::type_needs_copy_glue(tcx, t) { + cx = call_copy_glue(cx, dst, src_val, t, false); + } else { + cx = memmove_ty(cx, dst, src_val, t).bcx; + } if src.is_mem { ret zero_alloca(cx, src_val, t).bcx; } else { // Temporary value diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 1a6d23b3d09..b457ff22b30 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -85,6 +85,7 @@ type tydesc_info = mutable drop_glue: option::t<ValueRef>, mutable free_glue: option::t<ValueRef>, mutable cmp_glue: option::t<ValueRef>, + mutable copy_glue: option::t<ValueRef>, ty_params: [uint]}; /* @@ -614,6 +615,14 @@ fn T_cmp_glue_fn(cx: &crate_ctxt) -> TypeRef { ret t; } +fn T_copy_glue_fn(cx: &crate_ctxt) -> TypeRef { + let s = "copy_glue_fn"; + if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); } + let t = T_tydesc_field(cx, abi::tydesc_field_copy_glue); + cx.tn.associate(s, t); + ret t; +} + fn T_tydesc(taskptr_type: TypeRef) -> TypeRef { let tydesc = T_named_struct("tydesc"); let tydescpp = T_ptr(T_ptr(tydesc)); @@ -624,10 +633,13 @@ fn T_tydesc(taskptr_type: TypeRef) -> TypeRef { let cmp_glue_fn_ty = T_ptr(T_fn([T_ptr(T_i1()), taskptr_type, T_ptr(tydesc), tydescpp, pvoid, pvoid, T_i8()], T_void())); + let copy_glue_fn_ty = + T_ptr(T_fn([T_ptr(T_nil()), taskptr_type, T_ptr(T_nil()), tydescpp, + pvoid, pvoid], T_void())); let elems = [tydescpp, T_int(), T_int(), glue_fn_ty, glue_fn_ty, glue_fn_ty, - T_ptr(T_i8()), glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty, + copy_glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty, T_ptr(T_i8()), T_ptr(T_i8()), T_int()]; set_struct_body(tydesc, elems); ret tydesc; diff --git a/src/comp/middle/trans_ivec.rs b/src/comp/middle/trans_ivec.rs index 4820d5af69c..b0c18dbc522 100644 --- a/src/comp/middle/trans_ivec.rs +++ b/src/comp/middle/trans_ivec.rs @@ -367,6 +367,7 @@ fn trans_append(cx: &@block_ctxt, t: ty::t, lhs: ValueRef, lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, none); lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, none); lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, none); + lazily_emit_tydesc_glue(bcx, abi::tydesc_field_copy_glue, none); let rhs_len_and_data = get_len_and_data(bcx, rhs, unit_ty); let rhs_len = rhs_len_and_data.len; let rhs_data = rhs_len_and_data.data; diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index bb1c1c59422..5d448825b89 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -156,6 +156,7 @@ export type_kind; export type_err; export type_err_to_str; export type_has_dynamic_size; +export type_needs_copy_glue; export type_has_pointers; export type_needs_drop; export type_is_bool; @@ -1177,6 +1178,17 @@ fn type_has_dynamic_size(cx: &ctxt, ty: t) -> bool { }); } +fn type_needs_copy_glue(cx: &ctxt, ty: t) -> bool { + ret type_structurally_contains(cx, ty, fn(sty: &sty) -> bool { + ret alt sty { + ty_param(_, _) { true } + ty_vec(_) { true } + ty_istr. { true } + _ { false } + }; + }); +} + fn type_is_integral(cx: &ctxt, ty: t) -> bool { alt struct(cx, ty) { ty_int. { ret true; } |
