Skip to content

Commit

Permalink
refactor: remove trailing_pad.
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Jul 30, 2024
1 parent 2871b59 commit 89ae563
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 95 deletions.
16 changes: 4 additions & 12 deletions tasks/ast_codegen/src/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ pub struct StructDef {
pub has_lifetime: bool,
pub size_64: usize,
pub align_64: usize,
pub headroom_64: usize,
pub size_32: usize,
pub align_32: usize,
pub headroom_32: usize,
}

#[derive(Debug, Serialize)]
Expand All @@ -40,10 +38,8 @@ pub struct EnumDef {
pub has_lifetime: bool,
pub size_64: usize,
pub align_64: usize,
pub headroom_64: usize,
pub size_32: usize,
pub align_32: usize,
pub headroom_32: usize,
}

#[derive(Debug, Serialize)]
Expand Down Expand Up @@ -78,11 +74,11 @@ impl From<&RType> for Option<TypeDef> {

impl From<&REnum> for EnumDef {
fn from(it @ REnum { item, meta }: &REnum) -> Self {
let (size_64, align_64, headroom_64) = meta
let (size_64, align_64) = meta
.layout_64
.layout()
.map_or_else(|| panic!("Uncalculated layout on {}!", item.ident), KnownLayout::unpack);
let (size_32, align_32, headroom_32) = meta
let (size_32, align_32) = meta
.layout_32
.layout()
.map_or_else(|| panic!("Uncalculated layout on {}!", item.ident), KnownLayout::unpack);
Expand All @@ -94,21 +90,19 @@ impl From<&REnum> for EnumDef {

size_64,
align_64,
headroom_64,
size_32,
align_32,
headroom_32,
}
}
}

impl From<&RStruct> for StructDef {
fn from(it @ RStruct { item, meta }: &RStruct) -> Self {
let (size_64, align_64, headroom_64) = meta
let (size_64, align_64) = meta
.layout_64
.layout()
.map_or_else(|| panic!("Uncalculated layout on {}!", item.ident), KnownLayout::unpack);
let (size_32, align_32, headroom_32) = meta
let (size_32, align_32) = meta
.layout_32
.layout()
.map_or_else(|| panic!("Uncalculated layout on {}!", item.ident), KnownLayout::unpack);
Expand All @@ -119,10 +113,8 @@ impl From<&RStruct> for StructDef {

size_64,
align_64,
headroom_64,
size_32,
align_32,
headroom_32,
}
}
}
Expand Down
130 changes: 47 additions & 83 deletions tasks/ast_codegen/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub enum Layout {
}

impl Layout {
const fn known(size: usize, align: usize, trailing_pad: usize, niches: u128) -> Self {
Self::Layout(KnownLayout { size, align, trailing_pad, niches })
const fn known(size: usize, align: usize, niches: u128) -> Self {
Self::Layout(KnownLayout { size, align, niches })
}

pub fn layout(self) -> Option<KnownLayout> {
Expand All @@ -65,8 +65,6 @@ impl From<KnownLayout> for Layout {
pub struct KnownLayout {
size: usize,
align: usize,
/// padding at the end of type to align it
trailing_pad: usize,
/// number of available niches
niches: u128,
}
Expand All @@ -82,12 +80,6 @@ impl KnownLayout {
self.align
}

/// padding at the end of type to align it
#[inline]
pub fn trailing_pad(&self) -> usize {
self.trailing_pad
}

/// number of available niches
#[inline]
pub fn niches(&self) -> u128 {
Expand All @@ -96,33 +88,29 @@ impl KnownLayout {

/// Panics
/// if doesn't have enough viable space and `can_resize` is false
pub fn consume_trailing_pad(&mut self, size: usize) {
self.trailing_pad -= size;
}

/// Panics
/// if doesn't have enough viable space and `can_resize` is false
pub fn consume_niches(&mut self, n: u128, can_eat_pad: bool, can_resize: bool) {
pub fn consume_niches(&mut self, n: u128, can_resize: bool) {
if self.niches() >= n {
self.niches -= 1;
} else if can_eat_pad && self.trailing_pad() > 0 {
// consume one byte of padding at the end
self.consume_trailing_pad(1);
// consume one and add the remaining values of one byte as niches.
self.niches = (u8::MAX - 1) as u128;
} else if can_resize {
let align = self.align();
self.size += align;
self.trailing_pad += align;
self.consume_niches(n, can_eat_pad, can_resize);
self.niches += match align {
1 => u8::MAX as u128,
2 => u16::MAX as u128,
4 => u32::MAX as u128,
8 => u64::MAX as u128,
16 => u128::MAX as u128,
_ => unreachable!("We do not support paddings bigger than 16 bytes."),
};
self.consume_niches(n, can_resize);
} else {
panic!("`{}` called on a layout without enough space.", stringify!(consume_niches));
}
}

pub fn unpack(self) -> (/* size */ usize, /* align */ usize, /* trailing_pad */ usize) {
let Self { size, align, trailing_pad, .. } = self;
(size, align, trailing_pad)
pub fn unpack(self) -> (/* size */ usize, /* align */ usize) {
let Self { size, align, .. } = self;
(size, align)
}
}

Expand Down Expand Up @@ -168,7 +156,7 @@ impl Layout {
// NOTE: some or all of `niches` might be `trailing_pad` but we don't need to
// distinguish between them. This method is only used to get layout info of simple types.
// most of them are builtin primitives.
Self::known(size, align, 0, niches)
Self::known(size, align, niches)
}

const fn zero() -> Self {
Expand All @@ -178,15 +166,15 @@ impl Layout {
}

const fn ptr_32() -> Self {
Layout::known(4, 4, 0, 0)
Layout::known(4, 4, 0)
}

const fn ptr_64() -> Self {
Layout::known(8, 8, 0, 0)
Layout::known(8, 8, 0)
}

const fn wide_ptr_32() -> Self {
Layout::known(8, 4, 0, 1)
Layout::known(8, 4, 1)
}

const fn wide_ptr_64() -> Self {
Expand Down Expand Up @@ -243,9 +231,7 @@ fn calc_enum_layout(ty: &mut REnum, ctx: &CodegenCtx) -> Result<PlatformLayout>
// all unit variants?
if ty.item.variants.iter().all(|var| var.fields.is_empty()) {
// all AST enums are `repr(C)` so it would have a 4 byte layout/alignment,
let mut layout = KnownLayout { size: 0, align: 4, trailing_pad: 0, niches: 0 };
layout.consume_niches(ty.item.variants.len() as u128, true, true);
let layout = Layout::Layout(layout);
let layout = Layout::known(0, 4, 0);
Ok(vec![PlatformLayout(layout, layout)])
} else {
ty.item
Expand All @@ -269,10 +255,6 @@ fn calc_enum_layout(ty: &mut REnum, ctx: &CodegenCtx) -> Result<PlatformLayout>
if layout.size > acc.size {
acc.size = layout.size;
}
// min trailing_pad
if layout.trailing_pad() < acc.trailing_pad() {
acc.trailing_pad = layout.trailing_pad();
}
// min niches
if layout.niches() < acc.niches() {
acc.niches = layout.niches();
Expand All @@ -281,7 +263,7 @@ fn calc_enum_layout(ty: &mut REnum, ctx: &CodegenCtx) -> Result<PlatformLayout>
}

let with_tag = |mut acc: KnownLayout| -> KnownLayout {
acc.consume_niches(ty.item.variants.len() as u128, true, true);
acc.consume_niches(ty.item.variants.len() as u128, true);
acc
};

Expand All @@ -294,16 +276,8 @@ fn calc_enum_layout(ty: &mut REnum, ctx: &CodegenCtx) -> Result<PlatformLayout>
.collect::<Option<_>>()
.expect("already checked.");

let x32 =
with_tag(layouts_x32.into_iter().fold(
KnownLayout { size: 0, align: 0, trailing_pad: usize::MAX, niches: 0 },
fold_layout,
));
let x64 =
with_tag(layouts_x64.into_iter().fold(
KnownLayout { size: 0, align: 0, trailing_pad: usize::MAX, niches: 0 },
fold_layout,
));
let x32 = with_tag(layouts_x32.into_iter().fold(KnownLayout::default(), fold_layout));
let x64 = with_tag(layouts_x64.into_iter().fold(KnownLayout::default(), fold_layout));
Ok(PlatformLayout(Layout::from(x64), Layout::from(x32)))
}

Expand Down Expand Up @@ -337,18 +311,8 @@ fn calc_struct_layout(ty: &mut RStruct, ctx: &CodegenCtx) -> Result<PlatformLayo
offsets.push(offset);
niches += layout.niches();
}
// TODO: use `std::alloc::Layout::padding_needed_for` when it stabilized
let (pad, output) = {
let aligned = output.pad_to_align();
// padding_needed_for:
(aligned.size() - output.size(), aligned)
};
Ok(KnownLayout {
size: output.size(),
align: output.align(),
trailing_pad: pad + layouts.last().map(KnownLayout::trailing_pad).unwrap_or_default(),
niches,
})
let output = output.pad_to_align();
Ok(KnownLayout { size: output.size(), align: output.align(), niches })
}

let layouts = collect_field_layouts(ty, ctx)?;
Expand Down Expand Up @@ -384,7 +348,7 @@ fn calc_type_layout(ty: &TypeAnalyzeResult, ctx: &CodegenCtx) -> Result<Platform
fn try_fold_option(layout: Layout) -> Layout {
let Layout::Layout(mut known) = layout else { return layout };
// option needs only one bit to store its tag and it can be in a fragmented offset
known.consume_niches(1, true, true);
known.consume_niches(1, true);
Layout::Layout(known)
}

Expand Down Expand Up @@ -485,47 +449,47 @@ lazy_static! {
// 32bit layouts are based on WASM
u64: {
64 => Layout::of::<u64>(),
32 => Layout::known(8, 8, 0, 0),
32 => Layout::known(8, 8, 0),
},
i64: {
64 => Layout::of::<i64>(),
32 => Layout::known(8, 8, 0, 0),
32 => Layout::known(8, 8, 0),
},
f64: {
64 => Layout::of::<f64>(),
32 => Layout::known(8, 8, 0, 0),
32 => Layout::known(8, 8, 0),
},
usize: {
64 => Layout::of::<usize>(),
32 => Layout::known(4, 4, 0, 0),
32 => Layout::known(4, 4, 0),
},
isize: {
64 => Layout::of::<isize>(),
32 => Layout::known(4, 4, 0, 0),
32 => Layout::known(4, 4, 0),
},
// well known types
// TODO: generate const assertions for these in the ast crate
Span: { _ => Layout::known(8, 4, 0, 0), },
Span: { _ => Layout::known(8, 4, 0), },
Atom: {
64 => Layout::wide_ptr_64(),
32 => Layout::wide_ptr_32(),
},
Vec: {
64 => Layout::known(32, 8, 0, 1),
32 => Layout::known(16, 4, 0, 1),
64 => Layout::known(32, 8, 1),
32 => Layout::known(16, 4, 1),
},
Cell<Option<ScopeId>>: { _ => Layout::known(4, 4, 0, 1), },
Cell<Option<SymbolId>>: { _ => Layout::known(4, 4, 0, 1), },
Cell<Option<ReferenceId>>: { _ => Layout::known(4, 4, 0, 1), },
ReferenceFlag: { _ => Layout::known(1, 1, 0, 0), },
AssignmentOperator: { _ => Layout::known(1, 1, 0, 1), },
LogicalOperator: { _ => Layout::known(1, 1, 0, 1), },
UnaryOperator: { _ => Layout::known(1, 1, 0, 1), },
BinaryOperator: { _ => Layout::known(1, 1, 0, 1), },
UpdateOperator: { _ => Layout::known(1, 1, 0, 1), },
SourceType: { _ => Layout::known(4, 1, 0, 1), },
RegExpFlags: { _ => Layout::known(1, 1, 0, 0), },
BigintBase: { _ => Layout::known(1, 1, 0, 1), },
NumberBase: { _ => Layout::known(1, 1, 0, 1), },
Cell<Option<ScopeId>>: { _ => Layout::known(4, 4, 1), },
Cell<Option<SymbolId>>: { _ => Layout::known(4, 4, 1), },
Cell<Option<ReferenceId>>: { _ => Layout::known(4, 4, 1), },
ReferenceFlag: { _ => Layout::known(1, 1, 0), },
AssignmentOperator: { _ => Layout::known(1, 1, 1), },
LogicalOperator: { _ => Layout::known(1, 1, 1), },
UnaryOperator: { _ => Layout::known(1, 1, 1), },
BinaryOperator: { _ => Layout::known(1, 1, 1), },
UpdateOperator: { _ => Layout::known(1, 1, 1), },
SourceType: { _ => Layout::known(4, 1, 1), },
RegExpFlags: { _ => Layout::known(1, 1, 0), },
BigintBase: { _ => Layout::known(1, 1, 1), },
NumberBase: { _ => Layout::known(1, 1, 1), },
};
}

0 comments on commit 89ae563

Please sign in to comment.