@@ -20,9 +20,11 @@ use crate::llvm::debuginfo::{
2020use crate :: value:: Value ;
2121
2222use cstr:: cstr;
23+ use inlinable_string:: InlinableString ;
2324use rustc_codegen_ssa:: debuginfo:: type_names:: cpp_like_debuginfo;
2425use rustc_codegen_ssa:: debuginfo:: type_names:: VTableNameKind ;
2526use rustc_codegen_ssa:: traits:: * ;
27+ use rustc_data_structures:: base_n;
2628use rustc_data_structures:: fx:: FxHashMap ;
2729use rustc_fs_util:: path_to_c_string;
2830use rustc_hir:: def:: CtorKind ;
@@ -93,8 +95,23 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
9395
9496pub const NO_SCOPE_METADATA : Option < & DIScope > = None ;
9597
98+ /// Same as format!() but produces an InlinableString to avoid
99+ /// unnecessary memory allocations.
100+ macro_rules! format_inline {
101+ ( $( $tokens: expr) ,* ) => {
102+ {
103+ use inlinable_string:: StringExt ;
104+ let mut string = inlinable_string:: InlinableString :: new( ) ;
105+ write!( & mut string, $( $tokens) ,* ) . unwrap( ) ;
106+ string
107+ }
108+ } ;
109+ }
110+
96111mod unique_type_id {
112+ use inlinable_string:: InlinableString ;
97113 use rustc_data_structures:: {
114+ base_n,
98115 fingerprint:: Fingerprint ,
99116 stable_hasher:: { HashStable , NodeIdHashingMode , StableHasher } ,
100117 } ;
@@ -163,15 +180,16 @@ mod unique_type_id {
163180 UniqueTypeId :: VTableTy ( self_type, implemented_trait, HiddenZst { _inaccessible : ( ) } )
164181 }
165182
166- pub fn to_string ( & self , tcx : TyCtxt < ' tcx > ) -> String {
183+ pub fn to_string ( & self , tcx : TyCtxt < ' tcx > ) -> InlinableString {
167184 let mut hasher = StableHasher :: new ( ) ;
168185 let mut hcx = tcx. create_stable_hashing_context ( ) ;
169186 hcx. while_hashing_spans ( false , |hcx| {
170187 hcx. with_node_id_hashing_mode ( NodeIdHashingMode :: HashDefPath , |hcx| {
171188 self . hash_stable ( hcx, & mut hasher) ;
172189 } ) ;
173190 } ) ;
174- hasher. finish :: < Fingerprint > ( ) . to_hex ( )
191+ let ( low, high) = hasher. finish :: < Fingerprint > ( ) . as_value ( ) ;
192+ base_n:: encode ( ( low as u128 ) | ( ( high as u128 ) << 64 ) , base_n:: MAX_BASE )
175193 }
176194 }
177195}
@@ -884,7 +902,7 @@ fn foreign_type_metadata<'ll, 'tcx>(
884902
885903fn param_type_metadata < ' ll , ' tcx > ( cx : & CodegenCx < ' ll , ' tcx > , t : Ty < ' tcx > ) -> & ' ll DIType {
886904 debug ! ( "param_type_metadata: {:?}" , t) ;
887- let name = format ! ( "{:?}" , t) ;
905+ let name = format_inline ! ( "{:?}" , t) ;
888906 unsafe {
889907 llvm:: LLVMRustDIBuilderCreateBasicType (
890908 DIB ( cx) ,
@@ -1077,7 +1095,7 @@ struct SourceInfo<'ll> {
10771095/// structs or tuples) or an enum variant.
10781096#[ derive( Debug ) ]
10791097struct MemberDescription < ' ll > {
1080- name : String ,
1098+ name : InlinableString ,
10811099 type_metadata : & ' ll DIType ,
10821100 offset : Size ,
10831101 size : Size ,
@@ -1162,9 +1180,9 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
11621180 . enumerate ( )
11631181 . map ( |( i, f) | {
11641182 let name = if self . variant . ctor_kind == CtorKind :: Fn {
1165- format ! ( "__{}" , i)
1183+ format_inline ! ( "__{}" , i)
11661184 } else {
1167- f. name . to_string ( )
1185+ f. name . as_str ( ) . into ( )
11681186 } ;
11691187 let field = layout. field ( cx, i) ;
11701188 MemberDescription {
@@ -1227,7 +1245,10 @@ fn prepare_struct_metadata<'ll, 'tcx>(
12271245/// Here are some examples:
12281246/// - `name__field1__field2` when the upvar is captured by value.
12291247/// - `_ref__name__field` when the upvar is captured by reference.
1230- fn closure_saved_names_of_captured_variables ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Vec < String > {
1248+ fn closure_saved_names_of_captured_variables (
1249+ tcx : TyCtxt < ' _ > ,
1250+ def_id : DefId ,
1251+ ) -> Vec < InlinableString > {
12311252 let body = tcx. optimized_mir ( def_id) ;
12321253
12331254 body. var_debug_info
@@ -1242,7 +1263,7 @@ fn closure_saved_names_of_captured_variables(tcx: TyCtxt<'_>, def_id: DefId) ->
12421263 _ => return None ,
12431264 } ;
12441265 let prefix = if is_ref { "_ref__" } else { "" } ;
1245- Some ( prefix . to_owned ( ) + var. name . as_str ( ) )
1266+ Some ( format_inline ! ( "{}{}" , prefix , var. name) )
12461267 } )
12471268 . collect :: < Vec < _ > > ( )
12481269}
@@ -1273,7 +1294,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
12731294 let name = if let Some ( names) = capture_names. as_mut ( ) {
12741295 names. next ( ) . unwrap ( )
12751296 } else {
1276- format ! ( "__{}" , i)
1297+ format_inline ! ( "__{}" , i)
12771298 } ;
12781299 MemberDescription {
12791300 name,
@@ -1345,7 +1366,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
13451366 . map ( |( i, f) | {
13461367 let field = self . layout . field ( cx, i) ;
13471368 MemberDescription {
1348- name : f. name . to_string ( ) ,
1369+ name : f. name . as_str ( ) . into ( ) ,
13491370 type_metadata : type_metadata ( cx, field. ty ) ,
13501371 offset : Size :: ZERO ,
13511372 size : field. size ,
@@ -1563,7 +1584,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
15631584
15641585 MemberDescription {
15651586 name : if fallback {
1566- format ! ( "variant{}" , i. as_u32( ) )
1587+ format_inline ! ( "variant{}" , i. as_u32( ) )
15671588 } else {
15681589 variant_info. variant_name ( )
15691590 } ,
@@ -1697,7 +1718,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
16971718 vec ! [
16981719 MemberDescription {
16991720 // Name the dataful variant so that we can identify it for natvis
1700- name: "dataful_variant" . to_string ( ) ,
1721+ name: "dataful_variant" . into ( ) ,
17011722 type_metadata: variant_type_metadata,
17021723 offset: Size :: ZERO ,
17031724 size: self . layout. size,
@@ -1762,7 +1783,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
17621783struct VariantMemberDescriptionFactory < ' tcx > {
17631784 /// Cloned from the `layout::Struct` describing the variant.
17641785 offsets : Vec < Size > ,
1765- args : Vec < ( String , Ty < ' tcx > ) > ,
1786+ args : Vec < ( InlinableString , Ty < ' tcx > ) > ,
17661787}
17671788
17681789impl < ' tcx > VariantMemberDescriptionFactory < ' tcx > {
@@ -1776,7 +1797,7 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
17761797 . map ( |( i, & ( ref name, ty) ) | {
17771798 let ( size, align) = cx. size_and_align_of ( ty) ;
17781799 MemberDescription {
1779- name : name. to_string ( ) ,
1800+ name : name. clone ( ) ,
17801801 type_metadata : type_metadata ( cx, ty) ,
17811802 offset : self . offsets [ i] ,
17821803 size,
@@ -1819,20 +1840,20 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
18191840 }
18201841 }
18211842
1822- fn variant_name ( & self ) -> String {
1843+ fn variant_name ( & self ) -> InlinableString {
18231844 match self {
1824- VariantInfo :: Adt ( variant, _) => variant. name . to_string ( ) ,
1845+ VariantInfo :: Adt ( variant, _) => variant. name . as_str ( ) . into ( ) ,
18251846 VariantInfo :: Generator { variant_index, .. } => {
18261847 // Since GDB currently prints out the raw discriminant along
18271848 // with every variant, make each variant name be just the value
18281849 // of the discriminant. The struct name for the variant includes
18291850 // the actual variant description.
1830- format ! ( "{}" , variant_index. as_usize( ) )
1851+ base_n :: encode ( variant_index. as_usize ( ) as u128 , 10 )
18311852 }
18321853 }
18331854 }
18341855
1835- fn field_name ( & self , i : usize ) -> String {
1856+ fn field_name ( & self , i : usize ) -> InlinableString {
18361857 let field_name = match * self {
18371858 VariantInfo :: Adt ( variant, _) if variant. ctor_kind != CtorKind :: Fn => {
18381859 Some ( variant. fields [ i] . name )
@@ -1848,7 +1869,7 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
18481869 }
18491870 _ => None ,
18501871 } ;
1851- field_name. map ( |name| name. to_string ( ) ) . unwrap_or_else ( || format ! ( "__{}" , i) )
1872+ field_name. map ( |name| name. as_str ( ) . into ( ) ) . unwrap_or_else ( || format_inline ! ( "__{}" , i) )
18521873 }
18531874
18541875 fn source_info < ' ll > ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Option < SourceInfo < ' ll > > {
@@ -2532,19 +2553,19 @@ fn vtable_type_metadata<'ll, 'tcx>(
25322553 . filter_map ( |( index, vtable_entry) | {
25332554 let ( field_name, field_type) = match vtable_entry {
25342555 ty:: VtblEntry :: MetadataDropInPlace => {
2535- ( "drop_in_place" . to_string ( ) , void_pointer_type_debuginfo)
2556+ ( "drop_in_place" . into ( ) , void_pointer_type_debuginfo)
25362557 }
25372558 ty:: VtblEntry :: Method ( _) => {
25382559 // Note: This code does not try to give a proper name to each method
25392560 // because their might be multiple methods with the same name
25402561 // (coming from different traits).
2541- ( format ! ( "__method{}" , index) , void_pointer_type_debuginfo)
2562+ ( format_inline ! ( "__method{}" , index) , void_pointer_type_debuginfo)
25422563 }
25432564 ty:: VtblEntry :: TraitVPtr ( _) => {
2544- ( format ! ( "__super_trait_ptr{}" , index) , void_pointer_type_debuginfo)
2565+ ( format_inline ! ( "__super_trait_ptr{}" , index) , void_pointer_type_debuginfo)
25452566 }
2546- ty:: VtblEntry :: MetadataAlign => ( "align" . to_string ( ) , usize_debuginfo) ,
2547- ty:: VtblEntry :: MetadataSize => ( "size" . to_string ( ) , usize_debuginfo) ,
2567+ ty:: VtblEntry :: MetadataAlign => ( "align" . into ( ) , usize_debuginfo) ,
2568+ ty:: VtblEntry :: MetadataSize => ( "size" . into ( ) , usize_debuginfo) ,
25482569 ty:: VtblEntry :: Vacant => return None ,
25492570 } ;
25502571
0 commit comments