Skip to content

Commit b9f1064

Browse files
Inline make_drop_glue
1 parent 6a1ec55 commit b9f1064

File tree

1 file changed

+74
-82
lines changed

1 file changed

+74
-82
lines changed

src/librustc_trans/glue.rs

Lines changed: 74 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,80 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
200200
// llfn is expected be declared to take a parameter of the appropriate
201201
// type, so we don't need to explicitly cast the function parameter.
202202

203-
let bcx = make_drop_glue(bcx, get_param(llfn, 0), g);
203+
// NB: v0 is an *alias* of type t here, not a direct value.
204+
// Only drop the value when it ... well, we used to check for
205+
// non-null, (and maybe we need to continue doing so), but we now
206+
// must definitely check for special bit-patterns corresponding to
207+
// the special dtor markings.
208+
let v0 = get_param(llfn, 0);
209+
let t = g.ty();
210+
211+
let skip_dtor = match g {
212+
DropGlueKind::Ty(_) => false,
213+
DropGlueKind::TyContents(_) => true
214+
};
215+
216+
let bcx = match t.sty {
217+
ty::TyBox(content_ty) => {
218+
// Support for TyBox is built-in and its drop glue is
219+
// special. It may move to library and have Drop impl. As
220+
// a safe-guard, assert TyBox not used with TyContents.
221+
assert!(!skip_dtor);
222+
if !bcx.ccx.shared().type_is_sized(content_ty) {
223+
let llval = get_dataptr(&bcx, v0);
224+
let llbox = bcx.load(llval);
225+
drop_ty(&bcx, v0, content_ty);
226+
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
227+
let info = get_meta(&bcx, v0);
228+
let info = bcx.load(info);
229+
let (llsize, llalign) = size_and_align_of_dst(&bcx, content_ty, info);
230+
231+
// `Box<ZeroSizeType>` does not allocate.
232+
let needs_free = bcx.icmp(llvm::IntNE, llsize, C_uint(bcx.ccx, 0u64));
233+
if const_to_opt_uint(needs_free) == Some(0) {
234+
bcx
235+
} else {
236+
let next_cx = bcx.fcx().build_new_block("next");
237+
let cond_cx = bcx.fcx().build_new_block("cond");
238+
bcx.cond_br(needs_free, cond_cx.llbb(), next_cx.llbb());
239+
trans_exchange_free_dyn(&cond_cx, llbox, llsize, llalign);
240+
cond_cx.br(next_cx.llbb());
241+
next_cx
242+
}
243+
} else {
244+
let llval = v0;
245+
let llbox = bcx.load(llval);
246+
drop_ty(&bcx, llbox, content_ty);
247+
trans_exchange_free_ty(&bcx, llbox, content_ty);
248+
bcx
249+
}
250+
}
251+
ty::TyDynamic(..) => {
252+
// No support in vtable for distinguishing destroying with
253+
// versus without calling Drop::drop. Assert caller is
254+
// okay with always calling the Drop impl, if any.
255+
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
256+
assert!(!skip_dtor);
257+
let data_ptr = get_dataptr(&bcx, v0);
258+
let vtable_ptr = bcx.load(get_meta(&bcx, v0));
259+
let dtor = bcx.load(vtable_ptr);
260+
bcx.call(dtor, &[bcx.pointercast(bcx.load(data_ptr), Type::i8p(bcx.ccx))], None);
261+
bcx
262+
}
263+
ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => {
264+
trans_custom_dtor(bcx, t, v0, def.is_union())
265+
}
266+
ty::TyAdt(def, ..) if def.is_union() => {
267+
bcx
268+
}
269+
_ => {
270+
if bcx.ccx.shared().type_needs_drop(t) {
271+
drop_structural_ty(bcx, v0, t)
272+
} else {
273+
bcx
274+
}
275+
}
276+
};
204277
bcx.ret_void();
205278
}
206279

@@ -373,87 +446,6 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
373446
}
374447
}
375448

376-
fn make_drop_glue<'a, 'tcx>(bcx: BlockAndBuilder<'a, 'tcx>,
377-
v0: ValueRef,
378-
g: DropGlueKind<'tcx>)
379-
-> BlockAndBuilder<'a, 'tcx> {
380-
let t = g.ty();
381-
382-
let skip_dtor = match g { DropGlueKind::Ty(_) => false, DropGlueKind::TyContents(_) => true };
383-
// NB: v0 is an *alias* of type t here, not a direct value.
384-
// Only drop the value when it ... well, we used to check for
385-
// non-null, (and maybe we need to continue doing so), but we now
386-
// must definitely check for special bit-patterns corresponding to
387-
// the special dtor markings.
388-
389-
match t.sty {
390-
ty::TyBox(content_ty) => {
391-
// Support for TyBox is built-in and its drop glue is
392-
// special. It may move to library and have Drop impl. As
393-
// a safe-guard, assert TyBox not used with TyContents.
394-
assert!(!skip_dtor);
395-
if !bcx.ccx.shared().type_is_sized(content_ty) {
396-
let llval = get_dataptr(&bcx, v0);
397-
let llbox = bcx.load(llval);
398-
drop_ty(&bcx, v0, content_ty);
399-
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
400-
let info = get_meta(&bcx, v0);
401-
let info = bcx.load(info);
402-
let (llsize, llalign) = size_and_align_of_dst(&bcx, content_ty, info);
403-
404-
// `Box<ZeroSizeType>` does not allocate.
405-
let needs_free = bcx.icmp(
406-
llvm::IntNE,
407-
llsize,
408-
C_uint(bcx.ccx, 0u64),
409-
);
410-
if const_to_opt_uint(needs_free) == Some(0) {
411-
bcx
412-
} else {
413-
let fcx = bcx.fcx();
414-
let next_cx = fcx.build_new_block("next");
415-
let cond_cx = fcx.build_new_block("cond");
416-
bcx.cond_br(needs_free, cond_cx.llbb(), next_cx.llbb());
417-
trans_exchange_free_dyn(&cond_cx, llbox, llsize, llalign);
418-
cond_cx.br(next_cx.llbb());
419-
next_cx
420-
}
421-
} else {
422-
let llval = v0;
423-
let llbox = bcx.load(llval);
424-
drop_ty(&bcx, llbox, content_ty);
425-
trans_exchange_free_ty(&bcx, llbox, content_ty);
426-
bcx
427-
}
428-
}
429-
ty::TyDynamic(..) => {
430-
// No support in vtable for distinguishing destroying with
431-
// versus without calling Drop::drop. Assert caller is
432-
// okay with always calling the Drop impl, if any.
433-
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
434-
assert!(!skip_dtor);
435-
let data_ptr = get_dataptr(&bcx, v0);
436-
let vtable_ptr = bcx.load(get_meta(&bcx, v0));
437-
let dtor = bcx.load(vtable_ptr);
438-
bcx.call(dtor, &[bcx.pointercast(bcx.load(data_ptr), Type::i8p(bcx.ccx))], None);
439-
bcx
440-
}
441-
ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => {
442-
trans_custom_dtor(bcx, t, v0, def.is_union())
443-
}
444-
ty::TyAdt(def, ..) if def.is_union() => {
445-
bcx
446-
}
447-
_ => {
448-
if bcx.ccx.shared().type_needs_drop(t) {
449-
drop_structural_ty(bcx, v0, t)
450-
} else {
451-
bcx
452-
}
453-
}
454-
}
455-
}
456-
457449
// Iterates through the elements of a structural type, dropping them.
458450
fn drop_structural_ty<'a, 'tcx>(cx: BlockAndBuilder<'a, 'tcx>,
459451
av: ValueRef,

0 commit comments

Comments
 (0)