Skip to content

Backend: streaming request and response bodies, spooled uploads, HttpProxy - #6095

Merged
shai-almog merged 2 commits into
masterfrom
backend-streaming
Oct 25, 2026
Merged

shai-almog merged 2 commits into
masterfrom
backend-streaming

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Fixes #5994.

What it adds

  • Streaming request bodies. A binary, identity-encoded body past CN1_HTTP_SPOOL_THRESHOLD_KB (1024) is written to an unlinked temporary file as it arrives, on HTTP/1.1 and HTTP/2 alike. Request.getBodyStream() and getBodyLength() read it, and multipart parts are slices of the spool (Part.getInputStream(), getLength()).
    • CN1_HTTP_MAX_SPOOLED_BODY_MB raises the limit for such bodies.
    • CN1_HTTP_SPOOL_DIR picks the directory.
    • Text and compressed bodies keep the 8 MB in-memory limit on both protocols.
  • Outbound streaming. Web.open / WebClient.open return a Web.Exchange: the request body is written as it is produced, the response is read as it arrives, and each direction has a fixed window. close() before the end cancels the exchange. The packaged binary uses curl multi with pause/resume; the JVM twin uses HttpURLConnection.
  • HttpServer.Response.stream is chunked on HTTP/1.1 and DATA frames on HTTP/2. A BodyWriter that also implements Closeable is closed when the server never runs it: a HEAD, a bodiless status, an HTTP/2 stream it could not open, or a head write that failed.
  • HttpProxy:
    • Streams both directions.
    • Drops RFC 9110 hop-by-hop headers and the headers a Connection field names, in both directions.
    • Adds X-Forwarded-*.
    • Allows only the target's host plus those named with allowHost, over http and https.
    • Passes redirects through by default. setFollowRedirects(n) follows them only for a request without a body, and drops Authorization and Cookie on a hop to another host.
    • Answers 502 when the upstream fails before replying. When it fails mid-response, the client's response is aborted (never one that looks complete).
    • Forwards a gzip upload decoded, without its Content-Encoding.
    • A HEAD keeps the upstream's Content-Length.

Found along the way and fixed here

  • HTTP/2 served a truncated upload. When a DATA chunk crossed the body limit, nghttp2 reset the stream, but the client's frames already in flight were still delivered, and the last one's END_STREAM completed the request. The handler then answered 200 for the first 8 MB of a 9 MB upload. This is on master too, at its 8 MB ceiling. Such a stream is now marked refused and answered 413 (then RST_STREAM(NO_ERROR) once the 413 is on the wire, because nghttp2 sends a queued reset ahead of queued HEADERS). That matches HTTP/1.1.
  • HTTP/2 now applies the in-memory limit to text and compressed bodies as they arrive. Before, it spooled them to disk up to the much larger spooled limit and refused them only afterwards.

Verification

  • HttpStreamingTest (12 tests) and HttpBodiesTest (30 tests) pass on the JVM runtime.
  • New BackendHttpIntegrationTest#http2BodyPastTheLimitIsAnswered413 runs against the translated native server, together with the existing h2 body tests.
  • vm/backend/demo/streamcheck ran on the JVM and as a native binary: upload, download, cancellation, proxied body, headers, destinations and redirects (7/7 on both).
  • curl against the native server, --http1.1 vs --http2-prior-knowledge, at the default limit and with CN1_HTTP_MAX_SPOOLED_BODY_MB=20, gave the same results on both protocols:
    • a 3 MB binary upload gives the same checksum
    • a 9.5 MB binary is 413 at the default limit and accepted at 20 MB
    • 9.5 MB of JSON is 413 at both
    • 3 MB of JSON is 200
  • Backend SpotBugs 0, PMD (backend and backend-parparvm) clean, Checkstyle clean, JDK 25 doclint of the backend reference clean, and check-native-signatures.sh (369 backend natives resolve).
  • Guide snippets are compiled includes (docs/demos/backend/.../Streaming.java), and validate-guide-snippets.py passes.

🤖 Generated with Claude Code

Large binary uploads spool to an unlinked file on HTTP/1.1 and HTTP/2 alike;
Web.open streams outbound requests both ways; HttpProxy forwards with
hop-by-hop stripping, a destination allow-list and cancellation both ways.

