@@ -23,13 +23,13 @@ use middle::trans::base::*;
2323use middle:: trans:: callee;
2424use middle:: trans:: closure;
2525use middle:: trans:: common:: * ;
26+ use middle:: trans:: datum:: immediate_rvalue;
2627use middle:: trans:: build:: * ;
2728use middle:: trans:: expr;
2829use middle:: trans:: machine:: * ;
2930use middle:: trans:: reflect;
3031use middle:: trans:: tvec;
3132use middle:: trans:: type_of:: type_of;
32- use middle:: trans:: uniq;
3333use middle:: ty;
3434use util:: ppaux;
3535use util:: ppaux:: ty_to_short_str;
@@ -86,47 +86,16 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
8686 drop_ty ( bcx, vp, t)
8787}
8888
89- pub fn free_ty < ' a > ( cx : & ' a Block < ' a > , v : ValueRef , t : ty:: t )
90- -> & ' a Block < ' a > {
91- // NB: v is an *alias* of type t here, not a direct value.
92- let _icx = push_ctxt ( "free_ty" ) ;
93- if ty:: type_needs_drop ( cx. tcx ( ) , t) {
94- return call_tydesc_glue ( cx, v, t, abi:: tydesc_field_free_glue) ;
95- }
96- return cx;
97- }
98-
99- pub fn free_ty_immediate < ' a > ( bcx : & ' a Block < ' a > , v : ValueRef , t : ty:: t )
100- -> & ' a Block < ' a > {
101- let _icx = push_ctxt ( "free_ty_immediate" ) ;
102- match ty:: get ( t) . sty {
103- ty:: ty_uniq( _) |
104- ty:: ty_vec( _, ty:: vstore_uniq) |
105- ty:: ty_str( ty:: vstore_uniq) |
106- ty:: ty_box( _) | ty:: ty_opaque_box |
107- ty:: ty_vec( _, ty:: vstore_box) |
108- ty:: ty_str( ty:: vstore_box) |
109- ty:: ty_opaque_closure_ptr( _) => {
110- let vp = alloca ( bcx, type_of ( bcx. ccx ( ) , t) , "" ) ;
111- Store ( bcx, v, vp) ;
112- free_ty ( bcx, vp, t)
113- }
114- _ => bcx. tcx ( ) . sess . bug ( "free_ty_immediate: non-box ty" )
115- }
116- }
117-
11889pub fn lazily_emit_all_tydesc_glue ( ccx : @CrateContext ,
11990 static_ti : @tydesc_info ) {
12091 lazily_emit_tydesc_glue ( ccx, abi:: tydesc_field_take_glue, static_ti) ;
12192 lazily_emit_tydesc_glue ( ccx, abi:: tydesc_field_drop_glue, static_ti) ;
122- lazily_emit_tydesc_glue ( ccx, abi:: tydesc_field_free_glue, static_ti) ;
12393 lazily_emit_tydesc_glue ( ccx, abi:: tydesc_field_visit_glue, static_ti) ;
12494}
12595
12696pub fn simplified_glue_type ( tcx : ty:: ctxt , field : uint , t : ty:: t ) -> ty:: t {
12797 if ( field == abi:: tydesc_field_take_glue ||
128- field == abi:: tydesc_field_drop_glue ||
129- field == abi:: tydesc_field_free_glue) &&
98+ field == abi:: tydesc_field_drop_glue) &&
13099 ! ty:: type_needs_drop ( tcx, t) {
131100 return ty:: mk_u32 ( ) ;
132101 }
@@ -146,22 +115,7 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
146115 return ty:: mk_imm_box ( tcx, ty:: mk_u32 ( ) ) ;
147116 }
148117
149- if field == abi:: tydesc_field_free_glue {
150- match ty:: get ( t) . sty {
151- ty:: ty_bare_fn( ..) |
152- ty:: ty_closure( ..) |
153- ty:: ty_box( ..) |
154- ty:: ty_opaque_box |
155- ty:: ty_uniq( ..) |
156- ty:: ty_vec( _, ty:: vstore_uniq) | ty:: ty_str( ty:: vstore_uniq) |
157- ty:: ty_vec( _, ty:: vstore_box) | ty:: ty_str( ty:: vstore_box) |
158- ty:: ty_opaque_closure_ptr( ..) => ( ) ,
159- _ => { return ty:: mk_u32 ( ) ; }
160- }
161- }
162-
163- if ( field == abi:: tydesc_field_free_glue ||
164- field == abi:: tydesc_field_drop_glue) {
118+ if field == abi:: tydesc_field_drop_glue {
165119 match ty:: get ( t) . sty {
166120 ty:: ty_box( typ)
167121 if ! ty:: type_needs_drop ( tcx, typ) =>
@@ -197,8 +151,6 @@ pub fn lazily_emit_simplified_tydesc_glue(ccx: @CrateContext,
197151 ti. take_glue . set ( simpl_ti. take_glue . get ( ) ) ;
198152 } else if field == abi:: tydesc_field_drop_glue {
199153 ti. drop_glue . set ( simpl_ti. drop_glue . get ( ) ) ;
200- } else if field == abi:: tydesc_field_free_glue {
201- ti. free_glue . set ( simpl_ti. free_glue . get ( ) ) ;
202154 } else if field == abi:: tydesc_field_visit_glue {
203155 ti. visit_glue . set ( simpl_ti. visit_glue . get ( ) ) ;
204156 }
@@ -245,19 +197,6 @@ pub fn lazily_emit_tydesc_glue(ccx: @CrateContext,
245197 ppaux:: ty_to_str( ccx. tcx, ti. ty) ) ;
246198 }
247199 }
248- } else if field == abi:: tydesc_field_free_glue {
249- match ti. free_glue . get ( ) {
250- Some ( _) => ( ) ,
251- None => {
252- debug ! ( "+++ lazily_emit_tydesc_glue FREE {}" ,
253- ppaux:: ty_to_str( ccx. tcx, ti. ty) ) ;
254- let glue_fn = declare_generic_glue ( ccx, ti. ty , llfnty, "free" ) ;
255- ti. free_glue . set ( Some ( glue_fn) ) ;
256- make_generic_glue ( ccx, ti. ty , glue_fn, make_free_glue, "free" ) ;
257- debug ! ( "--- lazily_emit_tydesc_glue FREE {}" ,
258- ppaux:: ty_to_str( ccx. tcx, ti. ty) ) ;
259- }
260- }
261200 } else if field == abi:: tydesc_field_visit_glue {
262201 match ti. visit_glue . get ( ) {
263202 Some ( _) => ( ) ,
@@ -294,8 +233,6 @@ pub fn call_tydesc_glue_full(bcx: &Block,
294233 sti. take_glue . get ( )
295234 } else if field == abi:: tydesc_field_drop_glue {
296235 sti. drop_glue . get ( )
297- } else if field == abi:: tydesc_field_free_glue {
298- sti. free_glue . get ( )
299236 } else if field == abi:: tydesc_field_visit_glue {
300237 sti. visit_glue . get ( )
301238 } else {
@@ -346,8 +283,8 @@ pub fn call_tydesc_glue<'a>(
346283 return cx;
347284}
348285
349- pub fn make_visit_glue < ' a > ( bcx : & ' a Block < ' a > , v : ValueRef , t : ty:: t )
350- -> & ' a Block < ' a > {
286+ fn make_visit_glue < ' a > ( bcx : & ' a Block < ' a > , v : ValueRef , t : ty:: t )
287+ -> & ' a Block < ' a > {
351288 let _icx = push_ctxt ( "make_visit_glue" ) ;
352289 with_scope ( bcx, None , "visitor cleanup" , |bcx| {
353290 let mut bcx = bcx;
@@ -371,31 +308,32 @@ pub fn make_free_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
371308 // NB: v0 is an *alias* of type t here, not a direct value.
372309 let _icx = push_ctxt ( "make_free_glue" ) ;
373310 match ty:: get ( t) . sty {
311+ ty:: ty_opaque_box => bcx. tcx ( ) . sess . fatal ( "found ty_opaque_box in make_free_glue" ) ,
374312 ty:: ty_box( body_ty) => {
375313 let v = Load ( bcx, v) ;
376314 let body = GEPi ( bcx, v, [ 0 u, abi:: box_field_body] ) ;
377315 let bcx = drop_ty ( bcx, body, body_ty) ;
378316 trans_free ( bcx, v)
379317 }
380- ty:: ty_opaque_box => {
381- let v = Load ( bcx, v) ;
382- let td = Load ( bcx, GEPi ( bcx, v, [ 0 u, abi:: box_field_tydesc] ) ) ;
383- let valptr = GEPi ( bcx, v, [ 0 u, abi:: box_field_body] ) ;
384- // Generate code that, dynamically, indexes into the
385- // tydesc and calls the drop glue that got set dynamically
386- call_tydesc_glue_full ( bcx, valptr, td, abi:: tydesc_field_drop_glue,
387- None ) ;
388- trans_free ( bcx, v)
389- }
390318 ty:: ty_uniq( ..) => {
391- uniq:: make_free_glue ( bcx, v, t)
319+ let box_datum = immediate_rvalue ( Load ( bcx, v) , t) ;
320+ let not_null = IsNotNull ( bcx, box_datum. val ) ;
321+ with_cond ( bcx, not_null, |bcx| {
322+ let body_datum = box_datum. box_body ( bcx) ;
323+ let bcx = drop_ty ( bcx, body_datum. to_ref_llval ( bcx) , body_datum. ty ) ;
324+ if ty:: type_contents ( bcx. tcx ( ) , t) . owns_managed ( ) {
325+ trans_free ( bcx, box_datum. val )
326+ } else {
327+ trans_exchange_free ( bcx, box_datum. val )
328+ }
329+ } )
392330 }
393331 ty:: ty_vec( _, ty:: vstore_uniq) | ty:: ty_str( ty:: vstore_uniq) |
394332 ty:: ty_vec( _, ty:: vstore_box) | ty:: ty_str( ty:: vstore_box) => {
395333 make_free_glue ( bcx, v, tvec:: expand_boxed_vec_ty ( bcx. tcx ( ) , t) )
396334 }
397335 ty:: ty_closure( _) => {
398- closure:: make_closure_glue ( bcx, v, t, free_ty )
336+ closure:: make_closure_glue ( bcx, v, t, make_free_glue )
399337 }
400338 ty:: ty_opaque_closure_ptr( ck) => {
401339 closure:: make_opaque_cbox_free_glue ( bcx, ck, v)
@@ -469,13 +407,14 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
469407 let _icx = push_ctxt ( "make_drop_glue" ) ;
470408 let ccx = bcx. ccx ( ) ;
471409 match ty:: get ( t) . sty {
472- ty:: ty_box( _) | ty:: ty_opaque_box |
410+ ty:: ty_opaque_box => bcx. tcx ( ) . sess . fatal ( "found ty_opaque_box in make_drop_glue" ) ,
411+ ty:: ty_box( _) |
473412 ty:: ty_str( ty:: vstore_box) | ty:: ty_vec( _, ty:: vstore_box) => {
474- decr_refcnt_maybe_free ( bcx, Load ( bcx , v0 ) , Some ( v0 ) , t )
413+ decr_refcnt_maybe_free ( bcx, v0 , Some ( t ) )
475414 }
476415 ty:: ty_uniq( _) |
477416 ty:: ty_vec( _, ty:: vstore_uniq) | ty:: ty_str( ty:: vstore_uniq) => {
478- free_ty ( bcx, v0, t)
417+ make_free_glue ( bcx, v0, t)
479418 }
480419 ty:: ty_unboxed_vec( _) => {
481420 tvec:: make_drop_glue_unboxed ( bcx, v0, t)
@@ -500,9 +439,7 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
500439 }
501440 ty:: ty_trait( _, _, ty:: BoxTraitStore , _, _) => {
502441 let llbox_ptr = GEPi ( bcx, v0, [ 0 u, abi:: trt_field_box] ) ;
503- let llbox = Load ( bcx, llbox_ptr) ;
504- decr_refcnt_maybe_free ( bcx, llbox, Some ( llbox_ptr) ,
505- ty:: mk_opaque_box ( ccx. tcx ) )
442+ decr_refcnt_maybe_free ( bcx, llbox_ptr, None )
506443 }
507444 ty:: ty_trait( _, _, ty:: UniqTraitStore , _, _) => {
508445 let lluniquevalue = GEPi ( bcx, v0, [ 0 , abi:: trt_field_box] ) ;
@@ -517,7 +454,7 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
517454 call_tydesc_glue_full ( bcx,
518455 lluniquevalue,
519456 lltydesc,
520- abi:: tydesc_field_free_glue ,
457+ abi:: tydesc_field_drop_glue ,
521458 None ) ;
522459 bcx
523460 } )
@@ -534,44 +471,46 @@ pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
534471 }
535472}
536473
537- // box_ptr_ptr is optional, it is constructed if not supplied.
538- pub fn decr_refcnt_maybe_free < ' a > (
539- bcx : & ' a Block < ' a > ,
540- box_ptr : ValueRef ,
541- box_ptr_ptr : Option < ValueRef > ,
542- t : ty:: t )
543- -> & ' a Block < ' a > {
474+ fn decr_refcnt_maybe_free < ' a > ( bcx : & ' a Block < ' a > , box_ptr_ptr : ValueRef ,
475+ t : Option < ty:: t > ) -> & ' a Block < ' a > {
544476 let _icx = push_ctxt ( "decr_refcnt_maybe_free" ) ;
545477 let ccx = bcx. ccx ( ) ;
546478
547479 let decr_bcx = sub_block ( bcx, "decr" ) ;
548480 let free_bcx = sub_block ( decr_bcx, "free" ) ;
549481 let next_bcx = sub_block ( bcx, "next" ) ;
482+ let box_ptr = Load ( bcx, box_ptr_ptr) ;
550483 let llnotnull = IsNotNull ( bcx, box_ptr) ;
551484 CondBr ( bcx, llnotnull, decr_bcx. llbb , next_bcx. llbb ) ;
552485
553486 let rc_ptr = GEPi ( decr_bcx, box_ptr, [ 0 u, abi:: box_field_refcnt] ) ;
554487 let rc = Sub ( decr_bcx, Load ( decr_bcx, rc_ptr) , C_int ( ccx, 1 ) ) ;
555488 Store ( decr_bcx, rc, rc_ptr) ;
556- let llisnull = IsNull ( decr_bcx, rc) ;
557- CondBr ( decr_bcx, llisnull, free_bcx. llbb , next_bcx. llbb ) ;
558-
559- let free_bcx = match box_ptr_ptr {
560- Some ( p) => free_ty ( free_bcx, p, t) ,
561- None => free_ty_immediate ( free_bcx, box_ptr, t)
489+ CondBr ( decr_bcx, IsNull ( decr_bcx, rc) , free_bcx. llbb , next_bcx. llbb ) ;
490+
491+ let free_bcx = match t {
492+ Some ( t) => make_free_glue ( free_bcx, box_ptr_ptr, t) ,
493+ None => {
494+ let v = Load ( free_bcx, box_ptr_ptr) ;
495+ let td = Load ( free_bcx, GEPi ( free_bcx, v, [ 0 u, abi:: box_field_tydesc] ) ) ;
496+ let valptr = GEPi ( free_bcx, v, [ 0 u, abi:: box_field_body] ) ;
497+ // Generate code that, dynamically, indexes into the
498+ // tydesc and calls the drop glue that got set dynamically
499+ call_tydesc_glue_full ( free_bcx, valptr, td, abi:: tydesc_field_drop_glue, None ) ;
500+ trans_free ( free_bcx, v)
501+ }
562502 } ;
563503 Br ( free_bcx, next_bcx. llbb ) ;
564504
565505 next_bcx
566506}
567507
568-
569- pub fn make_take_glue < ' a > ( bcx : & ' a Block < ' a > , v : ValueRef , t : ty:: t )
570- -> & ' a Block < ' a > {
508+ fn make_take_glue < ' a > ( bcx : & ' a Block < ' a > , v : ValueRef , t : ty:: t ) -> & ' a Block < ' a > {
571509 let _icx = push_ctxt ( "make_take_glue" ) ;
572510 // NB: v is a *pointer* to type t here, not a direct value.
573511 match ty:: get ( t) . sty {
574- ty:: ty_box( _) | ty:: ty_opaque_box |
512+ ty:: ty_opaque_box => bcx. tcx ( ) . sess . fatal ( "found ty_opaque_box in make_take_glue" ) ,
513+ ty:: ty_box( _) |
575514 ty:: ty_vec( _, ty:: vstore_box) | ty:: ty_str( ty:: vstore_box) => {
576515 incr_refcnt_of_boxed ( bcx, Load ( bcx, v) ) ; bcx
577516 }
@@ -608,7 +547,7 @@ pub fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
608547 }
609548}
610549
611- pub fn incr_refcnt_of_boxed ( cx : & Block , box_ptr : ValueRef ) {
550+ fn incr_refcnt_of_boxed ( cx : & Block , box_ptr : ValueRef ) {
612551 let _icx = push_ctxt ( "incr_refcnt_of_boxed" ) ;
613552 let ccx = cx. ccx ( ) ;
614553 let rc_ptr = GEPi ( cx, box_ptr, [ 0 u, abi:: box_field_refcnt] ) ;
@@ -665,7 +604,6 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info {
665604 name : ty_name,
666605 take_glue : Cell :: new ( None ) ,
667606 drop_glue : Cell :: new ( None ) ,
668- free_glue : Cell :: new ( None ) ,
669607 visit_glue : Cell :: new ( None ) ,
670608 } ;
671609 debug ! ( "--- declare_tydesc {}" , ppaux:: ty_to_str( ccx. tcx, t) ) ;
@@ -770,21 +708,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
770708 }
771709 }
772710 } ;
773- let free_glue =
774- match ti. free_glue . get ( ) {
775- None => {
776- ccx. stats . n_null_glues . set ( ccx. stats . n_null_glues . get ( ) +
777- 1 u) ;
778- C_null ( glue_fn_ty)
779- }
780- Some ( v) => {
781- unsafe {
782- ccx. stats . n_real_glues . set ( ccx. stats . n_real_glues . get ( ) +
783- 1 ) ;
784- llvm:: LLVMConstPointerCast ( v, glue_fn_ty. to_ref ( ) )
785- }
786- }
787- } ;
788711 let visit_glue =
789712 match ti. visit_glue . get ( ) {
790713 None => {
@@ -808,7 +731,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
808731 ti. align , // align
809732 take_glue, // take_glue
810733 drop_glue, // drop_glue
811- free_glue, // free_glue
812734 visit_glue, // visit_glue
813735 ti. borrow_offset , // borrow_offset
814736 ti. name ] ) ; // name
0 commit comments