Skip to content

Commit

Permalink
feat: enable wasm optimizations using binaryen
Browse files Browse the repository at this point in the history
This enables both the speed (3) and size (z) optimizations, bringing the
miner actor down to 1MiB.
  • Loading branch information
Stebalien committed Jun 2, 2022
1 parent d82b1fa commit 4551871
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 2 deletions.
74 changes: 73 additions & 1 deletion Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fil_actors_runtime = { version = "8.0.0-alpha.1", path = "./actors/runtime", fea
[build-dependencies]
fil_actor_bundler = "3.0.3"
cid = { version = "0.8.3", default-features = false, features = ["serde-codec"] }
binaryen = "0.12.1"

[dependencies]
clap = { version = "3.1.8", features = ["derive"] }
Expand Down Expand Up @@ -86,3 +87,4 @@ panic = "unwind"
overflow-checks = true
lto = "thin"
opt-level = "z"
strip = true
38 changes: 37 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use binaryen::CodegenConfig;

use fil_actor_bundler::Bundler;
use std::error::Error;
use std::fs;
use std::io::{BufRead, BufReader};
use std::os::raw::c_char;
use std::path::Path;
use std::process::{Command, Stdio};
use std::thread;
Expand Down Expand Up @@ -29,6 +33,12 @@ const WASM_FEATURES: &[&str] = &["+bulk-memory", "+crt-static"];

const NETWORK_ENV: &str = "BUILD_FIL_NETWORK";

static CODEGEN_CONFIG: &CodegenConfig = &CodegenConfig {
shrink_level: 2, // Oz
optimization_level: 3, // O3
debug_info: false,
};

/// Returns the configured network name, checking both the environment and feature flags.
fn network_name() -> String {
let env_network = std::env::var_os(NETWORK_ENV);
Expand Down Expand Up @@ -167,7 +177,10 @@ fn main() -> Result<(), Box<dyn Error>> {
// content-addressed CIDs.
let forced_cid = None;

let cid = bundler.add_from_file(id, forced_cid, &bytecode_path).unwrap_or_else(|err| {
let bytecode = fs::read(&bytecode_path).expect("failed to open wasm module");
let bytecode = optimize_module(&bytecode).expect("failed to optimize wasm");

let cid = bundler.add_from_bytes(id, forced_cid, &bytecode).unwrap_or_else(|err| {
panic!("failed to add file {:?} to bundle for actor {}: {}", bytecode_path, id, err)
});
println!("cargo:warning=added actor {} to bundle with CID {}", id, cid);
Expand All @@ -178,3 +191,26 @@ fn main() -> Result<(), Box<dyn Error>> {

Ok(())
}

fn optimize_module(bytecode: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
// We have to do this manually to explicitly set the features.
let mut module = unsafe {
let raw = binaryen::ffi::BinaryenModuleSafeRead(
bytecode.as_ptr() as *const c_char,
bytecode.len(),
);
if raw.is_null() {
return Err("invalid module".to_string().into());
}

let wasm_features = binaryen::ffi::BinaryenFeatureMVP()
| binaryen::ffi::BinaryenFeatureSignExt()
| binaryen::ffi::BinaryenFeatureBulkMemory()
| binaryen::ffi::BinaryenFeatureMutableGlobals()
| binaryen::ffi::BinaryenFeatureNontrappingFPToInt();
binaryen::ffi::BinaryenModuleSetFeatures(raw, wasm_features);
binaryen::Module::from_raw(raw)
};
module.optimize(CODEGEN_CONFIG);
Ok(module.write())
}

0 comments on commit 4551871

Please sign in to comment.