Skip to content

Commit 9ddcc59

Browse files
Omit non-needs_drop drop_in_place in vtables
This replaces the drop_in_place reference with null in vtables. On librustc_driver.so, this drops about ~17k dynamic relocations from the output, since many vtables can now be placed in read-only memory, rather than having a relocated pointer included. This makes a tradeoff by adding a null check at vtable call sites. That's hard to avoid without changing the vtable format (e.g., to use a pc-relative relocation instead of an absolute address, and avoid the dynamic relocation that way). But it seems likely that the check is cheap at runtime.
1 parent 05b1415 commit 9ddcc59

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/abi/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ pub(crate) fn codegen_drop<'tcx>(
593593
fx: &mut FunctionCx<'_, '_, 'tcx>,
594594
source_info: mir::SourceInfo,
595595
drop_place: CPlace<'tcx>,
596+
target: BasicBlock,
596597
) {
597598
let ty = drop_place.layout().ty;
598599
let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx);
@@ -620,6 +621,12 @@ pub(crate) fn codegen_drop<'tcx>(
620621
let ptr = ptr.get_addr(fx);
621622
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable);
622623

624+
let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0);
625+
let target_block = fx.get_block(target);
626+
let continued = fx.bcx.create_block();
627+
fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]);
628+
fx.bcx.switch_to_block(continued);
629+
623630
// FIXME(eddyb) perhaps move some of this logic into
624631
// `Instance::resolve_drop_in_place`?
625632
let virtual_drop = Instance {
@@ -659,6 +666,12 @@ pub(crate) fn codegen_drop<'tcx>(
659666
let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx);
660667
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable);
661668

669+
let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0);
670+
let target_block = fx.get_block(target);
671+
let continued = fx.bcx.create_block();
672+
fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]);
673+
fx.bcx.switch_to_block(continued);
674+
662675
let virtual_drop = Instance {
663676
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
664677
args: drop_instance.args,
@@ -697,4 +710,7 @@ pub(crate) fn codegen_drop<'tcx>(
697710
}
698711
}
699712
}
713+
714+
let target_block = fx.get_block(target);
715+
fx.bcx.ins().jump(target_block, &[]);
700716
}

src/base.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
548548
}
549549
TerminatorKind::Drop { place, target, unwind: _, replace: _ } => {
550550
let drop_place = codegen_place(fx, *place);
551-
crate::abi::codegen_drop(fx, source_info, drop_place);
552-
553-
let target_block = fx.get_block(*target);
554-
fx.bcx.ins().jump(target_block, &[]);
551+
crate::abi::codegen_drop(fx, source_info, drop_place, *target);
555552
}
556553
};
557554
}

0 commit comments

Comments
 (0)