Skip to content

Commit 4eb3d99

Browse files
committed
---
yaml --- r: 4915 b: refs/heads/master c: fa97793 h: refs/heads/master i: 4913: bdba8c0 4911: 86e74db v: v3
1 parent 82a7412 commit 4eb3d99

File tree

7 files changed

+112
-8
lines changed

7 files changed

+112
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 60547f6500b0bf726e675b058ad0bdfe21455c11
2+
refs/heads/master: fa97793139a6b055eb0fba91ef7d64f6a545ca99

trunk/src/comp/back/abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const tydesc_field_align: int = 2;
5252
const tydesc_field_take_glue: int = 3;
5353
const tydesc_field_drop_glue: int = 4;
5454
const tydesc_field_free_glue: int = 5;
55-
const tydesc_field_unused: int = 6;
55+
const tydesc_field_copy_glue: int = 6;
5656
const tydesc_field_sever_glue: int = 7;
5757
const tydesc_field_mark_glue: int = 8;
5858
const tydesc_field_is_stateful: int = 9;

trunk/src/comp/middle/trans.rs

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,7 @@ fn declare_tydesc(cx: &@local_ctxt, sp: &span, t: ty::t, ty_params: &[uint])
11221122
mutable drop_glue: none::<ValueRef>,
11231123
mutable free_glue: none::<ValueRef>,
11241124
mutable cmp_glue: none::<ValueRef>,
1125+
mutable copy_glue: none::<ValueRef>,
11251126
ty_params: ty_params};
11261127
log "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
11271128
ret info;
@@ -1215,6 +1216,7 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
12151216
for each pair: @{key: ty::t, val: @tydesc_info} in ccx.tydescs.items() {
12161217
let glue_fn_ty = T_ptr(T_glue_fn(*ccx));
12171218
let cmp_fn_ty = T_ptr(T_cmp_glue_fn(*ccx));
1219+
let copy_fn_ty = T_ptr(T_copy_glue_fn(*ccx));
12181220
let ti = pair.val;
12191221
let take_glue =
12201222
alt { ti.take_glue } {
@@ -1236,6 +1238,11 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
12361238
none. { ccx.stats.n_null_glues += 1u; C_null(cmp_fn_ty) }
12371239
some(v) { ccx.stats.n_real_glues += 1u; v }
12381240
};
1241+
let copy_glue =
1242+
alt { ti.copy_glue } {
1243+
none. { ccx.stats.n_null_glues += 1u; C_null(copy_fn_ty) }
1244+
some(v) { ccx.stats.n_real_glues += 1u; v }
1245+
};
12391246

12401247
let shape = shape::shape_of(ccx, pair.key);
12411248
let shape_tables =
@@ -1250,7 +1257,7 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
12501257
take_glue, // take_glue
12511258
drop_glue, // drop_glue
12521259
free_glue, // free_glue
1253-
C_null(T_ptr(T_i8())), // unused
1260+
copy_glue, // copy_glue
12541261
C_null(glue_fn_ty), // sever_glue
12551262
C_null(glue_fn_ty), // mark_glue
12561263
C_null(glue_fn_ty), // is_stateful
@@ -1267,6 +1274,14 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
12671274
}
12681275
}
12691276

1277+
// NOTE this is currently just a complicated way to do memmove. I'm working on
1278+
// a representation of ivecs that will need pointers into itself, which must
1279+
// be adjusted when copying. Will flesh this out when the time comes.
1280+
fn make_copy_glue(cx: &@block_ctxt, src: ValueRef, dst: ValueRef, t: ty::t) {
1281+
let bcx = memmove_ty(cx, dst, src, t).bcx;
1282+
build_return(bcx);
1283+
}
1284+
12701285
fn make_take_glue(cx: &@block_ctxt, v: ValueRef, t: ty::t) {
12711286
// NB: v is an *alias* of type t here, not a direct value.
12721287

@@ -1988,6 +2003,7 @@ fn lazily_emit_all_tydesc_glue(cx: &@block_ctxt,
19882003
lazily_emit_tydesc_glue(cx, abi::tydesc_field_drop_glue, static_ti);
19892004
lazily_emit_tydesc_glue(cx, abi::tydesc_field_free_glue, static_ti);
19902005
lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, static_ti);
2006+
lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, static_ti);
19912007
}
19922008

