also sort by stack size

This commit is contained in:
Folkert 2021-08-07 13:08:55 +02:00
parent 3ca2140b69
commit c09acb255c
2 changed files with 34 additions and 11 deletions

View file

@ -1210,21 +1210,34 @@ fn layout_from_flat_type<'a>(
Record(fields, ext_var) => { Record(fields, ext_var) => {
// extract any values from the ext_var // extract any values from the ext_var
let variables = fields let pairs_it = fields
.sorted_iterator(subs, ext_var) .unsorted_iterator(subs, ext_var)
.filter_map(|(_, field)| { .filter_map(|(label, field)| {
// drop optional fields // drop optional fields
match field { let var = match field {
RecordField::Optional(_) => None, RecordField::Optional(_) => return None,
RecordField::Required(var) => Some(var), RecordField::Required(var) => var,
RecordField::Demanded(var) => Some(var), RecordField::Demanded(var) => var,
} };
Some((
label,
Layout::from_var(env, var).expect("invalid layout from var"),
))
}); });
let layouts_it = let mut pairs = Vec::from_iter_in(pairs_it, arena);
variables.map(|var| Layout::from_var(env, var).expect("invalid layout from var"));
let mut layouts = Vec::from_iter_in(layouts_it, arena); pairs.sort_by(|(label1, layout1), (label2, layout2)| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes);
size2.cmp(&size1).then(label1.cmp(label2))
});
let mut layouts = Vec::from_iter_in(pairs.into_iter().map(|t| t.1), arena);
if layouts.len() == 1 { if layouts.len() == 1 {
// If the record has only one field that isn't zero-sized, // If the record has only one field that isn't zero-sized,

View file

@ -926,6 +926,16 @@ impl RecordFields {
field_types_start, field_types_start,
} }
} }
#[inline(always)]
pub fn unsorted_iterator<'a>(
&'a self,
subs: &'a Subs,
ext: Variable,
) -> impl Iterator<Item = (&Lowercase, RecordField<Variable>)> + 'a {
let (it, _) = crate::types::gather_fields_unsorted_iter(subs, *self, ext);
it
}
/// Get a sorted iterator over the fields of this record type /// Get a sorted iterator over the fields of this record type
/// ///