HTTP/2 used to serve an upload truncated at the body limit: frames in flight
after the refusing chunk still completed the request. Such a stream is now
answered 413, as HTTP/1.1 answers it.

Fixes #5994

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

github-actions Bot commented Oct 24, 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: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

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

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)
    • ✅ ios: 0 findings (no issues)
    • ✅ javac: 0 findings (no issues)
    • ✅ project-model: 0 findings (no issues)
  • ✅ PMD: 0 findings (no issues) [Report archive]
  • ✅ Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 178 screenshots: 178 matched.

Native Android coverage

  • 📊 Line coverage: 17.40% (30698/176425 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 15.70% (145022/923606), branch 10.67% (10020/93920), complexity 8.23% (7457/90646), method 12.02% (5162/42960), class 20.73% (1061/5117)
    • 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: 17.40% (30698/176425 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 15.70% (145022/923606), branch 10.67% (10020/93920), complexity 8.23% (7457/90646), method 12.02% (5162/42960), class 20.73% (1061/5117)
    • 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 169ms / native 112ms = 1.5x speedup
SIMD float-mul (64K x300) java 162ms / native 132ms = 1.2x 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 90.000 ms
Base64 CN1 decode 84.000 ms
Base64 native encode 420.000 ms
Base64 encode ratio (CN1/native) 0.214x (78.6% faster)
Base64 native decode 267.000 ms
Base64 decode ratio (CN1/native) 0.315x (68.5% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 193 screenshots: 193 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 57ms / native 5ms = 11.4x speedup
SIMD float-mul (64K x300) java 56ms / native 4ms = 14.0x 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 76.000 ms
Base64 CN1 decode 91.000 ms
Base64 SIMD encode 113.000 ms
Base64 encode ratio (SIMD/CN1) 1.487x (48.7% slower)
Base64 SIMD decode 105.000 ms
Base64 decode ratio (SIMD/CN1) 1.154x (15.4% 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) 26.000 ms
Image applyMask (SIMD on) 28.000 ms
Image applyMask ratio (SIMD on/off) 1.077x (7.7% slower)
Image modifyAlpha (SIMD off) 27.000 ms
Image modifyAlpha (SIMD on) 18.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.667x (33.3% faster)
Image modifyAlpha removeColor (SIMD off) 30.000 ms
Image modifyAlpha removeColor (SIMD on) 63.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 2.100x (110.0% slower)

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 193 screenshots: 193 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 53ms / native 4ms = 13.2x speedup
SIMD float-mul (64K x300) java 52ms / native 3ms = 17.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 70.000 ms
Base64 CN1 decode 83.000 ms
Base64 SIMD encode 95.000 ms
Base64 encode ratio (SIMD/CN1) 1.357x (35.7% slower)
Base64 SIMD decode 89.000 ms
Base64 decode ratio (SIMD/CN1) 1.072x (7.2% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 9.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.222x (77.8% faster)
Image applyMask (SIMD off) 39.000 ms
Image applyMask (SIMD on) 46.000 ms
Image applyMask ratio (SIMD on/off) 1.179x (17.9% slower)
Image modifyAlpha (SIMD off) 38.000 ms
Image modifyAlpha (SIMD on) 30.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.789x (21.1% faster)
Image modifyAlpha removeColor (SIMD off) 39.000 ms
Image modifyAlpha removeColor (SIMD on) 22.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.564x (43.6% faster)

ParparVM vs HotSpot (JDK 25): Windows x64

Runner CPU: Intel64 Family 6 Model 207 Stepping 2, GenuineIntel (baseline windows-x64@intel64-family-6-model-207-genuineintel)

1 improvement past the baseline (not a failure; rebaseline to lock it in):

  • recursion on all 4 CPUs: time 0.94x against a 1.20x baseline (-21.7%, tolerance 20%)

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.29x (base 1.07x, +20.7%) 0.69x (base 0.86x, -19.8%) ok
translator (self) 4 0.82x (base 0.79x, +4.7%) 0.50x (base 0.53x, -4.3%) ok
intArithmetic 4 1.03x (base 1.02x, +0.2%) 0.06x (base 0.06x, +2.1%) ok
longArithmetic 4 0.98x (base 0.97x, +0.8%) 0.06x (base 0.05x, +3.2%) ok
mathTranscendental 4 0.89x (base 0.89x, +0.6%) 0.06x (base 0.06x, +2.6%) ok
arraySequential 4 1.59x (base 1.98x, -19.9%) 0.38x (base 0.38x, +0.4%) ok
arrayRandom 4 1.01x (base 1.01x, +0.3%) 0.23x (base 0.23x, +0.9%) ok
objectAllocation 4 1.22x (base 1.22x, +0.2%) 0.32x (base 0.37x, -14.3%) ok
valueEscape 4 0.13x (base 0.13x, -0.4%) 0.05x (base 0.04x, +4.2%) ok
hashMapChurn 4 1.21x (base 1.14x, +5.8%) 0.10x (base 0.10x, +5.0%) ok
stringBuilding 4 1.47x (base 1.42x, +3.9%) 0.22x (base 0.22x, +0.1%) ok
recursion 4 0.94x (base 1.20x, -21.7%) 0.06x (base 0.06x, +3.2%) improved: rebaseline to lock in (time -21.7%)
quicksort 4 1.03x (base 1.07x, -3.4%) 0.12x (base 0.12x, +1.7%) ok

A change that moves performance ON PURPOSE records the new baseline in vm/selfhost/perf-baseline/pr/6095.json, with the reason, from this job's perf-results.json. The rebaseline is then part of this pull request's diff:

python3 vm/selfhost/calibrate-perf-baseline.py --pr 6095 --reason "<why these benchmarks moved>" perf-results.json

Result: no regression (improved past the baseline: consider rebaselining)

@github-actions

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

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

Benchmark Results

  • Execution Time: 9839 ms

  • Hotspots (Top 20 sampled methods):

    • 11.84% com.codename1.tools.translator.IteratorEscape.ctorOnlyStoresParamsIntoThis (183 samples)
    • 7.96% java.util.ArrayList.indexOf (123 samples)
    • 6.02% java.lang.System.identityHashCode (93 samples)
    • 4.98% com.codename1.tools.translator.BytecodeMethod.equals (77 samples)
    • 4.40% com.codename1.tools.translator.classfile.analysis.Frame.execute (68 samples)
    • 3.17% java.lang.StringBuilder.append (49 samples)
    • 2.98% java.lang.Object.hashCode (46 samples)
    • 2.33% com.codename1.tools.translator.JavascriptReachability.enqueueResolved (36 samples)
    • 2.26% com.codename1.tools.translator.IteratorEscape.mangle (35 samples)
    • 1.75% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (27 samples)
    • 1.49% com.codename1.tools.translator.classfile.tree.JsrInliner.replay (23 samples)
    • 1.29% java.lang.String.equals (20 samples)
    • 1.16% com.codename1.tools.translator.ReachabilityCull.run (18 samples)
    • 1.16% com.codename1.tools.translator.Parser.cullMethods (18 samples)
    • 1.10% com.codename1.tools.translator.BytecodeMethod.updateInlinableFieldDependencies (17 samples)
    • 1.10% java.util.HashMap.hash (17 samples)
    • 1.03% java.util.HashMap.putVal (16 samples)
    • 0.97% com.codename1.tools.translator.ByteCodeClass.updateAllDependencies (15 samples)
    • 0.97% com.codename1.tools.translator.IteratorEscape.walk (15 samples)
    • 0.91% com.codename1.tools.translator.ByteCodeClass.generateCCode (14 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.

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 193 screenshots: 193 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 50ms / native 3ms = 16.6x speedup
SIMD float-mul (64K x300) java 49ms / native 3ms = 16.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 61.000 ms
Base64 CN1 decode 71.000 ms
Base64 SIMD encode 77.000 ms
Base64 encode ratio (SIMD/CN1) 1.262x (26.2% slower)
Base64 SIMD decode 73.000 ms
Base64 decode ratio (SIMD/CN1) 1.028x (2.8% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 5.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.200x (80.0% faster)
Image applyMask (SIMD off) 22.000 ms
Image applyMask (SIMD on) 22.000 ms
Image applyMask ratio (SIMD on/off) 1.000x (0.0% slower)
Image modifyAlpha (SIMD off) 18.000 ms
Image modifyAlpha (SIMD on) 13.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.722x (27.8% faster)
Image modifyAlpha removeColor (SIMD off) 20.000 ms
Image modifyAlpha removeColor (SIMD on) 11.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.550x (45.0% 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 1.00x (base 1.11x, -9.3%) 0.79x (base 0.75x, +5.5%) ok
translator (self) 4 0.87x (base 0.84x, +3.3%) 0.47x (base 0.51x, -6.5%) ok
intArithmetic 4 1.04x (base 1.04x, +0.0%) 0.06x (base 0.06x, +3.2%) ok
longArithmetic 4 0.79x (base 0.80x, -0.0%) 0.06x (base 0.06x, +3.5%) ok
mathTranscendental 4 0.72x (base 0.72x, -0.4%) 0.07x (base 0.06x, +1.7%) ok
arraySequential 4 0.42x (base 0.46x, -8.7%) 0.39x (base 0.39x, +0.1%) ok
arrayRandom 4 0.94x (base 0.94x, +0.1%) 0.23x (base 0.23x, +1.2%) ok
objectAllocation 4 1.77x (base 1.82x, -3.0%) 0.42x (base 0.43x, -3.2%) ok
valueEscape 4 0.76x (base 0.76x, +0.1%) 0.05x (base 0.05x, +3.0%) ok
hashMapChurn 4 0.98x (base 0.98x, -0.5%) 0.12x (base 0.12x, +0.2%) ok
stringBuilding 4 1.60x (base 1.43x, +11.8%) 0.27x (base 0.27x, -0.3%) ok
recursion 4 1.54x (base 1.46x, +5.4%) 0.07x (base 0.07x, +1.2%) ok
quicksort 4 1.00x (base 1.00x, +0.2%) 0.12x (base 0.12x, +0.6%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 193 screenshots: 193 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 7763 64-Core Processor (baseline linux-x64@amd-epyc-7763-64-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.85x (base 0.85x, +0.4%) 0.92x (base 0.83x, +9.7%) ok
translator (self) 4 0.52x (base 0.64x, -19.1%) 0.48x (base 0.52x, -8.0%) ok
intArithmetic 4 1.13x (base 1.12x, +1.5%) 0.06x (base 0.06x, +1.5%) ok
longArithmetic 4 1.08x (base 1.08x, +0.0%) 0.07x (base 0.05x, +38.7%) ok
mathTranscendental 4 1.09x (base 1.08x, +0.5%) 0.06x (base 0.07x, -21.2%) ok
arraySequential 4 2.46x (base 2.00x, +22.6%) 0.36x (base 0.36x, +0.0%) ok
arrayRandom 4 1.13x (base 0.91x, +23.8%) 0.23x (base 0.21x, +9.3%) ok
objectAllocation 4 1.66x (base 1.65x, +0.8%) 0.30x (base 0.35x, -16.3%) ok
valueEscape 4 0.10x (base 0.10x, -0.3%) 0.05x (base 0.04x, +5.3%) ok
hashMapChurn 4 1.48x (base 1.48x, +0.0%) 0.10x (base 0.09x, +3.9%) ok
stringBuilding 4 1.35x (base 1.39x, -2.6%) 0.26x (base 0.31x, -16.9%) ok
recursion 4 1.26x (base 1.25x, +0.0%) 0.08x (base 0.08x, +1.2%) ok
quicksort 4 1.08x (base 1.07x, +0.2%) 0.12x (base 0.11x, +3.0%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 193 screenshots: 193 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, -8.8%) 0.78x (base 0.93x, -16.3%) ok
translator (self) 4 0.75x (base 0.70x, +7.0%) 0.45x (base 0.43x, +4.1%) ok
intArithmetic 4 1.04x (base 1.04x, -0.1%) 0.03x (base 0.03x, +4.4%) ok
longArithmetic 4 0.79x (base 0.79x, -0.0%) 0.03x (base 0.03x, +4.8%) ok
mathTranscendental 4 1.10x (base 1.10x, +0.2%) 0.04x (base 0.03x, +8.9%) ok
arraySequential 4 0.37x (base 0.36x, +2.7%) 0.37x (base 0.37x, +0.3%) ok
arrayRandom 4 0.93x (base 0.94x, -0.6%) 0.20x (base 0.20x, +0.6%) ok
objectAllocation 4 1.88x (base 1.77x, +6.2%) 0.38x (base 0.37x, +2.8%) ok
valueEscape 4 0.51x (base 0.51x, -0.1%) 0.03x (base 0.03x, +4.6%) ok
hashMapChurn 4 0.84x (base 0.84x, -0.6%) 0.12x (base 0.12x, -0.1%) ok
stringBuilding 4 1.41x (base 1.57x, -9.9%) 0.26x (base 0.26x, -0.1%) ok
recursion 4 1.56x (base 1.43x, +8.8%) 0.04x (base 0.04x, +3.0%) ok
quicksort 4 1.01x (base 0.99x, +1.3%) 0.09x (base 0.09x, +1.2%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 179 screenshots: 179 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 324 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 69ms / native 7ms = 9.8x speedup
SIMD float-mul (64K x300) java 49ms / native 3ms = 16.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 active (NEON-accelerated)
Base64 CN1 encode 53.000 ms
Base64 CN1 decode 54.000 ms
Image encode benchmark iterations 100
Image createMask (SIMD off) 7.000 ms
Image createMask (SIMD on) 5.000 ms
Image createMask ratio (SIMD on/off) 0.714x (28.6% faster)
Image applyMask (SIMD off) 64.000 ms
Image applyMask (SIMD on) 55.000 ms
Image applyMask ratio (SIMD on/off) 0.859x (14.1% faster)
Image modifyAlpha (SIMD off) 60.000 ms
Image modifyAlpha (SIMD on) 38.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.633x (36.7% faster)
Image modifyAlpha removeColor (SIMD off) 40.000 ms
Image modifyAlpha removeColor (SIMD on) 38.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.950x (5.0% faster)

ParparVM vs HotSpot (JDK 25): macOS arm64

Runner CPU: Apple M1 (Virtual) (baseline macos-arm64)

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 (HelloCodenameOne) 3 0.84x (base 0.96x, -11.9%) 0.88x (base 0.93x, -4.6%) ok
translator (self) 3 0.67x (base 0.62x, +7.5%) 0.68x (base 0.58x, +18.6%) ok
intArithmetic 3 1.07x (base 1.03x, +3.5%) 0.12x (base 0.12x, +1.7%) ok
longArithmetic 3 1.04x (base 1.03x, +1.0%) 0.11x (base 0.07x, +63.9%) ok
mathTranscendental 3 0.96x (base 1.01x, -4.3%) 0.12x (base 0.12x, +0.4%) ok
arraySequential 3 0.47x (base 0.42x, +11.5%) 0.53x (base 0.53x, +0.9%) ok
arrayRandom 3 0.98x (base 0.99x, -1.1%) 0.32x (base 0.32x, +0.1%) ok
objectAllocation 3 1.04x (base 1.11x, -5.8%) 0.78x (base 0.72x, +7.4%) ok
valueEscape 3 0.51x (base 0.51x, +0.3%) 0.09x (base 0.09x, -3.2%) ok
hashMapChurn 3 1.05x (base 1.18x, -10.6%) 0.08x (base 0.07x, +13.0%) ok
stringBuilding 3 0.90x (base 0.84x, +6.6%) 0.47x (base 0.46x, +0.4%) ok
recursion 3 1.21x (base 1.24x, -2.2%) 0.12x (base 0.12x, -1.2%) ok
quicksort 3 1.00x (base 1.01x, -1.6%) 0.11x (base 0.11x, +0.8%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 176 screenshots: 176 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 1962 seconds

Build and Run Timing

Metric Duration
Simulator Boot 47000 ms
Simulator Boot (Run) 7000 ms
App Install 13000 ms
App Launch 1000 ms
Test Execution 403000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 296ms / native 4ms = 74.0x speedup
SIMD float-mul (64K x300) java 74ms / native 3ms = 24.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 63.000 ms
Base64 CN1 decode 66.000 ms
Base64 native encode 667.000 ms
Base64 encode ratio (CN1/native) 0.094x (90.6% faster)
Base64 native decode 444.000 ms
Base64 decode ratio (CN1/native) 0.149x (85.1% faster)
Base64 SIMD encode 69.000 ms
Base64 encode ratio (SIMD/CN1) 1.095x (9.5% slower)
Base64 SIMD decode 51.000 ms
Base64 decode ratio (SIMD/CN1) 0.773x (22.7% faster)
Base64 encode ratio (SIMD/native) 0.103x (89.7% faster)
Base64 decode ratio (SIMD/native) 0.115x (88.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 17.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.059x (94.1% faster)
Image applyMask (SIMD off) 29.000 ms
Image applyMask (SIMD on) 37.000 ms
Image applyMask ratio (SIMD on/off) 1.276x (27.6% slower)
Image modifyAlpha (SIMD off) 32.000 ms
Image modifyAlpha (SIMD on) 153.000 ms
Image modifyAlpha ratio (SIMD on/off) 4.781x (378.1% slower)
Image modifyAlpha removeColor (SIMD off) 49.000 ms
Image modifyAlpha removeColor (SIMD on) 28.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.571x (42.9% faster)

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 176 screenshots: 176 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 2023 seconds

Build and Run Timing

Metric Duration
Simulator Boot 83000 ms
Simulator Boot (Run) 2000 ms
App Install 29000 ms
App Launch 1000 ms
Test Execution 476000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 199ms / native 5ms = 39.8x speedup
SIMD float-mul (64K x300) java 200ms / native 18ms = 11.1x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 61.000 ms
Base64 CN1 decode 72.000 ms
Base64 native encode 1859.000 ms
Base64 encode ratio (CN1/native) 0.033x (96.7% faster)
Base64 native decode 737.000 ms
Base64 decode ratio (CN1/native) 0.098x (90.2% faster)
Base64 SIMD encode 68.000 ms
Base64 encode ratio (SIMD/CN1) 1.115x (11.5% slower)
Base64 SIMD decode 55.000 ms
Base64 decode ratio (SIMD/CN1) 0.764x (23.6% faster)
Base64 encode ratio (SIMD/native) 0.037x (96.3% faster)
Base64 decode ratio (SIMD/native) 0.075x (92.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 6.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.333x (66.7% faster)
Image applyMask (SIMD off) 56.000 ms
Image applyMask (SIMD on) 495.000 ms
Image applyMask ratio (SIMD on/off) 8.839x (783.9% slower)
Image modifyAlpha (SIMD off) 92.000 ms
Image modifyAlpha (SIMD on) 38.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.413x (58.7% faster)
Image modifyAlpha removeColor (SIMD off) 139.000 ms
Image modifyAlpha removeColor (SIMD on) 292.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 2.101x (110.1% slower)

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 236 screenshots: 236 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 175 screenshots: 175 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 574 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 96ms / native 4ms = 24.0x speedup
SIMD float-mul (64K x300) java 88ms / native 6ms = 14.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 83.000 ms
Base64 CN1 decode 90.000 ms
Base64 native encode 963.000 ms
Base64 encode ratio (CN1/native) 0.086x (91.4% faster)
Base64 native decode 538.000 ms
Base64 decode ratio (CN1/native) 0.167x (83.3% faster)
Base64 SIMD encode 89.000 ms
Base64 encode ratio (SIMD/CN1) 1.072x (7.2% slower)
Base64 SIMD decode 85.000 ms
Base64 decode ratio (SIMD/CN1) 0.944x (5.6% faster)
Base64 encode ratio (SIMD/native) 0.092x (90.8% faster)
Base64 decode ratio (SIMD/native) 0.158x (84.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 13.000 ms
Image createMask (SIMD on) 6.000 ms
Image createMask ratio (SIMD on/off) 0.462x (53.8% faster)
Image applyMask (SIMD off) 70.000 ms
Image applyMask (SIMD on) 67.000 ms
Image applyMask ratio (SIMD on/off) 0.957x (4.3% faster)
Image modifyAlpha (SIMD off) 77.000 ms
Image modifyAlpha (SIMD on) 77.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.000x (0.0% slower)
Image modifyAlpha removeColor (SIMD off) 136.000 ms
Image modifyAlpha removeColor (SIMD on) 93.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.684x (31.6% faster)

@shai-almog

shai-almog commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 171 screenshots: 171 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

@shai-almog
shai-almog merged commit 0c2ba17 into master Oct 25, 2026
113 checks passed
@shai-almog
shai-almog deleted the backend-streaming branch October 25, 2026 01:57
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.

RFE: Backend bounded streaming bodies, multipart uploads, and proxy forwarding

1 participant