Skip to content

Commit 8e40ca1

Browse files
committed
---
yaml --- r: 7101 b: refs/heads/master c: d1b987d h: refs/heads/master i: 7099: a576aac v: v3
1 parent 1142d7d commit 8e40ca1

File tree

2 files changed

+48
-23
lines changed

2 files changed

+48
-23
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: 8506241f3a0dce3f0d24764a3ce3d16f99bcb809
2+
refs/heads/master: d1b987d292cc0f4fa412d18b051ce8681256bb61

trunk/src/comp/middle/trans_closure.rs

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import syntax::codemap::span;
1212
import back::link::{
1313
mangle_internal_name_by_path,
1414
mangle_internal_name_by_path_and_seq};
15+
import util::ppaux::ty_to_str;
1516
import trans::{
1617
trans_shared_malloc,
1718
type_of_inner,
@@ -131,7 +132,8 @@ fn mk_tydesc_ty(tcx: ty::ctxt, ck: ty::closure_kind) -> ty::t {
131132
fn mk_closure_tys(tcx: ty::ctxt,
132133
ck: ty::closure_kind,
133134
ty_params: [fn_ty_param],
134-
bound_values: [environment_value]) -> (ty::t, [ty::t]) {
135+
bound_values: [environment_value])
136+
-> (ty::t, ty::t, [ty::t]) {
135137
let bound_tys = [];
136138

137139
let tydesc_ty =
@@ -157,23 +159,45 @@ fn mk_closure_tys(tcx: ty::ctxt,
157159
}
158160
let bound_data_ty = ty::mk_tup(tcx, bound_tys);
159161

162+
let norc_tys = [tydesc_ty, ty::mk_tup(tcx, param_ptrs), bound_data_ty];
163+
164+
// closure_norc_ty == everything but ref count
165+
//
166+
// This is a hack to integrate with the cycle coll. When you
167+
// allocate memory in the task-local space, you are expected to
168+
// provide a descriptor for that memory which excludes the ref
169+
// count. That's what this represents. However, this really
170+
// assumes a type setup like [uint, data] where data can be a
171+
// struct. We don't use that structure here because we don't want
172+
// to alignment of the first few fields being bound up in the
173+
// alignment of the bound data, as would happen if we laid out
174+
// that way. For now this should be fine but ultimately we need
175+
// to modify CC code or else modify box allocation interface to be
176+
// a bit more flexible, perhaps taking a vec of tys in the box
177+
// (which for normal rust code is always of length 1).
178+
let closure_norc_ty = ty::mk_tup(tcx, norc_tys);
179+
180+
#debug["closure_norc_ty=%s", ty_to_str(tcx, closure_norc_ty)];
181+
160182
// closure_ty == ref count, data tydesc, typarams, bound data
161-
let closure_ty =
162-
ty::mk_tup(tcx, [ty::mk_int(tcx), tydesc_ty,
163-
ty::mk_tup(tcx, param_ptrs), bound_data_ty]);
183+
let closure_ty = ty::mk_tup(tcx, [ty::mk_int(tcx)] + norc_tys);
184+
185+
#debug["closure_ty=%s", ty_to_str(tcx, closure_norc_ty)];
164186

165-
ret (closure_ty, bound_tys);
187+
ret (closure_ty, closure_norc_ty, bound_tys);
166188
}
167189

168190
fn allocate_cbox(bcx: @block_ctxt,
169191
ck: ty::closure_kind,
170-
cbox_ty: ty::t)
192+
cbox_ty: ty::t,
193+
cbox_norc_ty: ty::t)
171194
-> (@block_ctxt, ValueRef, [ValueRef]) {
172195

173-
fn alloc_in_heap(bcx: @block_ctxt,
174-
cbox_ty: ty::t,
175-
shared: bool,
176-
&temp_cleanups: [ValueRef])
196+
let ccx = bcx_ccx(bcx);
197+
198+
let alloc_in_heap = lambda(bcx: @block_ctxt,
199+
xchgheap: bool,
200+
&temp_cleanups: [ValueRef])
177201
-> (@block_ctxt, ValueRef) {
178202

179203
// n.b. If you are wondering why we don't use
@@ -183,28 +207,28 @@ fn allocate_cbox(bcx: @block_ctxt,
183207

184208
let {bcx, val:llsz} = size_of(bcx, cbox_ty);
185209
let ti = none;
210+
let tydesc_ty = if xchgheap { cbox_ty } else { cbox_norc_ty };
186211
let {bcx, val:lltydesc} =
187-
get_tydesc(bcx, cbox_ty, true, tps_normal, ti).result;
188-
let malloc =
189-
if shared { bcx_ccx(bcx).upcalls.shared_malloc }
190-
else { bcx_ccx(bcx).upcalls.malloc };
212+
get_tydesc(bcx, tydesc_ty, true, tps_normal, ti).result;
213+
let malloc = {
214+
if xchgheap { ccx.upcalls.shared_malloc}
215+
else { ccx.upcalls.malloc }
216+
};
191217
let box = Call(bcx, malloc, [llsz, lltydesc]);
192-
add_clean_free(bcx, box, shared);
218+
add_clean_free(bcx, box, xchgheap);
193219
temp_cleanups += [box];
194220
(bcx, box)
195-
}
196-
197-
let ccx = bcx_ccx(bcx);
221+
};
198222

199223
// Allocate the box:
200224
let temp_cleanups = [];
201225
let (bcx, box, rc) = alt ck {
202226
ty::closure_shared. {
203-
let (bcx, box) = alloc_in_heap(bcx, cbox_ty, false, temp_cleanups);
227+
let (bcx, box) = alloc_in_heap(bcx, false, temp_cleanups);
204228
(bcx, box, 1)
205229
}
206230
ty::closure_send. {
207-
let (bcx, box) = alloc_in_heap(bcx, cbox_ty, true, temp_cleanups);
231+
let (bcx, box) = alloc_in_heap(bcx, true, temp_cleanups);
208232
(bcx, box, 0xdeadc0de) // use arbitrary value for debugging
209233
}
210234
ty::closure_block. {
@@ -264,11 +288,12 @@ fn store_environment(
264288
let tcx = bcx_tcx(bcx);
265289

266290
// compute the shape of the closure
267-
let (cbox_ty, bound_tys) =
291+
let (cbox_ty, cbox_norc_ty, bound_tys) =
268292
mk_closure_tys(tcx, ck, lltyparams, bound_values);
269293

270294
// allocate closure in the heap
271-
let (bcx, llbox, temp_cleanups) = allocate_cbox(bcx, ck, cbox_ty);
295+
let (bcx, llbox, temp_cleanups) =
296+
allocate_cbox(bcx, ck, cbox_ty, cbox_norc_ty);
272297

273298
// store data tydesc.
274299
alt ck {

0 commit comments

Comments
 (0)