19932009
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,
20672083
ty_to_str(bcx_tcx(cx), ti.ty)];
20682084
}
20692085
}
2086+
} else if field == abi::tydesc_field_copy_glue {
2087+
alt { ti.copy_glue } {
2088+
some(_) {}
2089+
none. {
2090+
let lcx = cx.fcx.lcx;
2091+
let glue_fn =
2092+
declare_generic_glue(lcx, ti.ty, T_copy_glue_fn(*lcx.ccx),
2093+
"copy");
2094+
ti.copy_glue = some(glue_fn);
2095+
make_generic_glue(lcx, cx.sp, ti.ty, glue_fn,
2096+
copy_helper(make_copy_glue),
2097+
ti.ty_params, "copy");
2098+
}
2099+
}
20702100
}
20712101
}
20722102
}
@@ -2156,6 +2186,45 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: ty::t,
21562186
ret rslt(r.bcx, bld::Load(r.bcx, llcmpresultptr));
21572187
}
21582188

2189+
fn call_copy_glue(cx: &@block_ctxt, dst: ValueRef, src: ValueRef, t: ty::t,
2190+
take: bool) -> @block_ctxt {
2191+
// You can't call this on immediate types. Those are simply copied with
2192+
// Load/Store.
2193+
assert !type_is_immediate(bcx_ccx(cx), t);
2194+
let srcptr = bld::BitCast(cx, src, T_ptr(T_i8()));
2195+
let dstptr = bld::BitCast(cx, dst, T_ptr(T_i8()));
2196+
let ti = none;
2197+
let {bcx, val: lltydesc} = get_tydesc(cx, t, false, ti).result;
2198+
lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, ti);
2199+
let lltydescs = bld::GEP
2200+
(bcx, lltydesc, [C_int(0), C_int(abi::tydesc_field_first_param)]);
2201+
lltydescs = bld::Load(bcx, lltydescs);
2202+
2203+
let llfn = alt ti {
2204+
none. {
2205+
bld::Load(bcx, bld::GEP
2206+
(bcx, lltydesc, [C_int(0), C_int(abi::tydesc_field_copy_glue)]))
2207+
}
2208+
some(sti) { option::get(sti.copy_glue) }
2209+
};
2210+
bld::Call(bcx, llfn, [C_null(T_ptr(T_nil())), bcx.fcx.lltaskptr,
2211+
C_null(T_ptr(T_nil())), lltydescs, srcptr, dstptr]);
2212+
if take {
2213+
lazily_emit_tydesc_glue(cx, abi::tydesc_field_take_glue, ti);
2214+
llfn = alt ti {
2215+
none. {
2216+
bld::Load(bcx, bld::GEP(bcx, lltydesc,
2217+
[C_int(0),
2218+
C_int(abi::tydesc_field_take_glue)]))
2219+
}
2220+
some(sti) { option::get(sti.take_glue) }
2221+
};
2222+
bld::Call(bcx, llfn, [C_null(T_ptr(T_nil())), bcx.fcx.lltaskptr,
2223+
C_null(T_ptr(T_nil())), lltydescs, dstptr]);
2224+
}
2225+
ret bcx;
2226+
}
2227+
21592228

21602229
// Compares two values. Performs the simple scalar comparison if the types are
21612230
// scalar and calls to comparison glue otherwise.
@@ -2310,8 +2379,12 @@ fn copy_val_no_check(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
23102379
let bcx = if action == DROP_EXISTING {
23112380
drop_ty(cx, dst, t).bcx
23122381
} else { cx };
2313-
bcx = memmove_ty(bcx, dst, src, t).bcx;
2314-
ret take_ty(bcx, dst, t).bcx;
2382+
if ty::type_needs_copy_glue(ccx.tcx, t) {
2383+
ret call_copy_glue(bcx, dst, src, t, true);
2384+
} else {
2385+
bcx = memmove_ty(bcx, dst, src, t).bcx;
2386+
ret take_ty(bcx, dst, t).bcx;
2387+
}
23152388
}
23162389
ccx.sess.bug("unexpected type in trans::copy_val_no_check: " +
23172390
ty_to_str(ccx.tcx, t));
@@ -2348,7 +2421,11 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
23482421
ret cx;
23492422
} else if type_is_structural_or_param(tcx, t) {
23502423
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t).bcx; }
2351-
cx = memmove_ty(cx, dst, src_val, t).bcx;
2424+
if ty::type_needs_copy_glue(tcx, t) {
2425+
cx = call_copy_glue(cx, dst, src_val, t, false);
2426+
} else {
2427+
cx = memmove_ty(cx, dst, src_val, t).bcx;
2428+
}
23522429
if src.is_mem {
23532430
ret zero_alloca(cx, src_val, t).bcx;
23542431
} else { // Temporary value

trunk/src/comp/middle/trans_common.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ type tydesc_info =
8585
mutable drop_glue: option::t<ValueRef>,
8686
mutable free_glue: option::t<ValueRef>,
8787
mutable cmp_glue: option::t<ValueRef>,
88+
mutable copy_glue: option::t<ValueRef>,
8889
ty_params: [uint]};
8990

