From 16351716c987e4d4d4eb88a118d69fdc2dc902b4 Mon Sep 17 00:00:00 2001 From: andreatp Date: Fri, 30 Oct 2026 14:22:04 +0000 Subject: [PATCH] Add the Endive 1.2.0 release blog post --- docs/blog/2026-10-30-endive-1.2.0.md | 129 +++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs/blog/2026-10-30-endive-1.2.0.md diff --git a/docs/blog/2026-10-30-endive-1.2.0.md b/docs/blog/2026-10-30-endive-1.2.0.md new file mode 100644 index 000000000..681eefe91 --- /dev/null +++ b/docs/blog/2026-10-30-endive-1.2.0.md @@ -0,0 +1,129 @@ +--- +slug: endive-1.2.0 +title: 'Endive 1.2.0: SIMD in the Interpreter, GC-Friendly Native Memory, and Components on the Horizon' +authors: [andreaTP] +tags: [wasm, endive, release, redline] +--- + +**Endive 1.2.0** is out. Modules that use SIMD now run in the interpreter on any Java from 11 up, with +nothing to add or configure. `redline` releases native memory once the Java objects using it become +unreachable, so closing an instance is optional. Atomics behave the same across memory implementations +and no longer collapse on JDK 25. And next door, Component Model support is taking shape. + + + +## SIMD in the Interpreter, from Java 11 Up + +All 236 instructions of the SIMD proposal are now part of the core interpreter: no extra module, no JVM +flag, no machine factory to wire. The implementation is plain Java with no dependency on the incubating +Vector API, so one jar behaves identically on every JDK, and it passes the WebAssembly SIMD +specification tests. + +We measured libsodium and OpenSSL, each built with and without SIMD: wherever the C compiler vectorised +a kernel, the SIMD build runs faster in the interpreter, because there are fewer instructions to +dispatch. The plain Java implementation also keeps pace with one built on the Vector API, which is why +it is the only one we ship. The numbers are in the +[pull request](https://github.com/bytecodealliance/endive/pull/205). + +The bytecode compilers and `redline` don't support SIMD yet: compiling a module that uses it fails, so +such modules need the interpreter for now. Compiler support is next. SIMD execution relies on +validation, so keep it enabled for modules that use `v128`. + +Upgrading from `run.endive:simd`? Drop the dependency and the +`withMachineFactory(SimdInterpreterMachine::new)` call. + +## `redline`: GC-Friendly Native Memory + +[`redline`](/docs/experimental/redline) compiles your Wasm module to native code with +[Cranelift](https://cranelift.dev/) at build time and runs it through Panama FFM or jffi. + +- **Native memory follows its Java objects.** Code, linear memories, tables and globals live off-heap, + and are released once the Java objects that use them become unreachable. `close()` is optional. The + collector can't see off-heap bytes, so `redline` requests a collection as its native footprint grows. + The [documentation](/docs/experimental/redline#native-memory) covers the threshold and how it + interacts with your GC flags. In the measurement that accompanies the change, 200 instances of a + Javy module that were never closed were all reclaimed, at the same peak memory as closing each one. +- **No compiler at runtime.** The trampolines between Java and native code are generated at build time + with the rest of the module. The runners only load and link precompiled code, and Cranelift is not + one of their dependencies. +- **One watchdog.** `Thread.interrupt()` reaches running native code through a single watchdog thread + shared by every instance. +- **`call_indirect` across instances.** A function placed in a table by one instance and called + through `call_indirect` by another now runs with its own memory, globals and tables. This is how + `wit-component` lays out every component with imports: a shim module calls the host through a table + that a separate fixup module fills. Host reads and writes of a native memory also got cheaper, as the + memory layouts are built once. +- **Correctness.** Memory growth seen across instances and host imports, host-side atomics, + `wait`/`notify`, and traps raised by the runner got a round of fixes in both runners, with new tests. + +[CPython compiled to Wasm](https://github.com/trinodb/trino-wasm-python) is one of the modules we +exercised it on. + +### Before you upgrade + +- The native code format is now version 5. Recompile modules built with an earlier version. +- `close()` stops an instance and frees nothing: the garbage collector reclaims the memory. + `-XX:+DisableExplicitGC` turns off the collections `redline` requests. +- `redline-runner-jffi-experimental` no longer brings in jffi, so its version can follow the rest of + your application. Add `com.github.jnr:jffi` and its `native` classifier next to the runner. +- Instances nested through host imports on one thread share one stack budget, and `withMemoryLimits` + rejects limits that would change whether a memory is shared. +- Like any `Instance`, a native instance is not thread-safe: use it from one thread at a time + ([#211](https://github.com/bytecodealliance/endive/issues/211)). +- Modules using exception handling: an `exnref` is now a `WasmException` object. `apply()` throws on + exnref signatures, use `applyWithRefs()`; `Instance.exn()` and `registerException()` are deprecated + and throw; and build-time compiled output from 1.1.0 must be regenerated. + +## Atomics and Heap + +- **JDK 25.** `ByteArrayMemory` asked the JVM on every atomic load and store whether it supports volatile + access on array views. On JDK 21 the answer is cheap; on JDK 25 it is `false` and expensive, enough to + make the multi-threaded sieve benchmark run two orders of magnitude slower than on JDK 21. The answer + is now resolved once. Wide atomics on `ByteArrayMemory` still take a lock on JDK 25, since its array + views no longer support them lock-free. +- **Uniform atomics.** In both memory implementations, atomics work on shared and non-shared memories + alike, and overlapping accesses of different widths exclude each other. When hardware atomics aren't + available, the fallback takes one of a fixed set of striped locks, with no allocation per operation. +- **Leaner compiled modules.** After compiling, the parsed bodies of compiled functions are only useful + to the interpreter; in a server holding many modules they were most of the retained heap. + `MachineFactoryCompiler.Builder.compileModule()` returns a `CompiledModule` that keeps only the + bodies the interpreter may still run, so the rest can be garbage collected. `compile()` is unchanged, + and nothing is dropped when the reachable set can't be determined or the result comes from the cache. + +```java +var compiled = MachineFactoryCompiler.builder(module).compileModule(); +var instance = Instance.builder(compiled).build(); +``` + +## Conformance + +Exception handling (`exnref`, `throw_ref`, `catch_ref`), tail calls, and the interpreter's `v128` locals +and store address computation all moved closer to the specification. The +[release notes](https://github.com/bytecodealliance/endive/releases/tag/1.2.0) list every change. + +## On the Horizon + +**Component Model.** Support is taking shape in [endive-cm](https://github.com/roastedroot/endive-cm), +a companion repository built on Endive: the component type model, a binary parser, Canonical ABI +lifting and lowering, a `bindgen` annotation processor that turns WIT into Java, component +instantiation and linking, and WASI 0.2 host implementations of `wasi:io`, `wasi:clocks`, `wasi:cli`, +`wasi:filesystem` and `wasi:random`, with `wasi:sockets` in progress. It is tested against the official +Component Model test suite and a corpus of components built with real toolchains. + +**Java 11.** We intend to drop Java 11. Supporting it costs more with every release: Jackson 3 and other +dependencies have moved on, and the build relies on forks and Maven profiles to keep up. We asked the +projects that depend on Endive, and Trino, JRuby, Apache Camel, Microcks and Confidence all run Java 17 +or later. If you are on Java 11, tell us on +[#250](https://github.com/bytecodealliance/endive/issues/250): concrete use cases will shape the +transition. + +## Thanks + +Much of this release arrived as pull requests from the community, often from people running Endive in +production, complete with reproducers, measurements and regression tests. Thank you to everyone who +shipped code, filed an issue, tested a snapshot, or fixed a line in the docs. The +[adopters list](https://github.com/bytecodealliance/endive/blob/main/ADOPTERS.md) is the place to add +your project. + +[Documentation](https://endive.run/docs/) | [GitHub](https://github.com/bytecodealliance/endive) | +[Join the conversation on Zulip](https://bytecodealliance.zulipchat.com/#narrow/stream/endive)