Repository: bytecodealliance/wasmtime
Pull request #8469 (2024-04-25 03:40:01)

cranelift: Simplify computing the clobber set
We have a perfectly good data structure for holding sets of physical registers. We don't need a hash-set to determine whether we already added a register to an array when we can just add it to a PRegSet and then extract a suitable array out of that.

This change also makes the computed array sorted, which isn't particularly important since the backends all modify it and then sort it again, but is generally a nice property to have.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 47abbadae..d80c28cbf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 [[package]]
 name = "ahash"
-version = "0.8.7"
+version = "0.8.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -161,15 +161,6 @@ version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
 
-[[package]]
-name = "bincode"
-version = "1.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
-dependencies = [
- "serde",
-]
-
 [[package]]
 name = "bit-set"
 version = "0.5.2"
@@ -473,6 +464,12 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
 
+[[package]]
+name = "cobs"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15"
+
 [[package]]
 name = "codespan-reporting"
 version = "0.11.1"
@@ -599,7 +596,6 @@ name = "cranelift-codegen"
 version = "0.108.0"
 dependencies = [
  "anyhow",
- "bincode",
  "bumpalo",
  "capstone",
  "cranelift-bforest",
@@ -610,8 +606,9 @@ dependencies = [
  "cranelift-isle",
  "criterion",
  "gimli",
- "hashbrown 0.14.0",
+ "hashbrown 0.14.3",
  "log",
+ "postcard",
  "regalloc2",
  "serde",
  "serde_derive",
@@ -682,7 +679,7 @@ name = "cranelift-frontend"
 version = "0.108.0"
 dependencies = [
  "cranelift-codegen",
- "hashbrown 0.14.0",
+ "hashbrown 0.14.3",
  "log",
  "similar",
  "smallvec",
@@ -752,7 +749,7 @@ dependencies = [
  "anyhow",
  "cranelift-codegen",
  "cranelift-control",
- "hashbrown 0.14.0",
+ "hashbrown 0.14.3",
  "serde",
  "serde_derive",
 ]
@@ -842,14 +839,14 @@ dependencies = [
  "cranelift-codegen",
  "cranelift-entity",
  "cranelift-frontend",
- "hashbrown 0.14.0",
+ "hashbrown 0.14.3",
  "itertools 0.12.1",
  "log",
  "serde",
  "serde_derive",
  "smallvec",
  "target-lexicon",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmtime-types",
  "wat",
 ]
@@ -1045,6 +1042,12 @@ version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
+[[package]]
+name = "embedded-io"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
+
 [[package]]
 name = "embedding"
 version = "21.0.0"
@@ -1390,9 +1393,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.14.0"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
 dependencies = [
  "ahash",
 ]
@@ -1549,7 +1552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
 dependencies = [
  "equivalent",
- "hashbrown 0.14.0",
+ "hashbrown 0.14.3",
  "serde",
 ]
 
@@ -1923,7 +1926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d"
 dependencies = [
  "crc32fast",
- "hashbrown 0.14.0",
+ "hashbrown 0.14.3",
  "indexmap 2.0.0",
  "memchr",
 ]
@@ -2090,6 +2093,17 @@ dependencies = [
  "plotters-backend",
 ]
 
+[[package]]
+name = "postcard"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8"
+dependencies = [
+ "cobs",
+ "embedded-io",
+ "serde",
+]
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.16"
@@ -2756,7 +2770,7 @@ dependencies = [
  "cargo_metadata",
  "heck",
  "wasmtime",
- "wit-component 0.205.0",
+ "wit-component 0.206.0",
 ]
 
 [[package]]
@@ -3092,7 +3106,7 @@ name = "verify-component-adapter"
 version = "21.0.0"
 dependencies = [
  "anyhow",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wat",
 ]
 
@@ -3184,7 +3198,7 @@ dependencies = [
  "byte-array-literals",
  "object 0.33.0",
  "wasi",
- "wasm-encoder 0.205.0",
+ "wasm-encoder 0.206.0",
  "wit-bindgen",
 ]
 
@@ -3253,9 +3267,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e95b3563d164f33c1cfb0a7efbd5940c37710019be10cd09f800fdec8b0e5c"
+checksum = "d759312e1137f199096d80a70be685899cd7d3d09c572836bb2e9b69b4dc3b1e"
 dependencies = [
  "leb128",
 ]
@@ -3278,9 +3292,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-metadata"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9855ad6dd4d099fa8505f01fb0b84c7e3efd5f555207329e3ad938d5f394fe7"
+checksum = "84435ac34e29de6154fdb180ebbe2bdde96336f7ad0990003c43a21bd441303f"
 dependencies = [
  "anyhow",
  "indexmap 2.0.0",
@@ -3288,36 +3302,36 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "spdx",
- "wasm-encoder 0.205.0",
- "wasmparser 0.205.0",
+ "wasm-encoder 0.206.0",
+ "wasmparser 0.206.0",
 ]
 
 [[package]]
 name = "wasm-mutate"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d92842509e0cc163a0f8f4a54e38ec180e18594b9ed3999d0a05108e70d25cb3"
+checksum = "afd8f7a4dc2b33e16b5fe96e31922ab3d5351abd93e404fcdc5bdd67d91915f0"
 dependencies = [
  "egg",
  "log",
  "rand",
  "thiserror",
- "wasm-encoder 0.205.0",
- "wasmparser 0.205.0",
+ "wasm-encoder 0.206.0",
+ "wasmparser 0.206.0",
 ]
 
 [[package]]
 name = "wasm-smith"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1218f393276f7a13f6c54467434633144b46c33ecbc3cbafdc938033f0315d1a"
+checksum = "797d1293e8c8ce440c22dc283b7db0f68035929928f1736f12f4d9bf8fd2a24d"
 dependencies = [
  "anyhow",
  "arbitrary",
  "flagset",
  "indexmap 2.0.0",
  "leb128",
- "wasm-encoder 0.205.0",
+ "wasm-encoder 0.206.0",
 ]
 
 [[package]]
@@ -3373,11 +3387,13 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d457bb52804242e09d55a306e53ddbc65d1d29ed83db6a4eea3ed412ee0cfdf"
+checksum = "39192edb55d55b41963db40fd49b0b542156f04447b5b512744a91d38567bdbc"
 dependencies = [
+ "ahash",
  "bitflags 2.4.1",
+ "hashbrown 0.14.3",
  "indexmap 2.0.0",
  "semver",
 ]
@@ -3393,12 +3409,12 @@ dependencies = [
 
 [[package]]
 name = "wasmprinter"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edcd1e00bc348d4b1c0abe913d86f4a89377cbd5c1c704d4eca5cf3492a27da8"
+checksum = "3dec456f9cc479792c9920055cd499ae1d13f85e98f9443dfe4ea5751b21f3b0"
 dependencies = [
  "anyhow",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
 ]
 
 [[package]]
@@ -3408,7 +3424,6 @@ dependencies = [
  "addr2line",
  "anyhow",
  "async-trait",
- "bincode",
  "bumpalo",
  "cfg-if",
  "encoding_rs",
@@ -3421,6 +3436,7 @@ dependencies = [
  "object 0.33.0",
  "once_cell",
  "paste",
+ "postcard",
  "rayon",
  "rustix",
  "semver",
@@ -3430,8 +3446,8 @@ dependencies = [
  "target-lexicon",
  "tempfile",
  "wasi-common",
- "wasm-encoder 0.205.0",
- "wasmparser 0.205.0",
+ "wasm-encoder 0.206.0",
+ "wasmparser 0.206.0",
  "wasmtime-cache",
  "wasmtime-component-macro",
  "wasmtime-component-util",
@@ -3509,11 +3525,11 @@ version = "21.0.0"
 dependencies = [
  "anyhow",
  "base64",
- "bincode",
  "directories-next",
  "filetime",
  "log",
  "once_cell",
+ "postcard",
  "pretty_env_logger",
  "rustix",
  "serde",
@@ -3571,7 +3587,7 @@ dependencies = [
  "tracing",
  "walkdir",
  "wasi-common",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmtime",
  "wasmtime-cache",
  "wasmtime-cli-flags",
@@ -3585,10 +3601,10 @@ dependencies = [
  "wasmtime-wasi-nn",
  "wasmtime-wasi-threads",
  "wasmtime-wast",
- "wast 205.0.0",
+ "wast 206.0.0",
  "wat",
  "windows-sys 0.52.0",
- "wit-component 0.205.0",
+ "wit-component 0.206.0",
 ]
 
 [[package]]
@@ -3619,7 +3635,7 @@ dependencies = [
  "wasmtime",
  "wasmtime-component-util",
  "wasmtime-wit-bindgen",
- "wit-parser 0.205.0",
+ "wit-parser 0.206.0",
 ]
 
 [[package]]
@@ -3643,7 +3659,7 @@ dependencies = [
  "object 0.33.0",
  "target-lexicon",
  "thiserror",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmtime-environ",
  "wasmtime-versioned-export-macros",
 ]
@@ -3653,7 +3669,6 @@ name = "wasmtime-environ"
 version = "21.0.0"
 dependencies = [
  "anyhow",
- "bincode",
  "clap",
  "cpp_demangle",
  "cranelift-entity",
@@ -3662,13 +3677,14 @@ dependencies = [
  "indexmap 2.0.0",
  "log",
  "object 0.33.0",
+ "postcard",
  "rustc-demangle",
  "serde",
  "serde_derive",
  "target-lexicon",
  "thiserror",
- "wasm-encoder 0.205.0",
- "wasmparser 0.205.0",
+ "wasm-encoder 0.206.0",
+ "wasmparser 0.206.0",
  "wasmprinter",
  "wasmtime-component-util",
  "wasmtime-types",
@@ -3683,7 +3699,7 @@ dependencies = [
  "component-fuzz-util",
  "env_logger",
  "libfuzzer-sys",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmprinter",
  "wasmtime-environ",
  "wat",
@@ -3740,7 +3756,7 @@ dependencies = [
  "rand",
  "smallvec",
  "target-lexicon",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmtime",
  "wasmtime-fuzzing",
 ]
@@ -3761,12 +3777,12 @@ dependencies = [
  "target-lexicon",
  "tempfile",
  "v8",
- "wasm-encoder 0.205.0",
+ "wasm-encoder 0.206.0",
  "wasm-mutate",
  "wasm-smith",
  "wasm-spec-interpreter",
  "wasmi",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmprinter",
  "wasmtime",
  "wasmtime-wast",
@@ -3814,7 +3830,7 @@ dependencies = [
  "rustix",
  "smallvec",
  "sptr",
- "wasm-encoder 0.205.0",
+ "wasm-encoder 0.206.0",
  "wasmtime-asm-macros",
  "wasmtime-environ",
  "wasmtime-fiber",
@@ -3838,7 +3854,7 @@ dependencies = [
  "serde_derive",
  "smallvec",
  "thiserror",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
 ]
 
 [[package]]
@@ -3945,7 +3961,7 @@ dependencies = [
  "anyhow",
  "log",
  "wasmtime",
- "wast 205.0.0",
+ "wast 206.0.0",
 ]
 
 [[package]]
@@ -3957,7 +3973,7 @@ dependencies = [
  "gimli",
  "object 0.33.0",
  "target-lexicon",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmtime-cranelift",
  "wasmtime-environ",
  "winch-codegen",
@@ -3970,7 +3986,7 @@ dependencies = [
  "anyhow",
  "heck",
  "indexmap 2.0.0",
- "wit-parser 0.205.0",
+ "wit-parser 0.206.0",
 ]
 
 [[package]]
@@ -3988,24 +4004,24 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "205.0.0"
+version = "206.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "441a6a195b3b5245e26d450bbcc91366c6b652382a22f63cbe3c73240e13b2bb"
+checksum = "68586953ee4960b1f5d84ebf26df3b628b17e6173bc088e0acfbce431469795a"
 dependencies = [
  "bumpalo",
  "leb128",
  "memchr",
  "unicode-width",
- "wasm-encoder 0.205.0",
+ "wasm-encoder 0.206.0",
 ]
 
 [[package]]
 name = "wat"
-version = "1.205.0"
+version = "1.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19832624d606e7c6bf3cd4caa73578ecec5eac30c768269256d19c79900beb18"
+checksum = "da4c6f2606276c6e991aebf441b2fc92c517807393f039992a3e0ad873efe4ad"
 dependencies = [
- "wast 205.0.0",
+ "wast 206.0.0",
 ]
 
 [[package]]
@@ -4135,7 +4151,7 @@ dependencies = [
  "regalloc2",
  "smallvec",
  "target-lexicon",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
  "wasmtime-cranelift",
  "wasmtime-environ",
 ]
@@ -4386,9 +4402,9 @@ dependencies = [
 
 [[package]]
 name = "wit-component"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74841e17b2c2bfbd8ca8c45190ef85dff1c5e8659f0e2d164802ffc87dfb18c3"
+checksum = "81e1ae4cace3706e29a8cf1f728b792255ecdc02653b9f4130ab6cc64f435a67"
 dependencies = [
  "anyhow",
  "bitflags 2.4.1",
@@ -4397,10 +4413,10 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "wasm-encoder 0.205.0",
- "wasm-metadata 0.205.0",
- "wasmparser 0.205.0",
- "wit-parser 0.205.0",
+ "wasm-encoder 0.206.0",
+ "wasm-metadata 0.206.0",
+ "wasmparser 0.206.0",
+ "wit-parser 0.206.0",
 ]
 
 [[package]]
@@ -4423,9 +4439,9 @@ dependencies = [
 
 [[package]]
 name = "wit-parser"
-version = "0.205.0"
+version = "0.206.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3db34c7688c161ed7bd1b2f8055dca9fb2c15201db58754e9c48a0805f32e5f"
+checksum = "d226de4e95e052cb664d2bdad2f31d9cad5117038a3439568f078d1afd8842fe"
 dependencies = [
  "anyhow",
  "id-arena",
@@ -4436,7 +4452,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.205.0",
+ "wasmparser 0.206.0",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index f137a2e26..41cec657f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -234,15 +234,15 @@ rustix = "0.38.31"
 wit-bindgen = { version = "0.22.0", default-features = false }
 
 # wasm-tools family:
-wasmparser = "0.205.0"
-wat = "1.205.0"
-wast = "205.0.0"
-wasmprinter = "0.205.0"
-wasm-encoder = "0.205.0"
-wasm-smith = "0.205.0"
-wasm-mutate = "0.205.0"
-wit-parser = "0.205.0"
-wit-component = "0.205.0"
+wasmparser = "0.206.0"
+wat = "1.206.0"
+wast = "206.0.0"
+wasmprinter = "0.206.0"
+wasm-encoder = "0.206.0"
+wasm-smith = "0.206.0"
+wasm-mutate = "0.206.0"
+wit-parser = "0.206.0"
+wit-component = "0.206.0"
 
 # Non-Bytecode Alliance maintained dependencies:
 # --------------------------
@@ -290,7 +290,7 @@ test-log = { version = "0.2", default-features = false, features = ["trace"] }
 tracing-subscriber = { version = "0.3.1", default-features = false, features = ['fmt', 'env-filter', 'ansi', 'tracing-log'] }
 url = "2.3.1"
 humantime = "2.0.0"
-bincode = "1.2.1"
+postcard = { version = "1.0.8", default-features = false, features = ['alloc'] }
 
 # =============================================================================
 #
diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml
index 2dfde787e..02d4bb46f 100644
--- a/cranelift/codegen/Cargo.toml
+++ b/cranelift/codegen/Cargo.toml
@@ -28,7 +28,7 @@ target-lexicon = { workspace = true }
 log = { workspace = true }
 serde = { workspace = true, optional = true }
 serde_derive = { workspace = true, optional = true }
-bincode = { workspace = true, optional = true }
+postcard = { workspace = true, optional = true }
 gimli = { workspace = true, features = ["write"], optional = true }
 smallvec = { workspace = true }
 regalloc2 = { workspace = true, features = ["checker", "trace-log"] }
@@ -100,7 +100,7 @@ enable-serde = [
 # Enable the incremental compilation cache for hot-reload use cases.
 incremental-cache = [
     "enable-serde",
-    "bincode",
+    "postcard",
     "sha2"
 ]
 
diff --git a/cranelift/codegen/src/incremental_cache.rs b/cranelift/codegen/src/incremental_cache.rs
index 6290e55f8..bf5f6215e 100644
--- a/cranelift/codegen/src/incremental_cache.rs
+++ b/cranelift/codegen/src/incremental_cache.rs
@@ -208,12 +208,12 @@ pub fn compute_cache_key(isa: &dyn TargetIsa, func: &Function) -> CacheKeyHash {
 /// of the function call. The value is left untouched.
 pub fn serialize_compiled(
     result: CompiledCodeStencil,
-) -> (CompiledCodeStencil, Result<Vec<u8>, bincode::Error>) {
+) -> (CompiledCodeStencil, Result<Vec<u8>, postcard::Error>) {
     let cached = CachedFunc {
         version_marker: VersionMarker,
         stencil: result,
     };
-    let result = bincode::serialize(&cached);
+    let result = postcard::to_allocvec(&cached);
     (cached.stencil, result)
 }
 
@@ -223,7 +223,7 @@ pub enum RecompileError {
     /// The version embedded in the cache entry isn't the same as cranelift's current version.
     VersionMismatch,
     /// An error occurred while deserializing the cache entry.
-    Deserialize(bincode::Error),
+    Deserialize(postcard::Error),
 }
 
 impl fmt::Display for RecompileError {
@@ -231,7 +231,7 @@ impl fmt::Display for RecompileError {
         match self {
             RecompileError::VersionMismatch => write!(f, "cranelift version mismatch",),
             RecompileError::Deserialize(err) => {
-                write!(f, "bincode failed during deserialization: {err}")
+                write!(f, "postcard failed during deserialization: {err}")
             }
         }
     }
@@ -243,7 +243,7 @@ impl fmt::Display for RecompileError {
 /// Precondition: the bytes must have retrieved from a cache store entry which hash value
 /// is strictly the same as the `Function`'s computed hash retrieved from `compute_cache_key`.
 pub fn try_finish_recompile(func: &Function, bytes: &[u8]) -> Result<CompiledCode, RecompileError> {
-    match bincode::deserialize::<CachedFunc>(bytes) {
+    match postcard::from_bytes::<CachedFunc>(bytes) {
         Ok(result) => {
             if result.version_marker != func.stencil.version_marker {
                 Err(RecompileError::VersionMismatch)
diff --git a/cranelift/codegen/src/machinst/abi.rs b/cranelift/codegen/src/machinst/abi.rs
index 3e0f3a52a..a5de3824d 100644
--- a/cranelift/codegen/src/machinst/abi.rs
+++ b/cranelift/codegen/src/machinst/abi.rs
@@ -1094,16 +1094,10 @@ pub struct Callee<M: ABIMachineSpec> {
     /// Register-argument defs, to be provided to the `args`
     /// pseudo-inst, and pregs to constrain them to.
     reg_args: Vec<ArgPair>,
-    /// Clobbered registers, from regalloc.
-    clobbered: Vec<Writable<RealReg>>,
-    /// Total number of spillslots, including for 'dynamic' types, from regalloc.
-    spillslots: Option<usize>,
     /// Finalized frame layout for this function.
     frame_layout: Option<FrameLayout>,
     /// The register holding the return-area pointer, if needed.
-    ret_area_ptr: Option<Writable<Reg>>,
-    /// Temp registers required for argument setup, if needed.
-    arg_temp_reg: Vec<Option<Writable<Reg>>>,
+    ret_area_ptr: Option<Reg>,
     /// Calling convention this function expects.
     call_conv: isa::CallConv,
     /// The settings controlling this function's compilation.
@@ -1243,11 +1237,8 @@ impl<M: ABIMachineSpec> Callee<M> {
             outgoing_args_size: 0,
             tail_args_size,
             reg_args: vec![],
-            clobbered: vec![],
-            spillslots: None,
             frame_layout: None,
             ret_area_ptr: None,
-            arg_temp_reg: vec![],
             call_conv,
             flags,
             isa_flags: isa_flags.clone(),
@@ -1412,45 +1403,19 @@ impl<M: ABIMachineSpec> Callee<M> {
         &self.ir_sig
     }
 
-    /// Does the ABI-body code need temp registers (and if so, of what type)?
-    /// They will be provided to `init()` as the `temps` arg if so.
-    pub fn temps_needed(&self, sigs: &SigSet) -> Vec<Type> {
-        let mut temp_tys = vec![];
-        for arg in sigs.args(self.sig) {
-            match arg {
-                &ABIArg::ImplicitPtrArg { pointer, .. } => match &pointer {
-                    &ABIArgSlot::Reg { .. } => {}
-                    &ABIArgSlot::Stack { ty, .. } => {
-                        temp_tys.push(ty);
-                    }
-                },
-                _ => {}
-            }
-        }
-        if sigs[self.sig].stack_ret_arg.is_some() {
-            temp_tys.push(M::word_type());
-        }
-        temp_tys
-    }
-
     /// Initialize. This is called after the Callee is constructed because it
-    /// may be provided with a vector of temp vregs, which can only be allocated
-    /// once the lowering context exists.
-    pub fn init(&mut self, sigs: &SigSet, temps: Vec<Writable<Reg>>) {
-        let mut temps_iter = temps.into_iter();
-        for arg in sigs.args(self.sig) {
-            let temp = match arg {
-                &ABIArg::ImplicitPtrArg { pointer, .. } => match &pointer {
-                    &ABIArgSlot::Reg { .. } => None,
-                    &ABIArgSlot::Stack { .. } => Some(temps_iter.next().unwrap()),
-                },
-                _ => None,
-            };
-            self.arg_temp_reg.push(temp);
-        }
+    /// may allocate a temp vreg, which can only be allocated once the lowering
+    /// context exists.
+    pub fn init_retval_area(
+        &mut self,
+        sigs: &SigSet,
+        vregs: &mut VRegAllocator<M::I>,
+    ) -> CodegenResult<()> {
         if sigs[self.sig].stack_ret_arg.is_some() {
-            self.ret_area_ptr = Some(temps_iter.next().unwrap());
+            let ret_area_ptr = vregs.alloc(M::word_type())?;
+            self.ret_area_ptr = Some(ret_area_ptr.only_reg().unwrap());
         }
+        Ok(())
     }
 
     /// Accumulate outgoing arguments.
@@ -1580,9 +1545,9 @@ impl<M: ABIMachineSpec> Callee<M> {
                         tmp
                     }
                     &ABIArgSlot::Stack { offset, ty, .. } => {
-                        // In this case we need a temp register to hold the address.
-                        // This was allocated in the `init` routine.
-                        let addr_reg = self.arg_temp_reg[idx].unwrap();
+                        let addr_reg = writable_value_regs(vregs.alloc_with_deferred_error(ty))
+                            .only_reg()
+                            .unwrap();
                         insts.push(M::gen_load_stack(
                             StackAMode::IncomingArg(offset, sigs[self.sig].sized_stack_arg_space),
                             addr_reg,
@@ -1682,7 +1647,7 @@ impl<M: ABIMachineSpec> Callee<M> {
                                 _ => {}
                             };
                             ret.push(M::gen_store_base_offset(
-                                self.ret_area_ptr.unwrap().to_reg(),
+                                self.ret_area_ptr.unwrap(),
                                 off,
                                 from_reg,
                                 ty,
@@ -1712,17 +1677,14 @@ impl<M: ABIMachineSpec> Callee<M> {
         vregs: &mut VRegAllocator<M::I>,
     ) -> Option<M::I> {
         if let Some(i) = sigs[self.sig].stack_ret_arg {
-            let insts = self.gen_copy_arg_to_regs(
-                sigs,
-                i.into(),
-                ValueRegs::one(self.ret_area_ptr.unwrap()),
-                vregs,
-            );
+            let ret_area_ptr = Writable::from_reg(self.ret_area_ptr.unwrap());
+            let insts =
+                self.gen_copy_arg_to_regs(sigs, i.into(), ValueRegs::one(ret_area_ptr), vregs);
             insts.into_iter().next().map(|inst| {
                 trace!(
                     "gen_retval_area_setup: inst {:?}; ptr reg is {:?}",
                     inst,
-                    self.ret_area_ptr.unwrap().to_reg()
+                    ret_area_ptr.to_reg()
                 );
                 inst
             })
@@ -1777,16 +1739,6 @@ impl<M: ABIMachineSpec> Callee<M> {
 /// These methods of `Callee` may only be called after
 /// regalloc.
 impl<M: ABIMachineSpec> Callee<M> {
-    /// Update with the number of spillslots, post-regalloc.
-    pub fn set_num_spillslots(&mut self, slots: usize) {
-        self.spillslots = Some(slots);
-    }
-
-    /// Update with the clobbered registers, post-regalloc.
-    pub fn set_clobbered(&mut self, clobbered: Vec<Writable<RealReg>>) {
-        self.clobbered = clobbered;
-    }
-
     /// Generate a stack map, given a list of spillslots and the emission state
     /// at a given program point (prior to emission of the safepointing
     /// instruction).
@@ -1823,16 +1775,21 @@ impl<M: ABIMachineSpec> Callee<M> {
     /// Compute the final frame layout, post-regalloc.
     ///
     /// This must be called before gen_prologue or gen_epilogue.
-    pub fn compute_frame_layout(&mut self, sigs: &SigSet) {
+    pub fn compute_frame_layout(
+        &mut self,
+        sigs: &SigSet,
+        spillslots: usize,
+        clobbered: Vec<Writable<RealReg>>,
+    ) {
         let bytes = M::word_bytes();
-        let total_stacksize = self.stackslots_size + bytes * self.spillslots.unwrap() as u32;
+        let total_stacksize = self.stackslots_size + bytes * spillslots as u32;
         let mask = M::stack_align(self.call_conv) - 1;
         let total_stacksize = (total_stacksize + mask) & !mask; // 16-align the stack.
         self.frame_layout = Some(M::compute_frame_layout(
             self.call_conv,
             &self.flags,
             self.signature(),
-            &self.clobbered,
+            &clobbered,
             self.is_leaf,
             self.stack_args_size(sigs),
             self.tail_args_size,
@@ -2401,7 +2358,7 @@ impl<M: ABIMachineSpec> CallSite<M> {
                 "if the tail callee has a return pointer, then the tail caller \
                  must as well",
             );
-            self.gen_arg(ctx, i.into(), ValueRegs::one(ret_area_ptr.to_reg()));
+            self.gen_arg(ctx, i.into(), ValueRegs::one(ret_area_ptr));
         }
     }
 
diff --git a/cranelift/codegen/src/machinst/lower.rs b/cranelift/codegen/src/machinst/lower.rs
index a6b3bc501..cbd0491fc 100644
--- a/cranelift/codegen/src/machinst/lower.rs
+++ b/cranelift/codegen/src/machinst/lower.rs
@@ -1019,15 +1019,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
     ) -> CodegenResult<VCode<I>> {
         trace!("about to lower function: {:?}", self.f);
 
-        // Initialize the ABI object, giving it temps if requested.
-        let temps = self
-            .vcode
-            .abi()
-            .temps_needed(self.sigs())
-            .into_iter()
-            .map(|temp_ty| self.alloc_tmp(temp_ty).only_reg().unwrap())
-            .collect::<Vec<_>>();
-        self.vcode.init_abi(temps);
+        self.vcode.init_retval_area(&mut self.vregs)?;
 
         // Get the pinned reg here (we only parameterize this function on `B`,
         // not the whole `Lower` impl).
diff --git a/cranelift/codegen/src/machinst/vcode.rs b/cranelift/codegen/src/machinst/vcode.rs
index d246a31dd..ea34e8477 100644
--- a/cranelift/codegen/src/machinst/vcode.rs
+++ b/cranelift/codegen/src/machinst/vcode.rs
@@ -291,8 +291,8 @@ impl<I: VCodeInst> VCodeBuilder<I> {
         }
     }
 
-    pub fn init_abi(&mut self, temps: Vec<Writable<Reg>>) {
-        self.vcode.abi.init(&self.vcode.sigs, temps);
+    pub fn init_retval_area(&mut self, vregs: &mut VRegAllocator<I>) -> CodegenResult<()> {
+        self.vcode.abi.init_retval_area(&self.vcode.sigs, vregs)
     }
 
     /// Access the ABI object.
@@ -658,18 +658,12 @@ impl<I: VCodeInst> VCode<I> {
     }
 
     fn compute_clobbers(&self, regalloc: &regalloc2::Output) -> Vec<Writable<RealReg>> {
-        // Compute clobbered registers.
-        let mut clobbered = vec![];
-        let mut clobbered_set = FxHashSet::default();
+        let mut clobbered = PRegSet::default();
 
         // All moves are included in clobbers.
-        for edit in &regalloc.edits {
-            let Edit::Move { to, .. } = edit.1;
+        for (_, Edit::Move { to, .. }) in &regalloc.edits {
             if let Some(preg) = to.as_reg() {
-                let reg = RealReg::from(preg);
-                if clobbered_set.insert(reg) {
-                    clobbered.push(Writable::from_reg(reg));
-                }
+                clobbered.add(preg);
             }
         }
 
@@ -689,33 +683,23 @@ impl<I: VCodeInst> VCode<I> {
             let operands = &self.operands[start..end];
             let allocs = &regalloc.allocs[start..end];
             for (operand, alloc) in operands.iter().zip(allocs.iter()) {
-                // We're interested only in writes (Mods or Defs).
-                if operand.kind() == OperandKind::Use {
-                    continue;
-                }
-                if let Some(preg) = alloc.as_reg() {
-                    let reg = RealReg::from(preg);
-                    if clobbered_set.insert(reg) {
-                        clobbered.push(Writable::from_reg(reg));
+                if operand.kind() == OperandKind::Def {
+                    if let Some(preg) = alloc.as_reg() {
+                        clobbered.add(preg);
                     }
                 }
             }
 
             // Also add explicitly-clobbered registers.
-            for preg in self
-                .clobbers
-                .get(&InsnIndex::new(i))
-                .cloned()
-                .unwrap_or_default()
-            {
-                let reg = RealReg::from(preg);
-                if clobbered_set.insert(reg) {
-                    clobbered.push(Writable::from_reg(reg));
-                }
+            if let Some(&inst_clobbered) = self.clobbers.get(&InsnIndex::new(i)) {
+                clobbered.union_from(inst_clobbered);
             }
         }
 
         clobbered
+            .into_iter()
+            .map(|preg| Writable::from_reg(RealReg::from(preg)))
+            .collect()
     }
 
     /// Emit the instructions to a `MachBuffer`, containing fixed-up
@@ -772,9 +756,8 @@ impl<I: VCodeInst> VCode<I> {
         // setting clobbers is fairly minimal so this should be
         // relatively cheap.
         let clobbers = self.compute_clobbers(regalloc);
-        self.abi.set_num_spillslots(regalloc.num_spillslots);
-        self.abi.set_clobbered(clobbers);
-        self.abi.compute_frame_layout(&self.sigs);
+        self.abi
+            .compute_frame_layout(&self.sigs, regalloc.num_spillslots, clobbers);
 
         // Emit blocks.
         let mut cur_srcloc = None;
@@ -1260,26 +1243,8 @@ impl<I: VCodeInst> VCode<I> {
     }
 
     #[inline]
-    fn assert_no_vreg_aliases<'a>(&self, list: &'a [VReg]) -> &'a [VReg] {
-        for vreg in list {
-            self.assert_not_vreg_alias(*vreg);
-        }
-        list
-    }
-
-    #[inline]
-    fn assert_not_vreg_alias(&self, vreg: VReg) -> VReg {
-        debug_assert!(self.resolve_vreg_alias(vreg) == vreg);
-        vreg
-    }
-
-    #[inline]
-    fn assert_operand_not_vreg_alias(&self, op: Operand) -> Operand {
-        // It should be true by construction that `Operand`s do not contain any
-        // aliased vregs since they're all collected and mapped when the VCode
-        // is itself constructed.
-        self.assert_not_vreg_alias(op.vreg());
-        op
+    fn debug_assert_no_vreg_aliases(&self, mut list: impl Iterator<Item = VReg>) {
+        debug_assert!(list.all(|vreg| !self.vreg_aliases.contains_key(&vreg)));
     }
 
     /// Get the type of a VReg.
@@ -1356,7 +1321,8 @@ impl<I: VCodeInst> RegallocFunction for VCode<I> {
         let ret = &self.block_params[start as usize..end as usize];
         // Currently block params are never aliased to another vreg, but
         // double-check just to be sure.
-        self.assert_no_vreg_aliases(ret)
+        self.debug_assert_no_vreg_aliases(ret.iter().copied());
+        ret
     }
 
     fn branch_blockparams(&self, block: BlockIndex, _insn: InsnIndex, succ_idx: usize) -> &[VReg] {
@@ -1366,7 +1332,8 @@ impl<I: VCodeInst> RegallocFunction for VCode<I> {
         let (branch_block_args_start, branch_block_args_end) = succ_ranges[succ_idx];
         let ret = &self.branch_block_args
             [branch_block_args_start as usize..branch_block_args_end as usize];
-        self.assert_no_vreg_aliases(ret)
+        self.debug_assert_no_vreg_aliases(ret.iter().copied());
+        ret
     }
 
     fn is_ret(&self, insn: InsnIndex) -> bool {
@@ -1392,9 +1359,10 @@ impl<I: VCodeInst> RegallocFunction for VCode<I> {
     fn inst_operands(&self, insn: InsnIndex) -> &[Operand] {
         let (start, end) = self.operand_ranges[insn.index()];
         let ret = &self.operands[start as usize..end as usize];
-        for op in ret {
-            self.assert_operand_not_vreg_alias(*op);
-        }
+        // It should be true by construction that `Operand`s do not contain any
+        // aliased vregs since they're all collected and mapped when the VCode
+        // is itself constructed.
+        self.debug_assert_no_vreg_aliases(ret.iter().map(|op| op.vreg()));
         ret
     }
 
@@ -1407,17 +1375,18 @@ impl<I: VCodeInst> RegallocFunction for VCode<I> {
     }
 
     fn reftype_vregs(&self) -> &[VReg] {
-        self.assert_no_vreg_aliases(&self.reftyped_vregs[..])
+        let ret = &self.reftyped_vregs;
+        self.debug_assert_no_vreg_aliases(ret.iter().copied());
+        ret
     }
 
     fn debug_value_labels(&self) -> &[(VReg, InsnIndex, InsnIndex, u32)] {
         // VRegs here are inserted into `debug_value_labels` after code is
-        // generated and aliases are fully defined, so no double-check that
+        // generated and aliases are fully defined, so double-check that
         // aliases are not lingering.
-        for (vreg, ..) in self.debug_value_labels.iter() {
-            self.assert_not_vreg_alias(*vreg);
-        }
-        &self.debug_value_labels[..]
+        let ret = &self.debug_value_labels;
+        self.debug_assert_no_vreg_aliases(ret.iter().map(|&(vreg, ..)| vreg));
+        ret
     }
 
     fn spillslot_size(&self, regclass: RegClass) -> usize {
diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs
index 581f6a87a..af51c5602 100644
--- a/cranelift/object/src/backend.rs
+++ b/cranelift/object/src/backend.rs
@@ -39,10 +39,10 @@ impl ObjectBuilder {
     /// Create a new `ObjectBuilder` using the given Cranelift target, that
     /// can be passed to [`ObjectModule::new`].
     ///
-    /// The `libcall_names` function provides a way to translate `cranelift_codegen`'s [ir::LibCall]
+    /// The `libcall_names` function provides a way to translate `cranelift_codegen`'s [`ir::LibCall`]
     /// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
     /// floating point instructions, and for stack probes. If you don't know what to use for this
-    /// argument, use [cranelift_module::default_libcall_names]().
+    /// argument, use [`cranelift_module::default_libcall_names`].
     pub fn new<V: Into<Vec<u8>>>(
         isa: OwnedTargetIsa,
         name: V,
diff --git a/cranelift/wasm/src/sections_translator.rs b/cranelift/wasm/src/sections_translator.rs
index ba1b4ad0a..c9c89633b 100644
--- a/cranelift/wasm/src/sections_translator.rs
+++ b/cranelift/wasm/src/sections_translator.rs
@@ -381,6 +381,7 @@ pub fn parse_name_section<'data>(
             | wasmparser::Name::Element(_)
             | wasmparser::Name::Data(_)
             | wasmparser::Name::Tag(_)
+            | wasmparser::Name::Field(_)
             | wasmparser::Name::Unknown { .. } => {}
         }
     }
diff --git a/crates/cache/Cargo.toml b/crates/cache/Cargo.toml
index 475f3828e..481f54641 100644
--- a/crates/cache/Cargo.toml
+++ b/crates/cache/Cargo.toml
@@ -14,7 +14,7 @@ workspace = true
 [dependencies]
 anyhow = { workspace = true }
 base64 = "0.21.0"
-bincode = { workspace = true }
+postcard = { workspace = true }
 directories-next = "2.0"
 log = { workspace = true }
 serde = { workspace = true }
diff --git a/crates/cache/src/lib.rs b/crates/cache/src/lib.rs
index 279831259..aabaded44 100644
--- a/crates/cache/src/lib.rs
+++ b/crates/cache/src/lib.rs
@@ -54,8 +54,8 @@ impl<'config> ModuleCacheEntry<'config> {
         self.get_data_raw(
             &state,
             compute,
-            |_state, data| bincode::serialize(data).ok(),
-            |_state, data| bincode::deserialize(&data).ok(),
+            |_state, data| postcard::to_allocvec(data).ok(),
+            |_state, data| postcard::from_bytes(&data).ok(),
         )
     }
 
diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml
index bcf072581..2a6e1abf6 100644
--- a/crates/environ/Cargo.toml
+++ b/crates/environ/Cargo.toml
@@ -15,7 +15,7 @@ workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-bincode = { workspace = true }
+postcard = { workspace = true }
 cpp_demangle = { version = "0.4.3", optional = true }
 cranelift-entity = { workspace = true }
 wasmtime-types = { workspace = true }
diff --git a/crates/environ/src/compile/module_artifacts.rs b/crates/environ/src/compile/module_artifacts.rs
index 68f19e377..79b6f4c77 100644
--- a/crates/environ/src/compile/module_artifacts.rs
+++ b/crates/environ/src/compile/module_artifacts.rs
@@ -1,5 +1,5 @@
 //! Definitions of runtime structures and metadata which are serialized into ELF
-//! with `bincode` as part of a module's compilation process.
+//! with `postcard` as part of a module's compilation process.
 
 use crate::{
     obj, CompiledFunctionInfo, CompiledModuleInfo, DebugInfoData, DefinedFuncIndex, FunctionLoc,
@@ -261,7 +261,7 @@ impl<'a> ObjectBuilder<'a> {
             obj::ELF_WASMTIME_INFO.as_bytes().to_vec(),
             SectionKind::ReadOnlyData,
         );
-        let data = bincode::serialize(info).unwrap();
+        let data = postcard::to_allocvec(info).unwrap();
         self.obj.set_section_data(section, data, 1);
     }
 
diff --git a/crates/environ/src/component/types.rs b/crates/environ/src/component/types.rs
index 2afd9d87c..45f352ac7 100644
--- a/crates/environ/src/component/types.rs
+++ b/crates/environ/src/component/types.rs
@@ -831,7 +831,7 @@ impl ComponentTypesBuilder {
         self.add_tuple_type(TypeTuple { types, abi })
     }
 
-    fn flags_type(&mut self, flags: &IndexSet<KebabString>) -> TypeFlagsIndex {
+    fn flags_type(&mut self, flags: &wasmparser::map::IndexSet<KebabString>) -> TypeFlagsIndex {
         let flags = TypeFlags {
             names: flags.iter().map(|s| s.to_string()).collect(),
             abi: CanonicalAbiInfo::flags(flags.len()),
@@ -839,7 +839,7 @@ impl ComponentTypesBuilder {
         self.add_flags_type(flags)
     }
 
-    fn enum_type(&mut self, variants: &IndexSet<KebabString>) -> TypeEnumIndex {
+    fn enum_type(&mut self, variants: &wasmparser::map::IndexSet<KebabString>) -> TypeEnumIndex {
         let names = variants
             .iter()
             .map(|s| s.to_string())
diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs
index 9d91ff570..0257d3d2d 100644
--- a/crates/environ/src/module_environ.rs
+++ b/crates/environ/src/module_environ.rs
@@ -876,6 +876,7 @@ and for re-adding support for interface types you can see this issue:
                 | wasmparser::Name::Element(_)
                 | wasmparser::Name::Data(_)
                 | wasmparser::Name::Tag(_)
+                | wasmparser::Name::Field(_)
                 | wasmparser::Name::Unknown { .. } => {}
             }
         }
diff --git a/crates/wasi/src/preview1.rs b/crates/wasi/src/preview1.rs
index 41390112f..57fd0ebf5 100644
--- a/crates/wasi/src/preview1.rs
+++ b/crates/wasi/src/preview1.rs
@@ -2321,6 +2321,35 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
             // Indefinite sleeping is not supported in preview1.
             return Err(types::Errno::Inval.into());
         }
+
+        // This is a special case where `poll_oneoff` is just sleeping
+        // on a single relative timer event. This special case was added
+        // after experimental observations showed that std::thread::sleep
+        // results in more consistent sleep times. This design ensures that
+        // wasmtime can handle real-time requirements more accurately.
+        if nsubscriptions == 1 {
+            let sub = subs.read()?;
+            if let types::SubscriptionU::Clock(clocksub) = sub.u {
+                if !clocksub
+                    .flags
+                    .contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME)
+                    && self.ctx().allow_blocking_current_thread
+                {
+                    std::thread::sleep(std::time::Duration::from_nanos(clocksub.timeout));
+                    events.write(types::Event {
+                        userdata: sub.userdata,
+                        error: types::Errno::Success,
+                        type_: types::Eventtype::Clock,
+                        fd_readwrite: types::EventFdReadwrite {
+                            flags: types::Eventrwflags::empty(),
+                            nbytes: 1,
+                        },
+                    })?;
+                    return Ok(1);
+                }
+            }
+        }
+
         let subs = subs.as_array(nsubscriptions);
         let events = events.as_array(nsubscriptions);
 
diff --git a/crates/wasmtime/Cargo.toml b/crates/wasmtime/Cargo.toml
index 07e72b0fa..fccd5ba11 100644
--- a/crates/wasmtime/Cargo.toml
+++ b/crates/wasmtime/Cargo.toml
@@ -44,7 +44,7 @@ wat = { workspace = true, optional = true }
 serde = { workspace = true }
 serde_derive = { workspace = true }
 serde_json = { workspace = true }
-bincode = { workspace = true }
+postcard = { workspace = true }
 indexmap = { workspace = true }
 paste = "1.0.3"
 once_cell = { workspace = true }
diff --git a/crates/wasmtime/src/engine/serialization.rs b/crates/wasmtime/src/engine/serialization.rs
index d6254cdff..4aca40bc1 100644
--- a/crates/wasmtime/src/engine/serialization.rs
+++ b/crates/wasmtime/src/engine/serialization.rs
@@ -15,7 +15,7 @@
 //! 1. A version byte, currently `VERSION`.
 //! 2. A byte indicating how long the next field is.
 //! 3. A version string of the length of the previous byte value.
-//! 4. A `bincode`-encoded `Metadata` structure.
+//! 4. A `postcard`-encoded `Metadata` structure.
 //!
 //! This is hoped to help distinguish easily Wasmtime-based ELF files from
 //! other random ELF files, as well as provide better error messages for
@@ -110,7 +110,7 @@ pub fn check_compatible(engine: &Engine, mmap: &[u8], expected: ObjectKind) -> R
         }
         ModuleVersionStrategy::None => { /* ignore the version info, accept all */ }
     }
-    bincode::deserialize::<Metadata<'_>>(data)?.check_compatible(engine)
+    postcard::from_bytes::<Metadata<'_>>(data)?.check_compatible(engine)
 }
 
 #[cfg(any(feature = "cranelift", feature = "winch"))]
@@ -134,7 +134,7 @@ pub fn append_compiler_info(engine: &Engine, obj: &mut Object<'_>, metadata: &Me
     );
     data.push(version.len() as u8);
     data.extend_from_slice(version.as_bytes());
-    bincode::serialize_into(&mut data, metadata).unwrap();
+    data.extend(postcard::to_allocvec(metadata).unwrap());
     obj.set_section_data(section, data, 1);
 }
 
diff --git a/crates/wasmtime/src/runtime/component/component.rs b/crates/wasmtime/src/runtime/component/component.rs
index 4e263ba3f..09908b6b4 100644
--- a/crates/wasmtime/src/runtime/component/component.rs
+++ b/crates/wasmtime/src/runtime/component/component.rs
@@ -375,7 +375,7 @@ impl Component {
             static_modules,
         } = match artifacts {
             Some(artifacts) => artifacts,
-            None => bincode::deserialize(code_memory.wasmtime_info())?,
+            None => postcard::from_bytes(code_memory.wasmtime_info())?,
         };
 
         // Validate that the component can be used with the current instance
diff --git a/crates/wasmtime/src/runtime/module.rs b/crates/wasmtime/src/runtime/module.rs
index 04ecc47f1..42906a361 100644
--- a/crates/wasmtime/src/runtime/module.rs
+++ b/crates/wasmtime/src/runtime/module.rs
@@ -445,7 +445,7 @@ impl Module {
         // already.
         let (info, types) = match info_and_types {
             Some((info, types)) => (info, types),
-            None => bincode::deserialize(code_memory.wasmtime_info())?,
+            None => postcard::from_bytes(code_memory.wasmtime_info())?,
         };
 
         // Register function type signatures into the engine for the lifetime
diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml
index 0c5195ca7..21ffd2869 100644
--- a/supply-chain/audits.toml
+++ b/supply-chain/audits.toml
@@ -1062,6 +1062,12 @@ who = "Pat Hickey <phickey@fastly.com>"
 criteria = "safe-to-deploy"
 version = "0.2.0"
 
+[[audits.cobs]]
+who = "Alex Crichton <alex@alexcrichton.com>"
+criteria = "safe-to-deploy"
+version = "0.2.3"
+notes = "No `unsafe` code in the crate and no usage of `std`"
+
 [[audits.codespan-reporting]]
 who = "Jamey Sharp <jsharp@fastly.com>"
 criteria = "safe-to-deploy"
@@ -1197,6 +1203,12 @@ This diff brings in a number of minor updates of which none are related to
 `unsafe` code or anything system-related like filesystems.
 """
 
+[[audits.embedded-io]]
+who = "Alex Crichton <alex@alexcrichton.com>"
+criteria = "safe-to-deploy"
+version = "0.4.0"
+notes = "No `unsafe` code and only uses `std` in ways one would expect the crate to do so."
+
 [[audits.errno]]
 who = "Dan Gohman <dev@sunfishcode.online>"
 criteria = "safe-to-deploy"
@@ -2007,6 +2019,15 @@ No `unsafe` additions or anything outside of the purview of the crate in this
 change.
 """
 
+[[audits.postcard]]
+who = "Alex Crichton <alex@alexcrichton.com>"
+criteria = "safe-to-deploy"
+version = "1.0.8"
+notes = """
+I've audited the unsafe code to do what it looks like it's doing. Otherwise the
+crate is a standard serializer/deserializer crate.
+"""
+
 [[audits.pretty_env_logger]]
 who = "Alex Crichton <alex@alexcrichton.com>"
 criteria = "safe-to-deploy"
diff --git a/supply-chain/config.toml b/supply-chain/config.toml
index eb2b7081d..79a239e79 100644
--- a/supply-chain/config.toml
+++ b/supply-chain/config.toml
@@ -189,7 +189,7 @@ version = "0.17.0"
 criteria = "safe-to-deploy"
 
 [[exemptions.ahash]]
-version = "0.7.6"
+version = "0.8.11"
 criteria = "safe-to-deploy"
 
 [[exemptions.bincode]]
diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
index 61311c79f..9a86ce4b0 100644
--- a/supply-chain/imports.lock
+++ b/supply-chain/imports.lock
@@ -826,6 +826,13 @@ user-id = 2915
 user-login = "Amanieu"
 user-name = "Amanieu d'Antras"
 
+[[publisher.hashbrown]]
+version = "0.14.3"
+when = "2023-11-26"
+user-id = 2915
+user-login = "Amanieu"
+user-name = "Amanieu d'Antras"
+
 [[publisher.indexmap]]
 version = "1.9.1"
 when = "2022-06-21"
@@ -1196,6 +1203,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-encoder]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-metadata]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1226,6 +1239,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-metadata]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-mutate]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1256,6 +1275,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-mutate]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-smith]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1286,6 +1311,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-smith]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmparser]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1316,6 +1347,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasmparser]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmprinter]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1346,6 +1383,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasmprinter]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmtime]]
 version = "18.0.2"
 when = "2024-02-28"
@@ -1664,6 +1707,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wast]]
+version = "206.0.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wat]]
 version = "1.201.0"
 when = "2024-02-27"
@@ -1694,6 +1743,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wat]]
+version = "1.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wiggle]]
 version = "18.0.2"
 when = "2024-02-28"
@@ -1994,6 +2049,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-component]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-parser]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -2024,6 +2085,12 @@ when = "2024-04-18"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-parser]]
+version = "0.206.0"
+when = "2024-04-25"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.witx]]
 version = "0.9.1"
 when = "2021-06-22"


Test patch:
diff --git a/cranelift/filetests/filetests/isa/s390x/call.clif b/cranelift/filetests/filetests/isa/s390x/call.clif
index 1d72253b1..41bf58ea7 100644
--- a/cranelift/filetests/filetests/isa/s390x/call.clif
+++ b/cranelift/filetests/filetests/isa/s390x/call.clif
@@ -332,14 +332,14 @@ block0(v0: i128, v1: i128, v2: i128, v3: i128, v4: i128, v5: i128, v6: i128, v7:
 ;   vl %v24, 0(%r5)
 ;   lg %r4, 184(%r15)
 ;   vl %v27, 0(%r4)
-;   vaq %v16, %v1, %v3
-;   vaq %v17, %v5, %v7
-;   vaq %v18, %v18, %v21
-;   vaq %v19, %v24, %v27
-;   vaq %v16, %v16, %v17
-;   vaq %v17, %v18, %v19
-;   vaq %v16, %v16, %v17
-;   vst %v16, 0(%r2)
+;   vaq %v4, %v1, %v3
+;   vaq %v5, %v5, %v7
+;   vaq %v6, %v18, %v21
+;   vaq %v7, %v24, %v27
+;   vaq %v4, %v4, %v5
+;   vaq %v5, %v6, %v7
+;   vaq %v4, %v4, %v5
+;   vst %v4, 0(%r2)
 ;   br %r14
 ;
 ; Disassembled:
@@ -356,14 +356,14 @@ block0(v0: i128, v1: i128, v2: i128, v3: i128, v4: i128, v5: i128, v6: i128, v7:
 ;   vl %v24, 0(%r5)
 ;   lg %r4, 0xb8(%r15)
 ;   vl %v27, 0(%r4)
-;   vaq %v16, %v1, %v3
-;   vaq %v17, %v5, %v7
-;   vaq %v18, %v18, %v21
-;   vaq %v19, %v24, %v27
-;   vaq %v16, %v16, %v17
-;   vaq %v17, %v18, %v19
-;   vaq %v16, %v16, %v17
-;   vst %v16, 0(%r2)
+;   vaq %v4, %v1, %v3
+;   vaq %v5, %v5, %v7
+;   vaq %v6, %v18, %v21
+;   vaq %v7, %v24, %v27
+;   vaq %v4, %v4, %v5
+;   vaq %v5, %v6, %v7
+;   vaq %v4, %v4, %v5
+;   vst %v4, 0(%r2)
 ;   br %r14
 
 function %call_sret() -> i64 {