@@ -771,11 +771,25 @@ where
771
771
} ) ;
772
772
}
773
773
774
- let mk_dyn_vtable = || {
774
+ let mk_dyn_vtable = |principal : Option < ty:: PolyExistentialTraitRef < ' tcx > > | {
775
+ let min_count = TyCtxt :: COMMON_VTABLE_ENTRIES . len ( )
776
+ // As the comment below notes, it's hard to get access to supertraits
777
+ // here. Supertraits currently are determined by resolving predicates.
778
+ // It's not clear that it's easy to do that here. So, for now, we're
779
+ // just increasing the vtable size by the local, direct vtable entries.
780
+ // We know that *at least* that many pointers will be needed,
781
+ // which is already a win for some cases. As an example, this lets LLVM
782
+ // better hoist vtable loads out of loops for calls to `&mut dyn FnMut`
783
+ // function arguments.
784
+ + principal
785
+ . map ( |principal| {
786
+ tcx. own_existential_vtable_entries ( principal. def_id ( ) ) . len ( )
787
+ } )
788
+ . unwrap_or ( 0 ) ;
775
789
Ty :: new_imm_ref (
776
790
tcx,
777
791
tcx. lifetimes . re_static ,
778
- Ty :: new_array ( tcx, tcx. types . usize , 3 ) ,
792
+ Ty :: new_array ( tcx, tcx. types . usize , min_count . try_into ( ) . unwrap ( ) ) ,
779
793
)
780
794
/* FIXME: use actual fn pointers
781
795
Warning: naively computing the number of entries in the
@@ -808,16 +822,16 @@ where
808
822
// `std::mem::uninitialized::<&dyn Trait>()`, for example.
809
823
if let ty:: Adt ( def, args) = metadata. kind ( )
810
824
&& Some ( def. did ( ) ) == tcx. lang_items ( ) . dyn_metadata ( )
811
- && args. type_at ( 0 ) . is_trait ( )
825
+ && let ty :: Dynamic ( data , _ , ty :: Dyn ) = args. type_at ( 0 ) . kind ( )
812
826
{
813
- mk_dyn_vtable ( )
827
+ mk_dyn_vtable ( data . principal ( ) )
814
828
} else {
815
829
metadata
816
830
}
817
831
} else {
818
832
match tcx. struct_tail_erasing_lifetimes ( pointee, cx. param_env ( ) ) . kind ( ) {
819
833
ty:: Slice ( _) | ty:: Str => tcx. types . usize ,
820
- ty:: Dynamic ( _ , _, ty:: Dyn ) => mk_dyn_vtable ( ) ,
834
+ ty:: Dynamic ( data , _, ty:: Dyn ) => mk_dyn_vtable ( data . principal ( ) ) ,
821
835
_ => bug ! ( "TyAndLayout::field({:?}): not applicable" , this) ,
822
836
}
823
837
} ;
0 commit comments