From a37b3061fce5a56d0ed11c79e2c887ab8aa56827 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 31 Jan 2023 15:59:29 -0500 Subject: [PATCH 1/3] Extend `-Z print-type-sizes` to distinguish generator upvars and locals from "normal" ADT fields. --- compiler/rustc_session/src/code_stats.rs | 26 ++++++++++++++++++++---- compiler/rustc_session/src/session.rs | 2 +- compiler/rustc_ty_utils/src/layout.rs | 5 ++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index 1085bce4475..f0cd7d9322b 100644 --- a/compiler/rustc_session/src/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs @@ -19,8 +19,26 @@ pub enum SizeKind { Min, } +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum FieldKind { + AdtField, + Upvar, + GeneratorLocal, +} + +impl std::fmt::Display for FieldKind { + fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FieldKind::AdtField => { write!(w, "field") } + FieldKind::Upvar => { write!(w, "upvar") } + FieldKind::GeneratorLocal => { write!(w, "local") } + } + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FieldInfo { + pub kind: FieldKind, pub name: Symbol, pub offset: u64, pub size: u64, @@ -145,7 +163,7 @@ impl CodeStats { fields.sort_by_key(|f| (f.offset, f.size)); for field in fields { - let FieldInfo { ref name, offset, size, align } = field; + let FieldInfo { kind, ref name, offset, size, align } = field; if offset > min_offset { let pad = offset - min_offset; @@ -155,16 +173,16 @@ impl CodeStats { if offset < min_offset { // If this happens it's probably a union. println!( - "print-type-size {indent}field `.{name}`: {size} bytes, \ + "print-type-size {indent}{kind} `.{name}`: {size} bytes, \ offset: {offset} bytes, \ alignment: {align} bytes" ); } else if info.packed || offset == min_offset { - println!("print-type-size {indent}field `.{name}`: {size} bytes"); + println!("print-type-size {indent}{kind} `.{name}`: {size} bytes"); } else { // Include field alignment in output only if it caused padding injection println!( - "print-type-size {indent}field `.{name}`: {size} bytes, \ + "print-type-size {indent}{kind} `.{name}`: {size} bytes, \ alignment: {align} bytes" ); } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 91d23f1041f..7cf9b0fd1fa 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,6 +1,6 @@ use crate::cgu_reuse_tracker::CguReuseTracker; use crate::code_stats::CodeStats; -pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; +pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::Input; use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath}; use crate::errors::{ diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 378cd5a99ed..93c9c675c9a 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::{ self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable, }; -use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; +use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; use rustc_target::abi::*; @@ -881,6 +881,7 @@ fn variant_info_for_adt<'tcx>( let offset = layout.fields.offset(i); min_size = min_size.max(offset + field_layout.size); FieldInfo { + kind: FieldKind::AdtField, name, offset: offset.bytes(), size: field_layout.size.bytes(), @@ -960,6 +961,7 @@ fn variant_info_for_generator<'tcx>( let offset = layout.fields.offset(field_idx); upvars_size = upvars_size.max(offset + field_layout.size); FieldInfo { + kind: FieldKind::Upvar, name: Symbol::intern(&name), offset: offset.bytes(), size: field_layout.size.bytes(), @@ -983,6 +985,7 @@ fn variant_info_for_generator<'tcx>( // The struct is as large as the last field's end variant_size = variant_size.max(offset + field_layout.size); FieldInfo { + kind: FieldKind::GeneratorLocal, name: state_specific_names.get(*local).copied().flatten().unwrap_or( Symbol::intern(&format!(".generator_field{}", local.as_usize())), ), From 91f1b224eeff3471dc77defc0a7a3b3eecf11abb Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 31 Jan 2023 17:08:17 -0500 Subject: [PATCH 2/3] placate tidy. --- compiler/rustc_session/src/code_stats.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index f0cd7d9322b..87dfccdef2f 100644 --- a/compiler/rustc_session/src/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs @@ -29,9 +29,9 @@ pub enum FieldKind { impl std::fmt::Display for FieldKind { fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - FieldKind::AdtField => { write!(w, "field") } - FieldKind::Upvar => { write!(w, "upvar") } - FieldKind::GeneratorLocal => { write!(w, "local") } + FieldKind::AdtField => write!(w, "field"), + FieldKind::Upvar => write!(w, "upvar"), + FieldKind::GeneratorLocal => write!(w, "local"), } } } From 362c4fa755a52891f79b00a0bac53b6a597f2b72 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 31 Jan 2023 20:00:54 -0500 Subject: [PATCH 3/3] Bless updated output from print-type-sizes tests. --- tests/ui/print_type_sizes/async.stdout | 12 ++++++------ tests/ui/print_type_sizes/generator.stdout | 8 ++++---- .../generator_discr_placement.stdout | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index 6e47bb4930d..4588c0ebd81 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -1,15 +1,15 @@ print-type-size type: `[async fn body@$DIR/async.rs:8:36: 11:2]`: 16386 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Suspend0`: 16385 bytes -print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes -print-type-size field `.arg`: 8192 bytes -print-type-size field `.__awaitee`: 1 bytes +print-type-size upvar `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size local `.arg`: 8192 bytes +print-type-size local `.__awaitee`: 1 bytes print-type-size variant `Unresumed`: 8192 bytes -print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size variant `Returned`: 8192 bytes -print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size variant `Panicked`: 8192 bytes -print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size field `.value`: 8192 bytes print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes diff --git a/tests/ui/print_type_sizes/generator.stdout b/tests/ui/print_type_sizes/generator.stdout index 28d4a6e6cff..13d850a6690 100644 --- a/tests/ui/print_type_sizes/generator.stdout +++ b/tests/ui/print_type_sizes/generator.stdout @@ -1,10 +1,10 @@ print-type-size type: `[generator@$DIR/generator.rs:10:5: 10:14]`: 8193 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 8192 bytes -print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size variant `Returned`: 8192 bytes -print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size variant `Panicked`: 8192 bytes -print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size variant `Suspend0`: 8192 bytes -print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size upvar `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes diff --git a/tests/ui/print_type_sizes/generator_discr_placement.stdout b/tests/ui/print_type_sizes/generator_discr_placement.stdout index 7f8f4ccae7c..b294b2d139c 100644 --- a/tests/ui/print_type_sizes/generator_discr_placement.stdout +++ b/tests/ui/print_type_sizes/generator_discr_placement.stdout @@ -2,10 +2,10 @@ print-type-size type: `[generator@$DIR/generator_discr_placement.rs:11:13: 11:15 print-type-size discriminant: 1 bytes print-type-size variant `Suspend0`: 7 bytes print-type-size padding: 3 bytes -print-type-size field `.w`: 4 bytes, alignment: 4 bytes +print-type-size local `.w`: 4 bytes, alignment: 4 bytes print-type-size variant `Suspend1`: 7 bytes print-type-size padding: 3 bytes -print-type-size field `.z`: 4 bytes, alignment: 4 bytes +print-type-size local `.z`: 4 bytes, alignment: 4 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes