-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Chaos mode MVP: Skip branch optimization in MachBuffer #6039
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
0a42553
fuzz: Add chaos mode control plane
senekor f51732a
fuzz: Skip branch optimization with chaos mode
senekor bb15b08
fuzz: Rename chaos engine -> control plane
senekor dfa0594
chaos mode: refactoring ControlPlane to be passed through the call st…
MzrW 5f2cfc1
fuzz: annotate chaos todos
senekor 14ba45d
fuzz: cleanup control plane
senekor fd541f0
fuzz: remove control plane from compiler context
senekor a0f379b
fuzz: move control plane into emit state
senekor c8e5039
fuzz: fix remaining compiler errors
senekor 8e7591a
fix tests
senekor ccc2ba0
refactor emission state ctrl plane accessors
senekor 9e907a4
centralize conditional compilation of chaos mode
senekor bc76cae
add cranelift-control to published crates
senekor 54cc68c
add cranelift-control to public crates
senekor fa0eda7
Merge main into fuzz-skip-branch-opt
senekor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fuzz: cleanup control plane
Co-authored-by: Falk Zwimpfer <[email protected]> Co-authored-by: Moritz Waser <[email protected]>
- Loading branch information
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,58 +1,28 @@ | ||
| use std::{backtrace, fmt::Debug}; | ||
|
|
||
| use arbitrary::Arbitrary; | ||
|
|
||
| /// The control plane of chaos mode. | ||
| /// Please see the [crate-level documentation](crate). | ||
| /// | ||
| /// **Clone liberally!** The chaos engine is reference counted. | ||
| #[derive(Debug, Clone)] | ||
| #[derive(Debug, Clone, Default)] | ||
| pub struct ControlPlane { | ||
| data: Vec<bool>, | ||
| is_noop: bool, | ||
| } | ||
|
|
||
| impl Arbitrary<'_> for ControlPlane { | ||
| fn arbitrary<'a>(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> { | ||
| Ok(Self::new(u.arbitrary()?, false)) | ||
| } | ||
| } | ||
|
|
||
| impl ControlPlane { | ||
| fn new(data: Vec<bool>, is_noop: bool) -> Self { | ||
| Self { | ||
| data: data, | ||
| is_noop, | ||
| } | ||
| } | ||
|
|
||
| /// TODO chaos: should be explained | ||
| pub fn no_chaos() -> Self { | ||
| Self::new(Vec::new(), false) | ||
| } | ||
|
|
||
| pub fn todo() -> Self { | ||
| Self::new(Vec::new(), false) | ||
| } | ||
| } | ||
|
|
||
| impl Default for ControlPlane { | ||
| fn default() -> Self { | ||
| Self::new(Vec::new(), true) | ||
| Ok(Self { | ||
| data: u.arbitrary()?, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| impl ControlPlane { | ||
| pub fn get_decision(&mut self) -> Option<bool> { | ||
| if self.is_noop { | ||
| //println!( | ||
| // "try to get a decision from a noop chaos engine at {} ", | ||
| // backtrace::Backtrace::force_capture() | ||
| //); | ||
| //None | ||
| panic!("trying to get a decision from a noop chaos engine"); | ||
| } else { | ||
| self.data.pop() | ||
| } | ||
| /// Returns a pseudo-random boolean if the control plane was constructed | ||
| /// with `arbitrary`. | ||
| /// | ||
| /// The default value `false` will always be returned if the | ||
| /// pseudo-random data is exhausted or the control plane was constructed | ||
| /// with `default`. | ||
| pub fn get_decision(&mut self) -> bool { | ||
| self.data.pop().unwrap_or_default() | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,5 @@ | ||
| #[derive(Debug, Clone)] | ||
| #[derive(Debug, Clone, Default)] | ||
| pub struct ControlPlane { | ||
| /// prevent direct instantiation (use `noop` or `todo` instead) | ||
| /// prevent direct instantiation (use `default` instead) | ||
| _private: (), | ||
| } | ||
|
|
||
| impl ControlPlane { | ||
| pub fn no_chaos() -> Self { | ||
| Self { _private: () } | ||
| } | ||
|
|
||
| // get_decision function is not implemented here because it should only be called within | ||
| // conditional compiled code blocks. In that case the other implementation would be used anyway. | ||
| } | ||
|
|
||
| impl Default for ControlPlane { | ||
| fn default() -> Self { | ||
| Self::no_chaos() | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
One small tweak to the conditional-compilation strategy: I had been thinking that we could have the methods that produce decisions, like
get_decisionhere, return a default value (falsehere) as a constant in the non-chaos-feature case; then the sites where we use these decisions, like inMachBuffer, don't require annotation with conditional compilation. What do you think?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 thinking about the potential performance impact in release builds, but I guess it's safe to assume the compiler inlines a constant
falseand removes the resultingif false {}.In my view, it would be a nice aspect of the control plane that there is no way to (mis-)use it in regular builds. But I guess that every control plane API needs to have some default output value anyway... and that can probably always be inlined as well? And we can annotate these default-returning functions with
#[inline].What is the downside of conditional compilation at the call sites? It seemed like an easy way to be really, really sure nothing bad happens in release builds, but on second thought, it doesn't seem necessary.
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.
Indeed, we should be able to trust the branch-folding here.
The main downside is that it spreads the implementation of a conditional decision across distributed points -- the alternative, where everything is wired to a single module where all conditional-compilation logic lies, makes it easier to make changes in the future. (Another example of this principle in action is the
memfdpooling-allocator mechanism in Wasmtime: when I implemented this in #3697 last year I originally had feature-conditional code in many places, but Alex convinced me to centralize everything into two versions of one module and remove conditionals everywhere else. The result is far cleaner!)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 assuming this goes for the
Arbitraryimplementation as well, so I removed the conditional compilation here too.The shim control plane's
Arbitraryimplementation now returns the default without consuming any bytes.