-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
It looks like @cmichi hasn't signed our Contributor License Agreement, yet.
You can read and sign our full Contributor License Agreement at the following URL: https://cla.parity.io Once you've signed, please reply to this thread with Many thanks, Parity Technologies CLA Bot |
|
It looks like @cmichi signed our Contributor License Agreement. 👍 Many thanks, Parity Technologies CLA Bot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave a brief review, without checking the logic of the allocator. Will do a proper review tomorrow
let ret = slice::from_raw_parts(ptr, length as usize).to_vec(); | ||
ext_free(ptr); | ||
Some(ret) | ||
Some(<Vec<u8>>::from_raw_parts(ptr, length as usize, length as usize)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As was discussed in the issue, this actually violates formal preconditions required by Vec::from_raw_parts
(i.e. the pointer is allocated not with Vec
routines). Given that we agree with it, I still would like to have a comment here mentioning this fact.
And there should be another case nearby (below).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still against using Vec::from_raw_parts
because of all the invariants. If we can prove the invariants, I'm happy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gavofyork What is your opinion on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be better to return some other new type as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I stated in the other thread I'm against this UB dogma. I demonstrated that this code is safe. If you think otherwise please bring the argument forward, otherwise this code goes in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'd agree that it would work for us and I don't have anymore to add to our discussion here! But I'd still be in favor of a comment here. I hope it will save us a headache.
Also, @cmichi there is another case where we apply the same pattern: child_storage
, a function below. I'd like them to be synchronized.
To prevent misunderstandings of people executing both.
let ret = slice::from_raw_parts(ptr, length as usize).to_vec(); | ||
ext_free(ptr); | ||
Some(ret) | ||
Some(<Vec<u8>>::from_raw_parts(ptr, length as usize, length as usize)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still against using Vec::from_raw_parts
because of all the invariants. If we can prove the invariants, I'm happy.
Even though CI succeeds, it looks like there are a bunch of tests failing because of overflows, e.g.
CI is green because we are running tests in release but without debug assertions... |
This reverts commit 292c177.
core/executor/src/heap.rs
Outdated
/// (in bytes) for allocating memory. | ||
/// | ||
pub fn new(mut ptr_offset: u32, heap_size: u32) -> Self { | ||
assert!(BLOCK_SIZE % ALIGNMENT == 0, "Block size is no multiple of alignment!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I have a slight preference for moving it into tests, since if you think about it it doesn't have anything to do with a constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do it at compile time too with this method, because mem::transmute checks that type sizes are the same :)
const BLOCK_SIZE: usize = 1024;
const ALIGNMENT: usize = 8; // try changing to 9
fn _assert_block_size_aligned() {
::std::mem::transmute::<[u8; BLOCK_SIZE % ALIGNMENT], [u8; 0]>;
}
fn main() { }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I added it to the constructor with the intention of asserting that a Heap can only ever be created if the alignment is correct, no matter if tests have been run or not. Do you think assertions don't have a place outside of tests in general?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd consider not tested binary build broken, but yeah : ) I actually like @rphmeier 's approach since it will prevent this from compiling, and doesn't require a separate crate like static_assert
for doing that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done! I have only one small nit
* Add Arch Linux installation instructions * Enable tracing heap size * Extract heap * Replace linear allocator with buddy allocator * Fix test The purose of this big block is for the tests to test a failure when the block is too big though. The improved buddy allocation strategy results in this block fitting on the heap now. Hence the increase. * Get rid of memcpy in to_vec() * fixup: Style and comments * fixup: Split Linux instructions by distribution To prevent misunderstandings of people executing both. * fixup: Remove unnecessary types and code * fixup: Make Pointers start from 1, remove some panics, code improvements * fixup: Return 0 on errors * fixup: Move loop to separate function * fixup: Use FnvHashMap instead of HashMap * fixup: Fix error handling * fixup: Use current_size() instead of used_size() * fixup: Fix and document allocation offset * fixup: Remove unnecessary multiplication * fixup: Fix comments * fixup: Remove Arch installation instructions * Revert "Fix test" This reverts commit 292c177. * fixup: Remove unused code, improve import * fixup: Proper alignment * fixup: Do not use internal constant in public description * fixup: Add comment regarding invariants * fixup: Move assertion to compile-time check
* Better allocator for wasm (#1460) * Add Arch Linux installation instructions * Enable tracing heap size * Extract heap * Replace linear allocator with buddy allocator * Fix test The purose of this big block is for the tests to test a failure when the block is too big though. The improved buddy allocation strategy results in this block fitting on the heap now. Hence the increase. * Get rid of memcpy in to_vec() * fixup: Style and comments * fixup: Split Linux instructions by distribution To prevent misunderstandings of people executing both. * fixup: Remove unnecessary types and code * fixup: Make Pointers start from 1, remove some panics, code improvements * fixup: Return 0 on errors * fixup: Move loop to separate function * fixup: Use FnvHashMap instead of HashMap * fixup: Fix error handling * fixup: Use current_size() instead of used_size() * fixup: Fix and document allocation offset * fixup: Remove unnecessary multiplication * fixup: Fix comments * fixup: Remove Arch installation instructions * Revert "Fix test" This reverts commit 292c177. * fixup: Remove unused code, improve import * fixup: Proper alignment * fixup: Do not use internal constant in public description * fixup: Add comment regarding invariants * fixup: Move assertion to compile-time check * Fix bug in necessary tree level calculation The tree levels necessary to house a number of nodes was calculated incorrectly. * Improve naming
* Add Arch Linux installation instructions * Enable tracing heap size * Extract heap * Replace linear allocator with buddy allocator * Fix test The purose of this big block is for the tests to test a failure when the block is too big though. The improved buddy allocation strategy results in this block fitting on the heap now. Hence the increase. * Get rid of memcpy in to_vec() * fixup: Style and comments * fixup: Split Linux instructions by distribution To prevent misunderstandings of people executing both. * fixup: Remove unnecessary types and code * fixup: Make Pointers start from 1, remove some panics, code improvements * fixup: Return 0 on errors * fixup: Move loop to separate function * fixup: Use FnvHashMap instead of HashMap * fixup: Fix error handling * fixup: Use current_size() instead of used_size() * fixup: Fix and document allocation offset * fixup: Remove unnecessary multiplication * fixup: Fix comments * fixup: Remove Arch installation instructions * Revert "Fix test" This reverts commit 292c177. * fixup: Remove unused code, improve import * fixup: Proper alignment * fixup: Do not use internal constant in public description * fixup: Add comment regarding invariants * fixup: Move assertion to compile-time check
* Revert "Better allocator for wasm (paritytech#1460)" This reverts commit c3bee59. * Update wasm files
* Better allocator for wasm (paritytech#1460) * Add Arch Linux installation instructions * Enable tracing heap size * Extract heap * Replace linear allocator with buddy allocator * Fix test The purose of this big block is for the tests to test a failure when the block is too big though. The improved buddy allocation strategy results in this block fitting on the heap now. Hence the increase. * Get rid of memcpy in to_vec() * fixup: Style and comments * fixup: Split Linux instructions by distribution To prevent misunderstandings of people executing both. * fixup: Remove unnecessary types and code * fixup: Make Pointers start from 1, remove some panics, code improvements * fixup: Return 0 on errors * fixup: Move loop to separate function * fixup: Use FnvHashMap instead of HashMap * fixup: Fix error handling * fixup: Use current_size() instead of used_size() * fixup: Fix and document allocation offset * fixup: Remove unnecessary multiplication * fixup: Fix comments * fixup: Remove Arch installation instructions * Revert "Fix test" This reverts commit 292c177. * fixup: Remove unused code, improve import * fixup: Proper alignment * fixup: Do not use internal constant in public description * fixup: Add comment regarding invariants * fixup: Move assertion to compile-time check * Fix bug in necessary tree level calculation The tree levels necessary to house a number of nodes was calculated incorrectly. * Improve naming
Update Rust toolchain to latest nightly
Hi there,
this PR addresses #300.
Some notes:
The prior linear allocator didn't do any error handling, this allocator does. I went for
panic!
, since the allocation returnsu32
. Ispanic!
appropriate?Tracking the heap size is in there because it came handy for writing the tests. Should we remove it for production because of performance or do you think the
trace!
could still be helpful?The size of allocated bytes per pointer needs to be stored, so that
deallocate
can properly free allocated blocks. This size is currently stored in aHashMap
and there might be a more performant way.The alignment of
u8
onunknown-unknown-webassembly
is indeed1
; this was validated by @pepyakin .Once a block is allocated it fills up the block space ‒ no matter how full it is. I chose a block size of 8192 Bytes because it seemed like a reasonable trade-off between wasting space on the heap and still keeping the whole thing performant. I tried bigger block sizes as well, but the stack then quickly reaches it's limit and a number of tests fail.
I haven't done a proper benchmark yet, but I examined the average heap size when running a
--dev
chain. The difference looks very good (of course though, since the linear allocator never freed anything up). I haven't looked at the difference in execution time yet.