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

Run some tests in MIRI on CI #6332

Merged
merged 2 commits into from
May 3, 2023
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
46 changes: 46 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,51 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}

# Run a subset of tests under MIRI on CI to help check the `unsafe` code in
# Wasmtime to make sure it's at least not obviously incorrect for basic usage.
# Note that this doesn't run the full test suite since MIRI can't actually run
# WebAssembly itself at this time (aka it doesn't support a JIT). There are a
# number of annotations throughout the code which gates some tests on MIRI not
# being run.
#
# Note that `cargo nextest` is used here additionally to get parallel test
# execution by default to help cut down on the time in CI.
miri:
needs: determine
if: needs.determine.outputs.run-full
name: Miri
runs-on: ubuntu-latest
env:
CARGO_NEXTEST_VERSION: 0.9.51
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: ./.github/actions/install-rust
with:
toolchain: nightly-2023-03-20
- run: rustup component add rust-src miri
- uses: actions/cache@v3
with:
path: ${{ runner.tool_cache }}/cargo-nextest
key: cargo-nextest-bin-${{ env.CARGO_NEXTEST_VERSION }}
- run: echo "${{ runner.tool_cache }}/cargo-nextest/bin" >> $GITHUB_PATH
- run: cargo install --root ${{ runner.tool_cache }}/cargo-nextest --version ${{ env.CARGO_NEXTEST_VERSION }} cargo-nextest
- run: |
cargo miri nextest run -j4 --no-fail-fast \
-p wasmtime \
-p wasmtime-cli \
-p wasmtime-runtime \
-p wasmtime-environ
env:
MIRIFLAGS: -Zmiri-tree-borrows

# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}

# Perform release builds of `wasmtime` and `libwasmtime.so`. Builds a variety
# of platforms and architectures and then uploads the release artifacts to
# this workflow run's list of artifacts.
Expand Down Expand Up @@ -694,6 +739,7 @@ jobs:
- meta_deterministic_check
- verify-publish
- determine
- miri
if: always()
steps:
- name: Dump needs context
Expand Down
2 changes: 2 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ fn write_testsuite_tests(
// Ignore when using QEMU for running tests (limited memory).
if ignore(testsuite, &testname, strategy) {
writeln!(out, "#[ignore]")?;
} else {
writeln!(out, "#[cfg_attr(miri, ignore)]")?;
}

writeln!(
Expand Down
2 changes: 1 addition & 1 deletion cranelift/codegen/src/isa/x64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ fn isa_constructor(

// Check for compatibility between flags and ISA level
// requested. In particular, SIMD support requires SSE4.2.
if shared_flags.enable_simd() {
if !cfg!(miri) && shared_flags.enable_simd() {
if !isa_flags.has_sse3() || !isa_flags.has_ssse3() || !isa_flags.has_sse41() {
return Err(CodegenError::Unsupported(
"SIMD support requires SSE3, SSSE3, and SSE4.1 on x86_64.".into(),
Expand Down
56 changes: 33 additions & 23 deletions crates/environ/src/tunables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,26 @@ pub struct Tunables {

impl Default for Tunables {
fn default() -> Self {
let (static_memory_bound, static_memory_offset_guard_size) =
if cfg!(target_pointer_width = "64") {
// 64-bit has tons of address space to static memories can have 4gb
// address space reservations liberally by default, allowing us to
// help eliminate bounds checks.
//
// Coupled with a 2 GiB address space guard it lets us translate
// wasm offsets into x86 offsets as aggressively as we can.
(0x1_0000, 0x8000_0000)
} else if cfg!(target_pointer_width = "32") {
// For 32-bit we scale way down to 10MB of reserved memory. This
// impacts performance severely but allows us to have more than a
// few instances running around.
((10 * (1 << 20)) / crate::WASM_PAGE_SIZE as u64, 0x1_0000)
} else {
panic!("unsupported target_pointer_width");
};
let (static_memory_bound, static_memory_offset_guard_size) = if cfg!(miri) {
// No virtual memory tricks are available on miri so make these
// limits quite conservative.
((1 << 20) / crate::WASM_PAGE_SIZE as u64, 0)
} else if cfg!(target_pointer_width = "64") {
// 64-bit has tons of address space to static memories can have 4gb
// address space reservations liberally by default, allowing us to
// help eliminate bounds checks.
//
// Coupled with a 2 GiB address space guard it lets us translate
// wasm offsets into x86 offsets as aggressively as we can.
(0x1_0000, 0x8000_0000)
} else if cfg!(target_pointer_width = "32") {
// For 32-bit we scale way down to 10MB of reserved memory. This
// impacts performance severely but allows us to have more than a
// few instances running around.
((10 * (1 << 20)) / crate::WASM_PAGE_SIZE as u64, 0x1_0000)
} else {
panic!("unsupported target_pointer_width");
};
Self {
static_memory_bound,
static_memory_offset_guard_size,
Expand All @@ -78,14 +81,21 @@ impl Default for Tunables {
//
// Allocate a small guard to optimize common cases but without
// wasting too much memory.
dynamic_memory_offset_guard_size: 0x1_0000,
dynamic_memory_offset_guard_size: if cfg!(miri) { 0 } else { 0x1_0000 },

// We've got lots of address space on 64-bit so use a larger
// grow-into-this area, but on 32-bit we aren't as lucky.
#[cfg(target_pointer_width = "64")]
dynamic_memory_growth_reserve: 2 << 30, // 2GB
#[cfg(target_pointer_width = "32")]
dynamic_memory_growth_reserve: 1 << 20, // 1MB
// grow-into-this area, but on 32-bit we aren't as lucky. Miri is
// not exactly fast so reduce memory consumption instead of trying
// to avoid memory movement.
dynamic_memory_growth_reserve: if cfg!(miri) {
0
} else if cfg!(target_pointer_width = "64") {
2 << 30 // 2GB
} else if cfg!(target_pointer_width = "32") {
1 << 20 // 1MB
} else {
panic!("unsupported target_pointer_width");
},

generate_native_debuginfo: false,
parse_wasm_debuginfo: true,
Expand Down
3 changes: 3 additions & 0 deletions crates/jit-icache-coherence/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ cfg_if::cfg_if! {
if #[cfg(target_os = "windows")] {
mod win;
use win as imp;
} else if #[cfg(miri)] {
mod miri;
use crate::miri as imp;
} else {
mod libc;
use crate::libc as imp;
Expand Down
10 changes: 10 additions & 0 deletions crates/jit-icache-coherence/src/miri.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use std::ffi::c_void;
use std::io::Result;

pub(crate) fn pipeline_flush_mt() -> Result<()> {
Ok(())
}

pub(crate) fn clear_cache(_ptr: *const c_void, _len: usize) -> Result<()> {
Ok(())
}
3 changes: 3 additions & 0 deletions crates/jit/src/unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ cfg_if::cfg_if! {
if #[cfg(all(windows, any(target_arch = "x86_64", target_arch = "aarch64")))] {
mod winx64;
pub use self::winx64::*;
} else if #[cfg(miri)] {
mod miri;
pub use self::miri::*;
} else if #[cfg(unix)] {
mod systemv;
pub use self::systemv::*;
Expand Down
15 changes: 15 additions & 0 deletions crates/jit/src/unwind/miri.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use anyhow::Result;

pub struct UnwindRegistration {}

impl UnwindRegistration {
pub const SECTION_NAME: &str = ".eh_frame";

pub unsafe fn new(
_base_address: *const u8,
_unwind_info: *const u8,
_unwind_len: usize,
) -> Result<UnwindRegistration> {
Ok(UnwindRegistration {})
}
}
Loading