From 43d4f0b93b087a3a159863308eacdba12cff180f Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Mon, 13 Jun 2022 21:04:37 +0200 Subject: [PATCH] Serialize `BlockNode`'s cold field too when serializing a `Layout` (#4265) This fixes a bug when the `cold` field would not be serialized, since we're using a custom (de)serializer for `Layout`. This is now properly handled by adding a boolean in the serialized stream. This was caught during the work on #4155, as this would result in cache mismatches between a function and itself. --- cranelift/codegen/src/ir/layout.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cranelift/codegen/src/ir/layout.rs b/cranelift/codegen/src/ir/layout.rs index 47ec6b1fda..80471c3008 100644 --- a/cranelift/codegen/src/ir/layout.rs +++ b/cranelift/codegen/src/ir/layout.rs @@ -484,6 +484,8 @@ impl Layout { } } +/// A single node in the linked-list of blocks. +// Whenever you add new fields here, don't forget to update the custom serializer for `Layout` too. #[derive(Clone, Debug, Default)] struct BlockNode { prev: PackedOption, @@ -803,7 +805,7 @@ impl<'f> DoubleEndedIterator for Insts<'f> { /// /// ```plain /// data = block_data * ; -/// block_data = "block_id" , "inst_count" , ( "inst_id" * ) ; +/// block_data = "block_id" , "cold" , "inst_count" , ( "inst_id" * ) ; /// ``` #[cfg(feature = "enable-serde")] mod serde { @@ -821,7 +823,7 @@ mod serde { where S: Serializer, { - let size = self.blocks().count() * 2 + let size = self.blocks().count() * 3 + self .blocks() .map(|block| self.block_insts(block).count()) @@ -829,6 +831,7 @@ mod serde { let mut seq = serializer.serialize_seq(Some(size))?; for block in self.blocks() { seq.serialize_element(&block)?; + seq.serialize_element(&self.blocks[block].cold)?; seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?; for inst in self.block_insts(block) { seq.serialize_element(&inst)?; @@ -869,9 +872,15 @@ mod serde { while let Some(block) = access.next_element::()? { layout.append_block(block); + let cold = access + .next_element::()? + .ok_or_else(|| Error::missing_field("cold"))?; + layout.blocks[block].cold = cold; + let count = access .next_element::()? .ok_or_else(|| Error::missing_field("count"))?; + for _ in 0..count { let inst = access .next_element::()?