9091
/*
@@ -614,6 +615,14 @@ fn T_cmp_glue_fn(cx: &crate_ctxt) -> TypeRef {
614615
ret t;
615616
}
616617

618+
fn T_copy_glue_fn(cx: &crate_ctxt) -> TypeRef {
619+
let s = "copy_glue_fn";
620+
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
621+
let t = T_tydesc_field(cx, abi::tydesc_field_copy_glue);
622+
cx.tn.associate(s, t);
623+
ret t;
624+
}
625+
617626
fn T_tydesc(taskptr_type: TypeRef) -> TypeRef {
618627
let tydesc = T_named_struct("tydesc");
619628
let tydescpp = T_ptr(T_ptr(tydesc));
@@ -624,10 +633,13 @@ fn T_tydesc(taskptr_type: TypeRef) -> TypeRef {
624633
let cmp_glue_fn_ty =
625634
T_ptr(T_fn([T_ptr(T_i1()), taskptr_type, T_ptr(tydesc), tydescpp,
626635
pvoid, pvoid, T_i8()], T_void()));
636+
let copy_glue_fn_ty =
637+
T_ptr(T_fn([T_ptr(T_nil()), taskptr_type, T_ptr(T_nil()), tydescpp,
638+
pvoid, pvoid], T_void()));
627639

628640
let elems =
629641
[tydescpp, T_int(), T_int(), glue_fn_ty, glue_fn_ty, glue_fn_ty,
630-
T_ptr(T_i8()), glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty,
642+
copy_glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty,
631643
T_ptr(T_i8()), T_ptr(T_i8()), T_int()];
632644
set_struct_body(tydesc, elems);
633645
ret tydesc;

trunk/src/comp/middle/trans_ivec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ fn trans_append(cx: &@block_ctxt, t: ty::t, lhs: ValueRef,
367367
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, none);
368368
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, none);
369369
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, none);
370+
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_copy_glue, none);
370371
let rhs_len_and_data = get_len_and_data(bcx, rhs, unit_ty);
371372
let rhs_len = rhs_len_and_data.len;
372373
let rhs_data = rhs_len_and_data.data;

trunk/src/comp/middle/ty.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ export type_kind;
156156
export type_err;
157157
export type_err_to_str;
158158
export type_has_dynamic_size;
159+
export type_needs_copy_glue;
159160
export type_has_pointers;
160161
export type_needs_drop;
161162
export type_is_bool;
@@ -1177,6 +1178,17 @@ fn type_has_dynamic_size(cx: &ctxt, ty: t) -> bool {
11771178
});
11781179
}
11791180

1181+
fn type_needs_copy_glue(cx: &ctxt, ty: t) -> bool {
1182+
ret type_structurally_contains(cx, ty, fn(sty: &sty) -> bool {
1183+
ret alt sty {
1184+
ty_param(_, _) { true }
1185+
ty_vec(_) { true }
1186+
ty_istr. { true }
1187+
_ { false }
1188+
};
1189+
});
1190+
}
1191+
11801192
fn type_is_integral(cx: &ctxt, ty: t) -> bool {
11811193
alt struct(cx, ty) {
11821194
ty_int. { ret true; }

trunk/src/rt/rust_internal.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ struct rust_timer {
257257

258258
typedef void CDECL (glue_fn)(void *, rust_task *, void *,
259259
const type_desc **, void *);
260+
typedef void CDECL (copy_glue_fn)(void *, rust_task *, void *,
261+
const type_desc **, void *, void *);
260262
typedef void CDECL (cmp_glue_fn)(void *, rust_task *, void *,
261263
const type_desc **,
262264
void *, void *, int8_t);
@@ -275,7 +277,7 @@ struct type_desc {
275277
glue_fn *take_glue;
276278
glue_fn *drop_glue;
277279
glue_fn *free_glue;
278-
void *unused;
280+
copy_glue_fn *copy_glue;
279281
glue_fn *sever_glue; // For GC.
280282
glue_fn *mark_glue; // For GC.
281283
uintptr_t is_stateful;

0 commit comments

Comments
 (0)