]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_session/code_stats.rs
Auto merge of #66899 - msizanoen1:riscv-std, r=alexcrichton
[rust.git] / src / librustc_session / code_stats.rs
index 5baf0c5948f28a5481a25ee1111f52494d9c7349..9b89c7ae32abc68470f63ca7bec42d8e8f83aab5 100644 (file)
@@ -1,7 +1,7 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lock;
 use rustc_target::abi::{Align, Size};
-use rustc_data_structures::fx::{FxHashSet};
 use std::cmp::{self, Ordering};
-use rustc_data_structures::sync::Lock;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct VariantInfo {
@@ -51,20 +51,20 @@ pub struct CodeStats {
 }
 
 impl CodeStats {
-    pub fn record_type_size<S: ToString>(&self,
-                                         kind: DataTypeKind,
-                                         type_desc: S,
-                                         align: Align,
-                                         overall_size: Size,
-                                         packed: bool,
-                                         opt_discr_size: Option<Size>,
-                                         mut variants: Vec<VariantInfo>) {
+    pub fn record_type_size<S: ToString>(
+        &self,
+        kind: DataTypeKind,
+        type_desc: S,
+        align: Align,
+        overall_size: Size,
+        packed: bool,
+        opt_discr_size: Option<Size>,
+        mut variants: Vec<VariantInfo>,
+    ) {
         // Sort variants so the largest ones are shown first. A stable sort is
         // used here so that source code order is preserved for all variants
         // that have the same size.
-        variants.sort_by(|info1, info2| {
-            info2.size.cmp(&info1.size)
-        });
+        variants.sort_by(|info1, info2| info2.size.cmp(&info1.size));
         let info = TypeSizeInfo {
             kind,
             type_description: type_desc.to_string(),
@@ -92,13 +92,14 @@ pub fn print_type_sizes(&self) {
         });
 
         for info in &sorted {
-            println!("print-type-size type: `{}`: {} bytes, alignment: {} bytes",
-                     info.type_description, info.overall_size, info.align);
+            println!(
+                "print-type-size type: `{}`: {} bytes, alignment: {} bytes",
+                info.type_description, info.overall_size, info.align
+            );
             let indent = "    ";
 
             let discr_size = if let Some(discr_size) = info.opt_discr_size {
-                println!("print-type-size {}discriminant: {} bytes",
-                         indent, discr_size);
+                println!("print-type-size {}discriminant: {} bytes", indent, discr_size);
                 discr_size
             } else {
                 0
@@ -121,8 +122,12 @@ pub fn print_type_sizes(&self) {
                         Some(name) => name.to_owned(),
                         None => i.to_string(),
                     };
-                    println!("print-type-size {}variant `{}`: {} bytes",
-                             indent, name, size - discr_size);
+                    println!(
+                        "print-type-size {}variant `{}`: {} bytes",
+                        indent,
+                        name,
+                        size - discr_size
+                    );
                     "        "
                 } else {
                     assert!(i < 1);
@@ -132,45 +137,56 @@ pub fn print_type_sizes(&self) {
 
                 let mut min_offset = discr_size;
 
-                // We want to print fields by increasing offset.
+                // We want to print fields by increasing offset. We also want
+                // zero-sized fields before non-zero-sized fields, otherwise
+                // the loop below goes wrong; hence the `f.size` in the sort
+                // key.
                 let mut fields = fields.clone();
-                fields.sort_by_key(|f| f.offset);
+                fields.sort_by_key(|f| (f.offset, f.size));
 
                 for field in fields.iter() {
                     let FieldInfo { ref name, offset, size, align } = *field;
 
                     if offset > min_offset {
                         let pad = offset - min_offset;
-                        println!("print-type-size {}padding: {} bytes",
-                                 indent, pad);
+                        println!("print-type-size {}padding: {} bytes", indent, pad);
                     }
 
                     if offset < min_offset {
-                        // if this happens something is very wrong
-                        println!("print-type-size {}field `.{}`: {} bytes, \
+                        // If this happens it's probably a union.
+                        println!(
+                            "print-type-size {}field `.{}`: {} bytes, \
                                   offset: {} bytes, \
                                   alignment: {} bytes",
-                                 indent, name, size, offset, align);
+                            indent, name, size, offset, align
+                        );
                     } else if info.packed || offset == min_offset {
-                        println!("print-type-size {}field `.{}`: {} bytes",
-                                 indent, name, size);
+                        println!("print-type-size {}field `.{}`: {} bytes", indent, name, size);
                     } else {
                         // Include field alignment in output only if it caused padding injection
-                        println!("print-type-size {}field `.{}`: {} bytes, \
+                        println!(
+                            "print-type-size {}field `.{}`: {} bytes, \
                                   alignment: {} bytes",
-                                 indent, name, size, align);
+                            indent, name, size, align
+                        );
                     }
 
                     min_offset = offset + size;
                 }
             }
 
-            assert!(max_variant_size <= info.overall_size,
-                    "max_variant_size {} !<= {} overall_size",
-                    max_variant_size, info.overall_size);
+            assert!(
+                max_variant_size <= info.overall_size,
+                "max_variant_size {} !<= {} overall_size",
+                max_variant_size,
+                info.overall_size
+            );
             if max_variant_size < info.overall_size {
-                println!("print-type-size {}end padding: {} bytes",
-                         indent, info.overall_size - max_variant_size);
+                println!(
+                    "print-type-size {}end padding: {} bytes",
+                    indent,
+                    info.overall_size - max_variant_size
+                );
             }
         }
     }