@@ -5,13 +5,35 @@ import back::abi;
5
5
import base :: { call_memmove,
6
6
INIT , copy_val, load_if_immediate, get_tydesc,
7
7
sub_block, do_spill_noroot,
8
- dest, bcx_icx, non_gc_box_cast} ;
8
+ dest, bcx_icx, non_gc_box_cast,
9
+ heap, heap_exchange, heap_shared} ;
9
10
import syntax:: codemap:: span;
10
11
import shape:: llsize_of;
11
12
import build:: * ;
12
13
import common:: * ;
13
14
import util:: ppaux:: ty_to_str;
14
15
16
+ // Boxed vector types are in some sense currently a "shorthand" for a box
17
+ // containing an unboxed vector. This expands a boxed vector type into such an
18
+ // expanded type. It doesn't respect mutability, but that doesn't matter at
19
+ // this point.
20
+ fn expand_boxed_vec_ty ( tcx : ty:: ctxt , t : ty:: t ) -> ty:: t {
21
+ let unit_ty = ty:: sequence_element_type ( tcx, t) ;
22
+ let unboxed_vec_ty = ty:: mk_mut_unboxed_vec ( tcx, unit_ty) ;
23
+ alt ty:: get ( t) . struct {
24
+ ty:: ty_vec ( _) | ty:: ty_str |
25
+ ty:: ty_estr ( ty:: vstore_uniq) | ty:: ty_evec ( _, ty:: vstore_uniq) {
26
+ ty:: mk_imm_uniq ( tcx, unboxed_vec_ty)
27
+ }
28
+ ty:: ty_estr ( ty:: vstore_box) | ty:: ty_evec ( _, ty:: vstore_box) {
29
+ ty:: mk_imm_box ( tcx, unboxed_vec_ty)
30
+ }
31
+ _ { tcx. sess . bug ( "non boxed-vec type \
32
+ in tvec::expand_boxed_vec_ty") ;
33
+ }
34
+ }
35
+ }
36
+
15
37
fn get_fill ( bcx : block , vptr : ValueRef ) -> ValueRef {
16
38
let _icx = bcx. insn_ctxt ( "tvec::get_fill" ) ;
17
39
Load ( bcx, GEPi ( bcx, vptr, [ 0 u, abi:: vec_elt_fill] ) )
@@ -40,21 +62,25 @@ fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
40
62
ret PointerCast ( bcx, InBoundsGEP ( bcx, bptr, [ bytes] ) , old_ty) ;
41
63
}
42
64
43
- fn alloc_uniq_raw ( bcx : block , unit_ty : ty:: t ,
44
- fill : ValueRef , alloc : ValueRef ) -> result {
45
- let _icx = bcx. insn_ctxt ( "tvec::alloc_uniq_raw " ) ;
65
+ fn alloc_raw ( bcx : block , unit_ty : ty:: t ,
66
+ fill : ValueRef , alloc : ValueRef , heap : heap ) -> result {
67
+ let _icx = bcx. insn_ctxt ( "tvec::alloc_uniq " ) ;
46
68
let ccx = bcx. ccx ( ) ;
47
69
48
70
let vecbodyty = ty:: mk_mut_unboxed_vec ( bcx. tcx ( ) , unit_ty) ;
49
71
let vecsize = Add ( bcx, alloc, llsize_of ( ccx, ccx. opaque_vec_type ) ) ;
50
72
51
- let { box, body} = base:: malloc_unique_dyn ( bcx, vecbodyty, vecsize) ;
73
+ let { box, body} = base:: malloc_general_dyn ( bcx, vecbodyty, heap , vecsize) ;
52
74
Store ( bcx, fill, GEPi ( bcx, body, [ 0 u, abi:: vec_elt_fill] ) ) ;
53
75
Store ( bcx, alloc, GEPi ( bcx, body, [ 0 u, abi:: vec_elt_alloc] ) ) ;
54
76
ret { bcx : bcx, val : box} ;
55
77
}
78
+ fn alloc_uniq_raw ( bcx : block , unit_ty : ty:: t ,
79
+ fill : ValueRef , alloc : ValueRef ) -> result {
80
+ alloc_raw ( bcx, unit_ty, fill, alloc, heap_exchange)
81
+ }
56
82
57
- fn alloc_uniq ( bcx : block , unit_ty : ty:: t , elts : uint ) -> result {
83
+ fn alloc_vec ( bcx : block , unit_ty : ty:: t , elts : uint , heap : heap ) -> result {
58
84
let _icx = bcx. insn_ctxt ( "tvec::alloc_uniq" ) ;
59
85
let ccx = bcx. ccx ( ) ;
60
86
let llunitty = type_of:: type_of ( ccx, unit_ty) ;
@@ -63,7 +89,7 @@ fn alloc_uniq(bcx: block, unit_ty: ty::t, elts: uint) -> result {
63
89
let fill = Mul ( bcx, C_uint ( ccx, elts) , unit_sz) ;
64
90
let alloc = if elts < 4 u { Mul ( bcx, C_int ( ccx, 4 ) , unit_sz) }
65
91
else { fill } ;
66
- let { bcx: bcx , val : vptr } = alloc_uniq_raw ( bcx, unit_ty, fill, alloc) ;
92
+ let { bcx: bcx , val : vptr } = alloc_raw ( bcx, unit_ty, fill, alloc, heap ) ;
67
93
ret { bcx : bcx, val : vptr} ;
68
94
}
69
95
@@ -79,20 +105,18 @@ fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> result {
79
105
call_memmove ( bcx, new_data_ptr, data_ptr, fill) ;
80
106
81
107
let bcx = if ty:: type_needs_drop ( bcx. tcx ( ) , unit_ty) {
82
- iter_vec ( bcx, newptr , vec_ty, base:: take_ty)
108
+ iter_vec_raw ( bcx, new_data_ptr , vec_ty, fill , base:: take_ty)
83
109
} else { bcx } ;
84
110
ret rslt( bcx, newptr) ;
85
111
}
86
- fn make_free_glue ( bcx : block , vptr : ValueRef , vec_ty : ty:: t ) ->
112
+
113
+ fn make_drop_glue_unboxed ( bcx : block , vptr : ValueRef , vec_ty : ty:: t ) ->
87
114
block {
88
- let _icx = bcx. insn_ctxt ( "tvec::make_free_glue " ) ;
115
+ let _icx = bcx. insn_ctxt ( "tvec::make_drop_glue_unboxed " ) ;
89
116
let tcx = bcx. tcx ( ) , unit_ty = ty:: sequence_element_type ( tcx, vec_ty) ;
90
- base:: with_cond ( bcx, IsNotNull ( bcx, vptr) ) { |bcx|
91
- let bcx = if ty:: type_needs_drop ( tcx, unit_ty) {
92
- iter_vec ( bcx, vptr, vec_ty, base:: drop_ty)
93
- } else { bcx } ;
94
- base:: trans_unique_free ( bcx, vptr)
95
- }
117
+ if ty:: type_needs_drop ( tcx, unit_ty) {
118
+ iter_vec_unboxed ( bcx, vptr, vec_ty, base:: drop_ty)
119
+ } else { bcx }
96
120
}
97
121
98
122
fn trans_evec ( bcx : block , args : [ @ast:: expr ] ,
@@ -141,13 +165,18 @@ fn trans_evec(bcx: block, args: [@ast::expr],
141
165
{ bcx: bcx, val: p, dataptr: vp}
142
166
}
143
167
ast:: vstore_uniq {
144
- let { bcx, val} = alloc_uniq ( bcx, unit_ty, args. len ( ) ) ;
168
+ let { bcx, val} = alloc_vec ( bcx, unit_ty, args. len ( ) ,
169
+ heap_exchange) ;
145
170
add_clean_free ( bcx, val, true ) ;
146
171
let dataptr = get_dataptr ( bcx, get_bodyptr ( bcx, val) ) ;
147
172
{ bcx: bcx, val: val, dataptr: dataptr}
148
173
}
149
174
ast:: vstore_box {
150
- bcx. ccx ( ) . sess . unimpl ( "unhandled tvec::trans_evec" ) ;
175
+ let { bcx, val} = alloc_vec ( bcx, unit_ty, args. len ( ) ,
176
+ heap_shared) ;
177
+ add_clean_free ( bcx, val, true ) ;
178
+ let dataptr = get_dataptr ( bcx, get_bodyptr ( bcx, val) ) ;
179
+ { bcx: bcx, val: val, dataptr: dataptr}
151
180
}
152
181
} ;
153
182
@@ -223,13 +252,11 @@ fn get_base_and_len(cx: block, v: ValueRef, e_ty: ty::t)
223
252
let len = Load ( cx, GEPi ( cx, v, [ 0 u, abi:: slice_elt_len] ) ) ;
224
253
( base, len)
225
254
}
226
- ty:: vstore_uniq {
255
+ ty:: vstore_uniq | ty:: vstore_box {
256
+ #debug[ "get_base_and_len: %s", val_str(ccx.tn, v)];
227
257
let body = tvec::get_bodyptr(cx, v);
228
258
(tvec::get_dataptr(cx, body), tvec::get_fill(cx, body))
229
259
}
230
- ty:: vstore_box {
231
- cx. ccx ( ) . sess . unimpl ( "unhandled tvec::get_base_and_len" ) ;
232
- }
233
260
}
234
261
}
235
262
@@ -388,7 +415,7 @@ type iter_vec_block = fn(block, ValueRef, ty::t) -> block;
388
415
389
416
fn iter_vec_raw ( bcx : block , data_ptr : ValueRef , vec_ty : ty:: t ,
390
417
fill : ValueRef , f : iter_vec_block ) -> block {
391
- let _icx = bcx. insn_ctxt ( "tvec::iter_vec_uniq " ) ;
418
+ let _icx = bcx. insn_ctxt ( "tvec::iter_vec_raw " ) ;
392
419
393
420
let unit_ty = ty:: sequence_element_type ( bcx. tcx ( ) , vec_ty) ;
394
421
@@ -422,11 +449,12 @@ fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
422
449
iter_vec_raw ( bcx, data_ptr, vec_ty, fill, f)
423
450
}
424
451
425
- fn iter_vec ( bcx : block , vptr : ValueRef , vec_ty : ty:: t ,
426
- f : iter_vec_block ) -> block {
427
- let _icx = bcx. insn_ctxt ( "tvec::iter_vec" ) ;
428
- let fill = get_fill ( bcx, get_bodyptr ( bcx, vptr) ) ;
429
- ret iter_vec_uniq ( bcx, vptr, vec_ty, fill, f) ;
452
+ fn iter_vec_unboxed ( bcx : block , body_ptr : ValueRef , vec_ty : ty:: t ,
453
+ f : iter_vec_block ) -> block {
454
+ let _icx = bcx. insn_ctxt ( "tvec::iter_vec_unboxed" ) ;
455
+ let fill = get_fill ( bcx, body_ptr) ;
456
+ let dataptr = get_dataptr ( bcx, body_ptr) ;
457
+ ret iter_vec_raw ( bcx, dataptr, vec_ty, fill, f) ;
430
458
}
431
459
432
460
//
0 commit comments