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

Allow for configuring costs per WebAssembly opcode #1

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 60 additions & 59 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ wasmtime = { path = "crates/wasmtime", package = "dusk-wasmtime", version = "20.
wasmtime-c-api-macros = { path = "crates/c-api-macros", version = "=20.0.0" }
wasmtime-cache = { path = "crates/cache", version = "=20.0.0" }
wasmtime-cli-flags = { path = "crates/cli-flags", version = "=20.0.0" }
wasmtime-cranelift = { path = "crates/cranelift", version = "=20.0.0" }
wasmtime-cranelift = { path = "crates/cranelift", package = "dusk-wasmtime-cranelift", version = "=20.0.0" }
wasmtime-winch = { path = "crates/winch", version = "=20.0.0" }
wasmtime-environ = { path = "crates/environ", version = "=20.0.0" }
wasmtime-environ = { path = "crates/environ", package = "dusk-wasmtime-environ", version = "=20.0.0" }
wasmtime-explorer = { path = "crates/explorer", version = "=20.0.0" }
wasmtime-fiber = { path = "crates/fiber", version = "=20.0.0" }
wasmtime-types = { path = "crates/types", version = "20.0.0" }
Expand Down
2 changes: 1 addition & 1 deletion crates/cranelift/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "wasmtime-cranelift"
name = "dusk-wasmtime-cranelift"
version.workspace = true
authors.workspace = true
description = "Integration between Cranelift and Wasmtime"
Expand Down
18 changes: 1 addition & 17 deletions crates/cranelift/src/func_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,23 +318,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
return;
}

self.fuel_consumed += match op {
// Nop and drop generate no code, so don't consume fuel for them.
Operator::Nop | Operator::Drop => 0,

// Control flow may create branches, but is generally cheap and
// free, so don't consume fuel. Note the lack of `if` since some
// cost is incurred with the conditional check.
Operator::Block { .. }
| Operator::Loop { .. }
| Operator::Unreachable
| Operator::Return
| Operator::Else
| Operator::End => 0,

// everything else, just call it one operation.
_ => 1,
};
self.fuel_consumed += self.tunables.operator_cost.cost(op);

match op {
// Exiting a function (via a return or unreachable) or otherwise
Expand Down
3 changes: 2 additions & 1 deletion crates/environ/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "wasmtime-environ"
name = "dusk-wasmtime-environ"
version.workspace = true
authors.workspace = true
description = "Standalone environment support for WebAsssembly code in Cranelift"
Expand All @@ -21,6 +21,7 @@ cranelift-entity = { workspace = true }
wasmtime-types = { workspace = true }
wasmparser = { workspace = true }
indexmap = { workspace = true, features = ["serde"] }
paste = "1.0.3"
thiserror = { workspace = true }
serde = { workspace = true }
serde_derive = { workspace = true }
Expand Down
80 changes: 80 additions & 0 deletions crates/environ/src/tunables.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use anyhow::{anyhow, bail, Result};
use paste::paste;
use serde_derive::{Deserialize, Serialize};
use target_lexicon::{PointerWidth, Triple};
use wasmparser::Operator;

/// Tunable parameters for WebAssembly compilation.
#[derive(Clone, Hash, Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -31,6 +33,9 @@ pub struct Tunables {
/// will be consumed every time a wasm instruction is executed.
pub consume_fuel: bool,

/// The cost of each operator. If fuel is not enabled, this is ignored.
pub operator_cost: OperatorCost,

/// Whether or not we use epoch-based interruption.
pub epoch_interruption: bool,

Expand Down Expand Up @@ -102,6 +107,7 @@ impl Tunables {
generate_native_debuginfo: false,
parse_wasm_debuginfo: true,
consume_fuel: false,
operator_cost: OperatorCost::default(),
epoch_interruption: false,
static_memory_bound_is_maximum: false,
guard_before_linear_memory: true,
Expand Down Expand Up @@ -156,3 +162,77 @@ impl Tunables {
}
}
}

macro_rules! default_cost {
// Nop and drop generate no code, so don't consume fuel for them.
(Nop) => {
0
};
(Drop) => {
0
};

// Control flow may create branches, but is generally cheap and
// free, so don't consume fuel.
(Block) => {
0
};
(Loop) => {
0
};
(Unreachable) => {
0
};
(Return) => {
0
};
(Else) => {
0
};
(End) => {
0
};

// Everything else, just call it one operation.
($op:ident) => {
1
};
}

macro_rules! define_operator_cost {
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => {
paste! {
/// The fuel cost of each operator.
#[derive(Clone, Copy, Hash, Serialize, Deserialize, Debug)]
#[allow(missing_docs, non_snake_case)]
pub struct OperatorCost {
$(
pub $op: i64,
)*
}

impl OperatorCost {
/// Returns the cost of the given operator.
pub fn cost(&self, op: &Operator) -> i64 {
match op {
$(
Operator::$op $({ $($arg: [<_ $arg>]),* })? => self.$op,
)*
}
}
}

impl Default for OperatorCost {
fn default() -> Self {
Self {
$(
$op: default_cost!($op),
)*
}
}
}
}
}
}

wasmparser::for_each_operator!(define_operator_cost);
Loading