@@ -12,6 +12,7 @@ import syntax::codemap::span;
12
12
import back:: link:: {
13
13
mangle_internal_name_by_path,
14
14
mangle_internal_name_by_path_and_seq} ;
15
+ import util:: ppaux:: ty_to_str;
15
16
import trans :: {
16
17
trans_shared_malloc,
17
18
type_of_inner,
@@ -131,7 +132,8 @@ fn mk_tydesc_ty(tcx: ty::ctxt, ck: ty::closure_kind) -> ty::t {
131
132
fn mk_closure_tys ( tcx : ty:: ctxt ,
132
133
ck : ty:: closure_kind ,
133
134
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 ] ) {
135
137
let bound_tys = [ ] ;
136
138
137
139
let tydesc_ty =
@@ -157,23 +159,45 @@ fn mk_closure_tys(tcx: ty::ctxt,
157
159
}
158
160
let bound_data_ty = ty:: mk_tup ( tcx, bound_tys) ;
159
161
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
+
160
182
// 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 ) ] ;
164
186
165
- ret ( closure_ty, bound_tys) ;
187
+ ret ( closure_ty, closure_norc_ty , bound_tys) ;
166
188
}
167
189
168
190
fn allocate_cbox ( bcx : @block_ctxt ,
169
191
ck : ty:: closure_kind ,
170
- cbox_ty : ty:: t )
192
+ cbox_ty : ty:: t ,
193
+ cbox_norc_ty : ty:: t )
171
194
-> ( @block_ctxt , ValueRef , [ ValueRef ] ) {
172
195
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 ] )
177
201
-> ( @block_ctxt, ValueRef ) {
178
202
179
203
// n.b. If you are wondering why we don't use
@@ -183,28 +207,28 @@ fn allocate_cbox(bcx: @block_ctxt,
183
207
184
208
let { bcx, val: llsz } = size_of ( bcx, cbox_ty) ;
185
209
let ti = none;
210
+ let tydesc_ty = if xchgheap { cbox_ty } else { cbox_norc_ty } ;
186
211
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
+ } ;
191
217
let box = Call ( bcx, malloc, [ llsz, lltydesc] ) ;
192
- add_clean_free ( bcx, box, shared ) ;
218
+ add_clean_free ( bcx, box, xchgheap ) ;
193
219
temp_cleanups += [ box] ;
194
220
( bcx, box)
195
- }
196
-
197
- let ccx = bcx_ccx ( bcx) ;
221
+ } ;
198
222
199
223
// Allocate the box:
200
224
let temp_cleanups = [ ] ;
201
225
let ( bcx, box, rc) = alt ck {
202
226
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) ;
204
228
( bcx, box, 1 )
205
229
}
206
230
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) ;
208
232
( bcx, box, 0xdeadc0de ) // use arbitrary value for debugging
209
233
}
210
234
ty:: closure_block. {
@@ -264,11 +288,12 @@ fn store_environment(
264
288
let tcx = bcx_tcx ( bcx) ;
265
289
266
290
// compute the shape of the closure
267
- let ( cbox_ty, bound_tys) =
291
+ let ( cbox_ty, cbox_norc_ty , bound_tys) =
268
292
mk_closure_tys ( tcx, ck, lltyparams, bound_values) ;
269
293
270
294
// 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) ;
272
297
273
298
// store data tydesc.
274
299
alt ck {
0 commit comments