Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flash/mem] Significant changes to how Manticore does memory management #48

Merged
merged 8 commits into from
Jan 6, 2021

Conversation

mcy
Copy link
Contributor

@mcy mcy commented Nov 12, 2020

This PR is the result of a lot of pain and suffering on my part trying to make the existing Arena and Flash APIs do the right thing for parsing the PFM. I discovered a few things:

  • Coupling the lifetimes of allocations in RAM and a Flash object too closely results in some very difficult to resolve lifetime constraints.
  • There's no good way for parsing "packed C structs" out of Flash, which is something Cerberus, as a protocol, expects implementors to do.
  • The adapters in flash.rs were mostly unhelpful in this regard, since you really want to bind a Flash to a lifetime by using &'flash Flash.
  • Region/Ptr feel too boilerplatey and hard to use.

The result is this PR, which contains a number of interrelated changes to how Arenas and Flashes interact. The most important once is the elimination of FlashZero, which is replaced with Flash::direct_read. This function allows the user to request a zero-copy read, providing their own arena for the allocation if the request can't be fulfilled.

@mcy
Copy link
Contributor Author

mcy commented Nov 13, 2020

@jrvanwhy Would you mind looking over this? Please let me know if something I've done seems odd.

/// Calling `alloc(0)` must never fail.
/// Calling `alloc(0, 1)` must never fail. Note that there is no
/// requirement that calling `alloc(0, n)` will not return a subslice
/// of previously returned memory.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't calling alloc_aligned(0, 1) fail for OutOfMem? Should OutOfMem be willing to serve up 0-sized allocations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed it so that it can actually serve really aligned allocations of zero-size.

Ok(lv.into_mut())
}

fn alloc_slice<T: AsBytes + FromBytes + Copy>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear to me whether ArenaExt::alloc_slice will panic, as is required by the trait method documentation (line 154).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can panic due to calls of alloc_aligned.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I worded my comment poorly. What is meant was whether it panics must be documented.

src/mem/mod.rs Outdated

/// Computes the stride of `T`, that is, its size rounded up to its alignment.
#[inline]
pub(in crate) fn stride_of<T>() -> usize {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core::mem::size_of::<T>() is guaranteed to be a multiple of core::mem::align_of::<T>() already. See the second sentence of the size_of docs:

More specifically, this is the offset in bytes between successive elements in an array with that item type including alignment padding. Thus, for any type T and length n, [T; n] has a size of n * size_of::<T>().

Rust's size_of refers to the same concept as Swift calls "stride". If Rust ever has a distinction akin to Swift's "size"/"stride" distinction, then Rust's equivalent to Swift's "size" will need to be called something else. Here's some more background on the topic: rust-lang/rust#33266

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait really? I swear that Rust did not promise this. TIL!

let mask = align.saturating_sub(1);
let (addr, overflow) = addr.overflowing_add(mask);
if overflow {
return usize::MAX;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to mention that in the case of overflow, this will return an unaligned value. I think returning usize::MAX is a bit of a footgun, although my only suggestion is "document it better".

@mcy
Copy link
Contributor Author

mcy commented Nov 17, 2020

Jon: I replied to your suggestions. Let me know if you notice any other oddities.

Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
@mcy mcy force-pushed the flash-arena branch 3 times, most recently from b6affa3 to abd5356 Compare January 6, 2021 17:59
mcy added 7 commits January 6, 2021 13:02
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
It turns out that FlashZero was too restrictive, since it coupled arena
semantics too closely with a flash object. The new API is similar in
spirit, but allows for different arenas to be used with different
allocations, while also allowing for Flash implementations to optimize
whether they need to touch the arena at all.

Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
@mcy mcy merged commit 4d593a2 into lowRISC:master Jan 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants