Extend -Z print-type-sizes
to distinguish generator upvars and locals from "normal" ADT fields.
This commit is contained in:
parent
a64ef7d07d
commit
a37b3061fc
3 changed files with 27 additions and 6 deletions
|
@ -19,8 +19,26 @@ pub enum SizeKind {
|
||||||
Min,
|
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)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct FieldInfo {
|
pub struct FieldInfo {
|
||||||
|
pub kind: FieldKind,
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
pub offset: u64,
|
pub offset: u64,
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
|
@ -145,7 +163,7 @@ impl CodeStats {
|
||||||
fields.sort_by_key(|f| (f.offset, f.size));
|
fields.sort_by_key(|f| (f.offset, f.size));
|
||||||
|
|
||||||
for field in fields {
|
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 {
|
if offset > min_offset {
|
||||||
let pad = offset - min_offset;
|
let pad = offset - min_offset;
|
||||||
|
@ -155,16 +173,16 @@ impl CodeStats {
|
||||||
if offset < min_offset {
|
if offset < min_offset {
|
||||||
// If this happens it's probably a union.
|
// If this happens it's probably a union.
|
||||||
println!(
|
println!(
|
||||||
"print-type-size {indent}field `.{name}`: {size} bytes, \
|
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \
|
||||||
offset: {offset} bytes, \
|
offset: {offset} bytes, \
|
||||||
alignment: {align} bytes"
|
alignment: {align} bytes"
|
||||||
);
|
);
|
||||||
} else if info.packed || offset == min_offset {
|
} 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 {
|
} else {
|
||||||
// Include field alignment in output only if it caused padding injection
|
// Include field alignment in output only if it caused padding injection
|
||||||
println!(
|
println!(
|
||||||
"print-type-size {indent}field `.{name}`: {size} bytes, \
|
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \
|
||||||
alignment: {align} bytes"
|
alignment: {align} bytes"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::cgu_reuse_tracker::CguReuseTracker;
|
use crate::cgu_reuse_tracker::CguReuseTracker;
|
||||||
use crate::code_stats::CodeStats;
|
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::Input;
|
||||||
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
|
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_middle::ty::layout::{
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable,
|
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::symbol::Symbol;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use rustc_target::abi::*;
|
use rustc_target::abi::*;
|
||||||
|
@ -881,6 +881,7 @@ fn variant_info_for_adt<'tcx>(
|
||||||
let offset = layout.fields.offset(i);
|
let offset = layout.fields.offset(i);
|
||||||
min_size = min_size.max(offset + field_layout.size);
|
min_size = min_size.max(offset + field_layout.size);
|
||||||
FieldInfo {
|
FieldInfo {
|
||||||
|
kind: FieldKind::AdtField,
|
||||||
name,
|
name,
|
||||||
offset: offset.bytes(),
|
offset: offset.bytes(),
|
||||||
size: field_layout.size.bytes(),
|
size: field_layout.size.bytes(),
|
||||||
|
@ -960,6 +961,7 @@ fn variant_info_for_generator<'tcx>(
|
||||||
let offset = layout.fields.offset(field_idx);
|
let offset = layout.fields.offset(field_idx);
|
||||||
upvars_size = upvars_size.max(offset + field_layout.size);
|
upvars_size = upvars_size.max(offset + field_layout.size);
|
||||||
FieldInfo {
|
FieldInfo {
|
||||||
|
kind: FieldKind::Upvar,
|
||||||
name: Symbol::intern(&name),
|
name: Symbol::intern(&name),
|
||||||
offset: offset.bytes(),
|
offset: offset.bytes(),
|
||||||
size: field_layout.size.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
|
// The struct is as large as the last field's end
|
||||||
variant_size = variant_size.max(offset + field_layout.size);
|
variant_size = variant_size.max(offset + field_layout.size);
|
||||||
FieldInfo {
|
FieldInfo {
|
||||||
|
kind: FieldKind::GeneratorLocal,
|
||||||
name: state_specific_names.get(*local).copied().flatten().unwrap_or(
|
name: state_specific_names.get(*local).copied().flatten().unwrap_or(
|
||||||
Symbol::intern(&format!(".generator_field{}", local.as_usize())),
|
Symbol::intern(&format!(".generator_field{}", local.as_usize())),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue