Skip to content

Core crypto-currency support: wallets, chains, native/GPU kernels, async batches - #6118

Open
shai-almog wants to merge 40 commits into
masterfrom
core-crypto-wallets
Open

shai-almog wants to merge 40 commits into
masterfrom
core-crypto-wallets

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Adds a built-in crypto-currency stack, shared between the client and the backend, with no third-party libraries.

API (com.codename1.crypto.*, plus additions to com.codename1.security)

  • Primitives: secp256k1 (ECDSA and recovery), BIP-340 Schnorr, Ed25519, Keccak-256, SHA-256/512, RIPEMD-160, HMAC and PBKDF2.
  • Keys: BIP-39 mnemonics, BIP-32 (including xpub derivation), SLIP-10 and derivation paths.
  • Chains:
    • EVM: addresses, legacy/EIP-2930/EIP-1559 transactions, EIP-191/712 signing, the Solidity ABI.
    • Bitcoin: addresses, transactions with sighash, Taproot and PSBT.
    • Solana: addresses, messages, transactions and instructions.
  • Wallets: Signer, SeedSigner, the vault-backed VaultSigner, and the Wallet facade.
  • Network: RPC clients for EVM, Esplora and Solana, and price feeds.
  • Bastion now uses the core classes instead of its own copies.

Performance

  • Native C kernels on ParparVM targets and Android JNI, with SIMD paths:
    • ARMv8.2 SHA3 instructions for Keccak;
    • SHA instructions for SHA-256;
    • AVX2 hash groups on x86.
  • CryptoBatch verifies and hashes many entries on every core, with packed zero-copy forms.
  • Large batches are split between the CPU and the GPU: Metal on Apple platforms, Vulkan elsewhere, WebGPU in the browser.
  • Every batch method has an ...Async form that takes a Callback, delivered on the EDT.
  • crypto-bench.yml holds each kernel to a ratio floor against libsecp256k1, OpenSSL/libsodium and BouncyCastle on the same runner.

Docs: a new developer-guide chapter, "Crypto wallets". It covers:

  • background on the algorithms;
  • each chain end to end;
  • batches and the asynchronous forms;
  • a Performance section with tables and five charts, drawn by scripts/crypto-bench/charts.py from the committed results.

Verification

  • The WebGPU kernels agree with the C kernels on 518 test vectors.
  • The Java record prep matches the C prep word for word.
  • In the browser, every GPU answer is checked against the CPU engine, including a pass where every GPU dispatch is forced to fail.
  • Local checks:
    • core-unittests: 8272 tests pass, SpotBugs 0;
    • ByteCodeTranslator SpotBugs 0;
    • PMD and Checkstyle clean;
    • javadoc builds for the client and backend references;
    • vm/tests JavaScript: 413 tests pass.

🤖 Generated with Claude Code

shai-almog and others added 30 commits October 26, 2026 15:11
secp256k1 moves from 16-bit limbs and Fermat inversion to 26-bit field
limbs with lazy reduction, safegcd inversion, a signed-digit comb for k*G
and a GLV/wNAF Strauss double multiplication for verify and recover:
pubkey 573 -> ~45k/s, sign 506 -> ~34k/s, verify 266 -> ~20k/s on
HotSpot, 1.2-2x BouncyCastle. Keccak-f is unrolled into locals (8x).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pto kernels

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nk them on use

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bsodium, OpenSSL, BouncyCastle

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…swords, probed against the Mac loop

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ation, SLIP-10 Ed25519, derivation paths

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…VM addresses, transactions, ABI, EIP-191, EIP-712, ERC-20

java.math is not in the device class library, so the encoding commit's Rlp
could never have linked on a device; UInt256 replaces it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…BIP-341 sighash, Taproot, PSBT, WIF

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sactions, System/Token/ComputeBudget/Memo; shared Base64

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… PSBT signs through BitcoinKey and reads BIP-32 origins

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ort with client and backend transports; randomness through CryptoEngine so the crypto stack builds in the backend; SpotBugs fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… caching decorator

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-1559/Wei/address classes

ChainVectorTest keeps the recorded signed bytes and derived addresses
byte-identical; EthRpc is a thin EvmRpc subclass over WebRpcTransport that
keeps the HTTPS-or-localhost rule. SpotBugs exclusion for the one-shot
NetworkTransport request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recovery phrase to wallet, addresses per chain, sending on EVM, Bitcoin
(PSBT) and Solana, price feeds, and where keys live (vault vs server).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…encodings, HD and chain formats

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… usage

The ParparVM kernel sources compile unchanged against a JNI shim; four ABIs,
API 21, 16 KB pages. AndroidImplementation loads them behind a guarded
System.loadLibrary and falls back to the Java engine. A source stamp and
scripts/check-android-crypto-kernels.sh catch stale binaries. Bench: dalvikvm
leg in scripts/crypto-bench/android-run.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d CryptoEngine

SHA instructions where the CPU has them (ARMv8 SHA-256, ARMv8.2 SHA-512,
x86 SHA-NI), picked once per process, unrolled portable C otherwise; Ed25519's
SHA-512 goes through the same path. Hash, Hmac and Pbkdf2 route the one-shot
SHA-256/512 and RIPEMD-160 forms through new engine hooks, so BIP-32 and BIP-39
run native. Android libraries rebuilt; bulk ParparVM run covers every padding
boundary (349 checks, 0 failing).

Apple silicon vs OpenSSL: sha256 1.09x, sha512 1.21x, hmac 2.62x, pbkdf2
1.18x, ripemd160 1.34x. Android emulator vs BouncyCastle: 1.8-6.6x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One native call per batch, cut into chunks run by libdispatch on Apple,
pthreads on Linux/Android and Win32 threads on Windows; small batches run
inline. Every entry gets the single-call answer (no Ed25519 batch equation),
and a malformed entry is invalid rather than an exception. The JNI wrapper
uses Get<Type>ArrayElements so a long batch never holds a critical region.

16-core Apple silicon vs the reference on one core: ECDSA 8.0x libsecp256k1,
Ed25519 17.6x OpenSSL, SHA-256 Merkle nodes 5.5x OpenSSL. Android emulator
vs BouncyCastle: ECDSA 18.3x, Ed25519 4.7x. Bulk ParparVM run: 351 checks,
0 failing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ve kernels

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Debian 12's clang 14 declares the SHA intrinsics only for a translation unit
built for the extension, and GCC 12 refuses to inline them under the target
names clang uses. Old clang gets the instructions as inline assembly, GCC
asks for the targets its own header declares them under. selftest.c checks
the hash kernels with only a C compiler, which is how this was found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ructions

CryptoBatch gains fixed-stride forms of every batch (hashes 32*n, signatures
64*n, keys keyLength*n, one result byte each). On ParparVM the kernels read
those arrays where they are: no flattening, no per-entry objects, nothing
copied in or out. Simd.allocByte aligns them for the vector units.

Keccak-f runs on EOR3/RAX1/XAR/BCAX, two states per permutation, one per
lane: a single hash is 1.04x the portable code and a batch hashes two inputs
per permutation, 2.1x on one core. SHA-256 batches run two streams through
the SHA unit together. The core count is asked once, not per batch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…N-wide batch grouping

Hash batches now run in groups of the widest lane count the CPU has: two on
ARMv8 (SHA3 / two-stream SHA-256), four Keccak and eight SHA-256 lanes in AVX2
on x86 (SHA-256 only without SHA-NI). AVX2 is used only when cpuid reports it
and XGETBV says the OS saves YMM state.

Also restores the escaped newlines in the old-clang SHA3 asm shims, which had
become literal newlines and failed to compile on clang 14.

selftest.c cross-checks every lane of each group against the single hash;
passes on Apple clang, clang 14, GCC 12 (arm64) and x86-64 under Rosetta with
and without ROSETTA_ADVERTISE_AVX.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Large verify and hash batches are split between the GPU and every CPU core in
the ratio of their measured throughput, and both halves run at once. Metal on
iOS and macOS; Vulkan, loaded at run time, on Android, Linux and Windows. The
GPU only does the scalar multiplications of public data; parsing,
decompression and challenge hashes are prepared on the CPU, so every result
is exactly what a single verify answers.

The curve kernels use complete projective formulas with one addition and one
doubling site per scalar multiplication: drivers inline every call, and the
earlier layout took 214 s to compile on lavapipe. All five pipelines now
build in seconds.

scripts/crypto-gpu holds the shader generator, a check of the hand-declared
Vulkan subset against vulkan_core.h, and batch-check, which holds GPU batches
to CPU batches and reports throughput and crossover per kernel; the
crypto-bench workflow runs them on lavapipe. libcn1crypto.so is rebuilt with
the Vulkan host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rand_s was implicitly declared, which clang 16+ rejects; found by a mingw
cross build of the Vulkan host. libcn1crypto.so rebuilt for the new digest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hmarks in the guide

Every CryptoBatch method gains an Async form taking a Callback: arguments are
checked before it returns, the batch runs through CryptoEngine.runInBackground
and the answer arrives through deliver (the EDT on a port). The JavaScript
port's HTML5CryptoEngine sends large batches to WebGPU kernels generated from
the same source as the Metal and Vulkan ones (WGSL through naga), with the
Java prep held to the C prep word for word and the kernels to the C answers.
The kernel asset ships only with applications that run a batch.

The developer guide gains a Performance section: tables for the JVM, native,
Android, the GPU split and the browser, and two charts drawn by
scripts/crypto-bench/charts.py from the committed results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
shai-almog and others added 5 commits October 27, 2026 11:30
…copes and device recovery, background and charts in the guide

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d open, every-dispatch-fails fallback pass, measured figures saved

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…first browser run described as sampled

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

Comment thread CodenameOne/src/com/codename1/security/Ed25519Math.java Fixed
Comment thread CodenameOne/src/com/codename1/security/Ed25519Math.java Fixed
@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 191 screenshots: 191 matched.

Native Android coverage

  • 📊 Line coverage: 18.90% (48251/255341 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 17.64% (229184/1299035), branch 12.04% (16820/139675), complexity 9.68% (12913/133466), method 14.57% (9122/62628), class 25.16% (1774/7052)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • com.codename1.androidcompat.rt.com.codename1.androidcompat.rt.TextXmlPullParser – 0.00% (0/623 lines covered)
      • com.codename1.androidcompat.androidx.constraintlayout.core.widgets.com.codename1.androidcompat.androidx.constraintlayout.core.widgets.Flow – 0.00% (0/576 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 18.90% (48251/255341 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 17.64% (229184/1299035), branch 12.04% (16820/139675), complexity 9.68% (12913/133466), method 14.57% (9122/62628), class 25.16% (1774/7052)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • com.codename1.androidcompat.rt.com.codename1.androidcompat.rt.TextXmlPullParser – 0.00% (0/623 lines covered)
      • com.codename1.androidcompat.androidx.constraintlayout.core.widgets.com.codename1.androidcompat.androidx.constraintlayout.core.widgets.Flow – 0.00% (0/576 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 189ms / native 165ms = 1.1x speedup
SIMD float-mul (64K x300) java 185ms / native 137ms = 1.3x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 76.000 ms
Base64 CN1 decode 84.000 ms
Base64 native encode 389.000 ms
Base64 encode ratio (CN1/native) 0.195x (80.5% faster)
Base64 native decode 272.000 ms
Base64 decode ratio (CN1/native) 0.309x (69.1% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 227 screenshots: 227 matched.
✅ JavaScript-port screenshot tests passed.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ✅ ByteCodeTranslator: 0 findings (no issues)
    • ✅ android: 0 findings (no issues)
    • ✅ android-compat: 0 findings (no issues)
    • ✅ android-res-compiler: 0 findings (no issues)
    • ✅ backend: 0 findings (no issues)
    • ✅ backend-test: 0 findings (no issues)
    • ✅ build-engine: 0 findings (no issues)
    • ✅ build-hint-catalog: 0 findings (no issues)
    • ✅ build-hint-tools: 0 findings (no issues)
    • ✅ codenameone-gradle-plugin: 0 findings (no issues)
    • ✅ codenameone-maven-plugin: 0 findings (no issues)
    • ✅ core-unittests: 0 findings (no issues)
    • ✅ desktop-compat-runtime: 0 findings (no issues)
    • ✅ fxml-compiler: 0 findings (no issues)
    • ✅ ios: 0 findings (no issues)
    • ✅ javac: 0 findings (no issues)
    • ✅ javafx-compat: 0 findings (no issues)
    • ✅ project-model: 0 findings (no issues)
    • ✅ swing-compat: 0 findings (no issues)
  • ❌ PMD: 1 findings (P3: 1) [HTML preview] [Download]
  • ✅ Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 77ms / native 5ms = 15.4x speedup
SIMD float-mul (64K x300) java 62ms / native 6ms = 10.3x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 74.000 ms
Base64 CN1 decode 90.000 ms
Base64 SIMD encode 105.000 ms
Base64 encode ratio (SIMD/CN1) 1.419x (41.9% slower)
Base64 SIMD decode 100.000 ms
Base64 decode ratio (SIMD/CN1) 1.111x (11.1% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 9.000 ms
Image createMask (SIMD on) 4.000 ms
Image createMask ratio (SIMD on/off) 0.444x (55.6% faster)
Image applyMask (SIMD off) 28.000 ms
Image applyMask (SIMD on) 32.000 ms
Image applyMask ratio (SIMD on/off) 1.143x (14.3% slower)
Image modifyAlpha (SIMD off) 34.000 ms
Image modifyAlpha (SIMD on) 20.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.588x (41.2% faster)
Image modifyAlpha removeColor (SIMD off) 31.000 ms
Image modifyAlpha removeColor (SIMD on) 18.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.581x (41.9% faster)

@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Windows port (x64 / Intel-AMD): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, SSE2 SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 64ms / native 4ms = 16.0x speedup
SIMD float-mul (64K x300) java 57ms / native 4ms = 14.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 84.000 ms
Base64 CN1 decode 93.000 ms
Base64 SIMD encode 108.000 ms
Base64 encode ratio (SIMD/CN1) 1.286x (28.6% slower)
Base64 SIMD decode 106.000 ms
Base64 decode ratio (SIMD/CN1) 1.140x (14.0% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 12.000 ms
Image createMask (SIMD on) 5.000 ms
Image createMask ratio (SIMD on/off) 0.417x (58.3% faster)
Image applyMask (SIMD off) 45.000 ms
Image applyMask (SIMD on) 44.000 ms
Image applyMask ratio (SIMD on/off) 0.978x (2.2% faster)
Image modifyAlpha (SIMD off) 40.000 ms
Image modifyAlpha (SIMD on) 28.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.700x (30.0% faster)
Image modifyAlpha removeColor (SIMD off) 38.000 ms
Image modifyAlpha removeColor (SIMD on) 24.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.632x (36.8% faster)

ParparVM vs HotSpot (JDK 25): Windows x64

Runner CPU: AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD (baseline windows-x64@amd64-family-25-model-1-authenticamd)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (WinHelloMain) 4 1.41x (base 1.22x, +15.5%) 0.57x (base 0.94x, -38.7%) ok
translator (self) 4 0.83x (base 0.83x, +0.2%) 0.52x (base 0.54x, -3.8%) ok
intArithmetic 4 1.10x (base 1.10x, -0.0%) 0.06x (base 0.06x, +8.1%) ok
longArithmetic 4 1.14x (base 1.08x, +5.0%) 0.06x (base 0.05x, +3.1%) ok
mathTranscendental 4 0.79x (base 0.79x, -0.4%) 0.06x (base 0.06x, +2.7%) ok
arraySequential 4 1.33x (base 1.36x, -2.5%) 0.39x (base 0.39x, +0.2%) ok
arrayRandom 4 1.05x (base 1.06x, -0.6%) 0.23x (base 0.23x, +0.5%) ok
objectAllocation 4 1.53x (base 1.56x, -2.1%) 0.28x (base 0.39x, -28.4%) ok
valueEscape 4 0.10x (base 0.10x, +0.1%) 0.05x (base 0.04x, +4.0%) ok
hashMapChurn 4 1.84x (base 1.80x, +2.2%) 0.09x (base 0.09x, -3.7%) ok
stringBuilding 4 1.34x (base 1.22x, +10.4%) 0.27x (base 0.32x, -16.7%) ok
recursion 4 1.41x (base 1.49x, -5.9%) 0.06x (base 0.06x, +1.5%) ok
quicksort 4 1.10x (base 1.13x, -2.5%) 0.12x (base 0.12x, +0.4%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Linux port (x64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub x64 runner. Baseline: scripts/linux/screenshots.

ParparVM vs HotSpot (JDK 25): Linux x64

Runner CPU: AMD EPYC 9V45 96-Core Processor (baseline linux-x64@amd-epyc-9v45-96-core-processor)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (LinuxHelloMain) 4 0.95x (base 0.92x, +3.1%) 0.72x (base 0.84x, -14.1%) ok
translator (self) 4 0.63x (base 0.64x, -1.1%) 0.57x (base 0.55x, +4.8%) ok
intArithmetic 4 1.00x (base 1.00x, +0.1%) 0.06x (base 0.06x, +1.5%) ok
longArithmetic 4 0.99x (base 0.99x, -0.1%) 0.07x (base 0.07x, +2.7%) ok
mathTranscendental 4 1.20x (base 1.20x, +0.2%) 0.08x (base 0.06x, +35.0%) ok
arraySequential 4 3.17x (base 2.91x, +9.0%) 0.36x (base 0.36x, +0.0%) ok
arrayRandom 4 0.98x (base 1.04x, -6.0%) 0.21x (base 0.23x, -7.9%) ok
objectAllocation 4 1.58x (base 1.61x, -1.9%) 0.24x (base 0.24x, +1.7%) ok
valueEscape 4 0.10x (base 0.12x, -15.7%) 0.06x (base 0.04x, +36.1%) ok
hashMapChurn 4 1.30x (base 1.31x, -0.8%) 0.09x (base 0.09x, +4.2%) ok
stringBuilding 4 1.57x (base 1.58x, -0.5%) 0.26x (base 0.22x, +20.1%) ok
recursion 4 1.35x (base 1.34x, +0.9%) 0.06x (base 0.08x, -25.1%) ok
quicksort 4 1.06x (base 1.06x, +0.2%) 0.11x (base 0.11x, +0.8%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Linux port (arm64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub arm64 runner. Baseline: scripts/linux/screenshots-arm.

ParparVM vs HotSpot (JDK 25): Linux arm64

Runner CPU: Neoverse-N2 (baseline linux-arm64@neoverse-n2)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (LinuxHelloMain) 4 0.93x (base 1.02x, -9.0%) 0.65x (base 0.93x, -30.2%) ok
translator (self) 4 0.73x (base 0.70x, +4.8%) 0.47x (base 0.43x, +10.3%) ok
intArithmetic 4 1.04x (base 1.04x, -0.0%) 0.03x (base 0.03x, +3.3%) ok
longArithmetic 4 0.79x (base 0.79x, -0.1%) 0.03x (base 0.03x, +5.0%) ok
mathTranscendental 4 1.09x (base 1.10x, -0.3%) 0.04x (base 0.03x, +9.7%) ok
arraySequential 4 0.34x (base 0.36x, -5.6%) 0.37x (base 0.37x, +0.2%) ok
arrayRandom 4 0.93x (base 0.94x, -0.3%) 0.20x (base 0.20x, +0.7%) ok
objectAllocation 4 1.80x (base 1.77x, +1.7%) 0.37x (base 0.37x, -0.2%) ok
valueEscape 4 0.51x (base 0.51x, -0.1%) 0.03x (base 0.03x, +5.0%) ok
hashMapChurn 4 0.85x (base 0.84x, +0.6%) 0.12x (base 0.12x, +1.9%) ok
stringBuilding 4 1.40x (base 1.57x, -10.7%) 0.32x (base 0.26x, +20.6%) ok
recursion 4 1.42x (base 1.43x, -1.3%) 0.04x (base 0.04x, +3.0%) ok
quicksort 4 1.00x (base 0.99x, +0.9%) 0.09x (base 0.09x, +1.3%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Windows port (arm64 / Apple Silicon - Arm): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, NEON SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD float-mul (64K x300) java 53ms / native 3ms = 17.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 59.000 ms
Base64 CN1 decode 70.000 ms
Base64 SIMD encode 78.000 ms
Base64 encode ratio (SIMD/CN1) 1.322x (32.2% slower)
Base64 SIMD decode 73.000 ms
Base64 decode ratio (SIMD/CN1) 1.043x (4.3% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 6.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.167x (83.3% faster)
Image applyMask (SIMD off) 18.000 ms
Image applyMask (SIMD on) 20.000 ms
Image applyMask ratio (SIMD on/off) 1.111x (11.1% slower)
Image modifyAlpha (SIMD off) 18.000 ms
Image modifyAlpha (SIMD on) 11.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.611x (38.9% faster)
Image modifyAlpha removeColor (SIMD off) 16.000 ms
Image modifyAlpha removeColor (SIMD on) 11.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.688x (31.3% faster)

ParparVM vs HotSpot (JDK 25): Windows arm64

Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline windows-arm64@armv8-64-bit-family-8-model-d49-microsoft-corporation)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (WinHelloMain) 4 0.98x (base 1.11x, -11.3%) 0.62x (base 0.75x, -16.9%) ok
translator (self) 4 0.90x (base 0.84x, +6.8%) 0.49x (base 0.51x, -2.6%) ok
intArithmetic 4 1.04x (base 1.04x, -0.0%) 0.06x (base 0.06x, +3.0%) ok
longArithmetic 4 0.80x (base 0.80x, +0.1%) 0.06x (base 0.06x, +3.5%) ok
mathTranscendental 4 0.72x (base 0.72x, -0.0%) 0.07x (base 0.06x, +1.6%) ok
arraySequential 4 0.36x (base 0.46x, -21.2%) 0.39x (base 0.39x, -0.0%) ok
arrayRandom 4 0.94x (base 0.94x, +0.1%) 0.23x (base 0.23x, +0.2%) ok
objectAllocation 4 1.80x (base 1.82x, -1.0%) 0.41x (base 0.43x, -5.8%) ok
valueEscape 4 0.76x (base 0.76x, +0.0%) 0.05x (base 0.05x, +3.6%) ok
hashMapChurn 4 1.00x (base 0.98x, +1.7%) 0.12x (base 0.12x, -3.2%) ok
stringBuilding 4 1.61x (base 1.43x, +12.6%) 0.27x (base 0.27x, -0.5%) ok
recursion 4 1.55x (base 1.46x, +5.8%) 0.07x (base 0.07x, +1.4%) ok
quicksort 4 1.01x (base 1.00x, +0.4%) 0.12x (base 0.12x, +0.5%) ok

Result: no regression

…uct on x86, CI fixes

- Ed25519.verify checks [u]B - [v1]R - [v0]A = O with v0 = v1 k (mod 8L), v1 odd,
  both near 2^127 (binary Euclid on the lattice); exact for every input, torsion
  included, with (k, 1) as the fallback row. Half the doublings.
- Field product: Karatsuba over the two limb halves (75 products instead of 100)
  on x86 JVMs, where ref10's form is multiplier-bound; ref10 stays on arm64.
- Guide and javadoc snippets self-contained for the Playground; the bash block
  moved to docs/demos. The Playground auto-imports the outer class of Outer.Inner.
- Android kernel stamp, bastion template zip, Vulkan ABI check kernel ids, a
  narrowing compound assignment CodeQL flagged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • ✅ Tests: 883 total, 0 failed, 55 skipped

Benchmark Results

  • Execution Time: 9347 ms

  • Hotspots (Top 20 sampled methods):

    • 11.87% com.codename1.tools.translator.IteratorEscape.mangle (176 samples)
    • 7.69% java.util.ArrayList.indexOf (114 samples)
    • 4.99% java.lang.System.identityHashCode (74 samples)
    • 4.18% com.codename1.tools.translator.BytecodeMethod.equals (62 samples)
    • 3.98% java.lang.Object.hashCode (59 samples)
    • 3.30% com.codename1.tools.translator.classfile.analysis.Frame.execute (49 samples)
    • 2.90% java.lang.StringBuilder.append (43 samples)
    • 2.02% com.codename1.tools.translator.IteratorEscape.ctorOnlyStoresParamsIntoThis (30 samples)
    • 2.02% com.codename1.tools.translator.bytecodes.Invoke.findMethodUp (30 samples)
    • 1.75% com.codename1.tools.translator.JavascriptReachability.enqueueResolved (26 samples)
    • 1.62% com.codename1.tools.translator.Parser.cullMethods (24 samples)
    • 1.55% java.util.HashMap.hash (23 samples)
    • 1.42% java.lang.String.equals (21 samples)
    • 1.15% com.codename1.tools.translator.ReachabilityCull.run (17 samples)
    • 1.15% com.codename1.tools.translator.BytecodeMethod.updateInlinableFieldDependencies (17 samples)
    • 1.15% com.codename1.tools.translator.ByteCodeClass.hasDeclaredMethod (17 samples)
    • 1.08% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (16 samples)
    • 1.08% java.util.AbstractCollection.containsAll (16 samples)
    • 0.94% java.lang.StringCoding.encode (14 samples)
    • 0.88% java.lang.StringBuilder.toString (13 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Flutter vs Codename One

No benchmark results were produced.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: 1 alert(s) (0 errors, 1 warnings, 0 suggestions) (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: 20 advisory match(es) — top: MORFOLOGIK_RULE_EN_US (15), EN_COMPOUNDS_CRYPTO_CURRENCY (1), EN_A_VS_AN (1) (report)
  • Image references: No unused images detected (report)

shai-almog and others added 4 commits October 27, 2026 15:45
… chart alt texts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… guide names the core classes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…point

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants