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

Experimental aarch64 support #6200

Merged
merged 4 commits into from
Feb 1, 2022
Merged
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
30 changes: 16 additions & 14 deletions runtime/near-vm-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,9 @@ This crate implements the specification of the interface that Near blockchain ex
[dependencies]
borsh = "0.9"
serde = { version = "1", features = ["derive"] }
wasmer-runtime = { version = "0.18.0", features = ["default-backend-singlepass"], default-features = false, package = "wasmer-runtime-near", optional = true }
wasmer-runtime-core = { version = "0.18.2", package = "wasmer-runtime-core-near", optional = true}
wasmparser = "0.78"
memoffset = "0.6"

# Use the following for development versions of Wasmer.
# wasmer-types = { package = "wasmer-types-near", git = "https://github.com/near/wasmer", branch = "near-main", optional = true }
# wasmer-compiler-singlepass = { package = "wasmer-compiler-singlepass-near", git = "https://github.com/near/wasmer", branch = "near-main", optional = true }
# wasmer-engine-universal = { package = "wasmer-engine-universal-near", git = "https://github.com/near/wasmer", branch = "near-main", optional = true }
# wasmer-vm = { package = "wasmer-vm-near", git = "https://github.com/near/wasmer", branch = "near-main" }
wasmer-compiler = { package = "wasmer-compiler-near", version = "=2.2.0", optional = true }
wasmer-compiler-singlepass = { package = "wasmer-compiler-singlepass-near", version = "=2.2.0", optional = true }
wasmer-engine = { package = "wasmer-engine-near", version = "=2.2.0", optional = true }
wasmer-engine-universal = { package = "wasmer-engine-universal-near", version = "=2.2.0", optional = true, features = ["compiler"] }
wasmer-types = { package = "wasmer-types-near", version = "=2.2.0", optional = true }
wasmer-vm = { package = "wasmer-vm-near", version = "=2.2.0", optional = true }

loupe = "0.1"
once_cell = "1.5.2"
pwasm-utils = "0.18"
Expand All @@ -52,6 +38,22 @@ threadpool = "1.8.1"
pwasm-utils_12 = { package = "pwasm-utils", version = "0.12" }
parity-wasm_41 = { package = "parity-wasm", version = "0.41" }

[target.'cfg(target_arch = "x86_64")'.dependencies]
wasmer-runtime = { version = "0.18.0", features = ["default-backend-singlepass"], default-features = false, package = "wasmer-runtime-near", optional = true }
wasmer-runtime-core = { version = "0.18.2", package = "wasmer-runtime-core-near", optional = true}

# Use the following for development versions of Wasmer.
# wasmer-types = { package = "wasmer-types-near", git = "https://github.com/near/wasmer", branch = "near-main", optional = true }
# wasmer-compiler-singlepass = { package = "wasmer-compiler-singlepass-near", git = "https://github.com/near/wasmer", branch = "near-main", optional = true }
# wasmer-engine-universal = { package = "wasmer-engine-universal-near", git = "https://github.com/near/wasmer", branch = "near-main", optional = true }
# wasmer-vm = { package = "wasmer-vm-near", git = "https://github.com/near/wasmer", branch = "near-main" }
wasmer-compiler = { package = "wasmer-compiler-near", version = "=2.2.0", optional = true }
wasmer-compiler-singlepass = { package = "wasmer-compiler-singlepass-near", version = "=2.2.0", optional = true }
wasmer-engine = { package = "wasmer-engine-near", version = "=2.2.0", optional = true }
wasmer-engine-universal = { package = "wasmer-engine-universal-near", version = "=2.2.0", optional = true, features = ["compiler"] }
wasmer-types = { package = "wasmer-types-near", version = "=2.2.0", optional = true }
wasmer-vm = { package = "wasmer-vm-near", version = "=2.2.0", optional = true }


[dev-dependencies]
near-test-contracts = { path = "../near-test-contracts" }
Expand Down
36 changes: 21 additions & 15 deletions runtime/near-vm-runner/src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
use crate::errors::ContractPrecompilatonResult;
use crate::prepare;
use crate::vm_kind::VMKind;
use borsh::{BorshDeserialize, BorshSerialize};
use near_primitives::contract::ContractCode;
use near_primitives::hash::CryptoHash;
use near_primitives::types::CompiledContractCache;
use near_vm_errors::{CacheError, CompilationError, FunctionCallError, VMError};
use near_vm_errors::{CacheError, CompilationError};
use near_vm_logic::{ProtocolVersion, VMConfig};
use std::collections::HashMap;
use std::fmt;
use std::sync::{Arc, Mutex};

#[cfg(target_arch = "x86_64")]
use crate::prepare;
#[cfg(target_arch = "x86_64")]
use near_vm_errors::{FunctionCallError, VMError};

#[derive(Debug, Clone, BorshSerialize)]
enum ContractCacheKey {
_Version1,
Expand All @@ -32,13 +36,13 @@ enum CacheRecord {

fn vm_hash(vm_kind: VMKind) -> u64 {
match vm_kind {
#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
VMKind::Wasmer0 => crate::wasmer_runner::wasmer0_vm_hash(),
#[cfg(not(feature = "wasmer0_vm"))]
#[cfg(not(all(feature = "wasmer0_vm", target_arch = "x86_64")))]
VMKind::Wasmer0 => panic!("Wasmer0 is not enabled"),
#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
VMKind::Wasmer2 => crate::wasmer2_runner::wasmer2_vm_hash(),
#[cfg(not(feature = "wasmer2_vm"))]
#[cfg(not(all(feature = "wasmer2_vm", target_arch = "x86_64")))]
VMKind::Wasmer2 => panic!("Wasmer2 is not enabled"),
#[cfg(feature = "wasmtime_vm")]
VMKind::Wasmtime => crate::wasmtime_runner::wasmtime_vm_hash(),
Expand All @@ -62,6 +66,7 @@ pub fn get_contract_cache_key(
near_primitives::hash::hash(&key.try_to_vec().unwrap())
}

#[cfg(target_arch = "x86_64")]
fn cache_error(
error: &CompilationError,
key: &CryptoHash,
Expand All @@ -73,6 +78,7 @@ fn cache_error(
Ok(())
}

#[cfg(target_arch = "x86_64")]
pub fn into_vm_result<T>(
res: Result<Result<T, CompilationError>, CacheError>,
) -> Result<T, VMError> {
Expand Down Expand Up @@ -114,23 +120,23 @@ impl fmt::Debug for MockCompiledContractCache {
}
}

#[cfg(not(feature = "no_cache"))]
#[cfg(all(not(feature = "no_cache"), target_arch = "x86_64"))]
const CACHE_SIZE: usize = 128;

#[cfg(all(feature = "wasmer0_vm", not(feature = "no_cache")))]
#[cfg(all(feature = "wasmer0_vm", not(feature = "no_cache"), target_arch = "x86_64"))]
static WASMER_CACHE: once_cell::sync::Lazy<
near_cache::SyncLruCache<CryptoHash, Result<wasmer_runtime::Module, CompilationError>>,
> = once_cell::sync::Lazy::new(|| near_cache::SyncLruCache::new(CACHE_SIZE));

#[cfg(all(feature = "wasmer2_vm", not(feature = "no_cache")))]
#[cfg(all(feature = "wasmer2_vm", not(feature = "no_cache"), target_arch = "x86_64"))]
static WASMER2_CACHE: once_cell::sync::Lazy<
near_cache::SyncLruCache<
CryptoHash,
Result<crate::wasmer2_runner::VMArtifact, CompilationError>,
>,
> = once_cell::sync::Lazy::new(|| near_cache::SyncLruCache::new(CACHE_SIZE));

#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
pub mod wasmer0_cache {
use super::*;
use near_vm_errors::CompilationError;
Expand Down Expand Up @@ -243,7 +249,7 @@ pub mod wasmer0_cache {
}
}

#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
pub mod wasmer2_cache {
use crate::wasmer2_runner::{VMArtifact, Wasmer2VM};
use near_primitives::contract::ContractCode;
Expand Down Expand Up @@ -367,19 +373,19 @@ pub fn precompile_contract_vm(
None => {}
};
match vm_kind {
#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
VMKind::Wasmer0 => {
Ok(wasmer0_cache::compile_and_serialize_wasmer(wasm_code.code(), config, &key, cache)?
.map(|_| ContractPrecompilatonResult::ContractCompiled))
}
#[cfg(not(feature = "wasmer0_vm"))]
#[cfg(not(all(feature = "wasmer0_vm", target_arch = "x86_64")))]
VMKind::Wasmer0 => panic!("Wasmer0 is not enabled!"),
#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
VMKind::Wasmer2 => {
Ok(wasmer2_cache::compile_and_serialize_wasmer2(wasm_code.code(), &key, config, cache)?
.map(|_| ContractPrecompilatonResult::ContractCompiled))
}
#[cfg(not(feature = "wasmer2_vm"))]
#[cfg(not(all(feature = "wasmer2_vm", target_arch = "x86_64")))]
VMKind::Wasmer2 => panic!("Wasmer2 is not enabled!"),
VMKind::Wasmtime => panic!("Not yet supported"),
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/near-vm-runner/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ imports! {
#["protocol_feature_alt_bn128", AltBn128] alt_bn128_pairing_check<[value_len: u64, value_ptr: u64] -> [u64]>,
}

#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
pub(crate) mod wasmer {
use super::str_eq;
use near_vm_logic::{ProtocolVersion, VMLogic, VMLogicError};
Expand Down Expand Up @@ -272,7 +272,7 @@ pub(crate) mod wasmer {
}
}

#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
pub(crate) mod wasmer2 {
use std::sync::Arc;

Expand Down
8 changes: 5 additions & 3 deletions runtime/near-vm-runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
mod cache;
mod errors;
mod imports;
#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
mod memory;
#[cfg(target_arch = "x86_64")]
mod preload;
pub mod prepare;
mod runner;
#[cfg(test)]
mod tests;
mod vm_kind;
#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
mod wasmer2_runner;
#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
mod wasmer_runner;
#[cfg(feature = "wasmtime_vm")]
mod wasmtime_runner;
Expand All @@ -24,6 +25,7 @@ pub use near_vm_logic::with_ext_cost_counter;
pub use cache::{
get_contract_cache_key, precompile_contract, precompile_contract_vm, MockCompiledContractCache,
};
#[cfg(target_arch = "x86_64")]
pub use preload::{ContractCallPrepareRequest, ContractCallPrepareResult, ContractCaller};
pub use runner::{run, VM};

Expand Down
4 changes: 2 additions & 2 deletions runtime/near-vm-runner/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ impl VMKind {
/// This is not intended to be used by code other than standalone-vm-runner.
pub fn runtime(&self, config: VMConfig) -> Option<Box<dyn VM>> {
match self {
#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
Self::Wasmer0 => Some(Box::new(crate::wasmer_runner::Wasmer0VM::new(config))),
#[cfg(feature = "wasmtime_vm")]
Self::Wasmtime => Some(Box::new(crate::wasmtime_runner::WasmtimeVM::new(config))),
#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
Self::Wasmer2 => Some(Box::new(crate::wasmer2_runner::Wasmer2VM::new(config))),
#[allow(unreachable_patterns)] // reachable when some of the VMs are disabled.
_ => None,
Expand Down
4 changes: 2 additions & 2 deletions runtime/near-vm-runner/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ const PREDECESSOR_ACCOUNT_ID: &str = "carol";
const LATEST_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::MAX;

fn with_vm_variants(runner: fn(VMKind) -> ()) {
#[cfg(feature = "wasmer0_vm")]
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
runner(VMKind::Wasmer0);

#[cfg(feature = "wasmtime_vm")]
runner(VMKind::Wasmtime);

#[cfg(feature = "wasmer2_vm")]
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
runner(VMKind::Wasmer2);
}

Expand Down
4 changes: 3 additions & 1 deletion runtime/near-vm-runner/src/tests/cache.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Tests that `CompiledContractCache` is working correctly.
//! Tests that `CompiledContractCache` is working correctly. Currently testing only wasmer code, so disabled outside of x86_64
#![cfg(target_arch = "x86_64")]

use super::{create_context, with_vm_variants, LATEST_PROTOCOL_VERSION};
use crate::internal::VMKind;
use crate::wasmer2_runner::Wasmer2VM;
Expand Down
3 changes: 3 additions & 0 deletions runtime/near-vm-runner/src/tests/contract_preload.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Currently only testing wasmer code, so disabled outside of x86_64
#![cfg(target_arch = "x86_64")]

use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread::sleep;
Expand Down
19 changes: 16 additions & 3 deletions runtime/near-vm-runner/src/vm_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ pub enum VMKind {

impl VMKind {
pub fn for_protocol_version(protocol_version: ProtocolVersion) -> VMKind {
// Only wasmtime supports non-x86_64 systems
#[cfg(all(
not(target_arch = "x86_64"),
any(feature = "force_wasmer0", feature = "force_wasmer2")
))]
compile_error!(
"Wasmer only supports x86_64, but a force_wasmer* feature was passed to near-vm-runner"
);

if cfg!(feature = "force_wasmer0") {
return VMKind::Wasmer0;
}
Expand All @@ -30,10 +39,14 @@ impl VMKind {
return VMKind::Wasmer2;
}

if checked_feature!("stable", Wasmer2, protocol_version) {
VMKind::Wasmer2
if cfg!(target_arch = "x86_64") {
if checked_feature!("stable", Wasmer2, protocol_version) {
VMKind::Wasmer2
} else {
VMKind::Wasmer0
}
} else {
VMKind::Wasmer0
VMKind::Wasmtime
}
}
}