Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
17c5ce8
ParparVM perf tier1: box caches, BCE, conditional-volatile SSA, nurse…
shai-almog Jun 27, 2026
185085c
ParparVM: pre-size the StringBuilder in invokedynamic string-concat l…
shai-almog Jun 27, 2026
f123617
ParparVM tagged-int: fix 4 header-deref crashes found by edge-case re…
shai-almog Jun 27, 2026
7049ad0
ParparVM: native HashMap.get (closed-world hot-path wrapper collapse)
shai-almog Jun 27, 2026
519d5e1
ParparVM: native HashMap.put (closed-world hot-path wrapper collapse)
shai-almog Jun 27, 2026
bc9e713
ParparVM: native StringBuilder.append(int)/append(long) digit writers
shai-almog Jun 27, 2026
5da6233
ParparVM: HashMap Entry object pool (eliminate churn allocation)
shai-almog Jun 27, 2026
ae6af08
ParparVM: StringBuilder.toString shares the buffer (copy-on-write)
shai-almog Jun 27, 2026
be882e4
ParparVM: inline the full method-frame setup/teardown
shai-almog Jun 27, 2026
7fc70f2
ParparVM: inline pop() (operand-stack pop helper)
shai-almog Jun 27, 2026
d4185da
ParparVM: @StackAllocate annotation -> stack-allocate non-escaping ob…
shai-almog Jun 28, 2026
8ea3c18
ParparVM: scalar-replace @StackAllocate objects -> clang promotes to …
shai-almog Jun 28, 2026
7469b54
ParparVM: fuse LCMP+IFxx into a direct long comparison (clang can vec…
shai-almog Jun 28, 2026
ab36ca8
ParparVM: elide per-line stack-trace line stores on non-throwing lines
shai-almog Jun 28, 2026
aa2838e
ParparVM: parallel GC marking (work-pool drain, atomic claim)
shai-almog Jun 28, 2026
7df04ea
ParparVM: non-moving BiBOP segregated heap + page sweep for small obj…
shai-almog Jun 28, 2026
0260fe8
ParparVM: frameless codegen for primitive-only methods (recursion 4.6…
shai-almog Jun 29, 2026
b0e6c98
ParparVM: conservative native-stack GC + frameless for object-bearing…
shai-almog Jun 29, 2026
9933311
ParparVM: fix Thread.start/join visibility race (alive set on wrong t…
shai-almog Jun 29, 2026
d34c80c
ParparVM: default-on conservative native-stack GC + object/instance f…
shai-almog Jun 29, 2026
37e8f62
ParparVM: inline BiBOP bump alloc fast-path at the new-site (-DCN1_IN…
shai-almog Jun 29, 2026
85502d5
ParparVM: inline tiny leaf constructors + de-atomic byte accounting (…
shai-almog Jun 29, 2026
3edcbc8
ParparVM: fix use-after-free in conservative-GC root-snapshot build (…
shai-almog Jun 29, 2026
b3dcdf3
ParparVM: make the alloc fast-path default-on (un-gate; this is an AO…
shai-almog Jun 30, 2026
bd0d808
ParparVM: adaptive allocation pacing (bound churn RSS) + batched page…
shai-almog Jun 30, 2026
9c9e298
ParparVM: O(live-pages) BiBOP sweep -- O(1) reclaim/skip of homogeneo…
shai-almog Jun 30, 2026
4b82a95
ParparVM: trim the per-object BiBOP alloc fast path (dead store + cou…
shai-almog Jun 30, 2026
60b9910
ParparVM: shrink the per-object header 48 -> 16 bytes (relocate 3 GC …
shai-almog Jun 30, 2026
3008cfa
ParparVM: always-on per-object memset elimination + thread-stop GC ha…
shai-almog Jul 2, 2026
0f8afae
ParparVM: single-writer allObjectsInHeap (dead-thread drain) + once-p…
shai-almog Jul 2, 2026
a7de4b0
ParparVM: general fused objects (@Fused) + small arrays in BiBOP + Ja…
shai-almog Jul 2, 2026
6373a47
ParparVM: computed-size fused children (new int[w*h]) + ThinLTO for R…
shai-almog Jul 2, 2026
d136205
ParparVM: register-allocatable locals, frameless whitelist holes, fmo…
shai-almog Jul 2, 2026
7a507a4
ParparVM: per-page sticky monitor flag replaces the global sweep supp…
shai-almog Jul 2, 2026
04e9dad
ParparVM: closed-world devirtualization, String finalizer removal, st…
shai-almog Jul 2, 2026
4a2aa8b
Compact open-addressed HashMap + native String compare: hashMapChurn …
shai-almog Jul 2, 2026
fe7a37e
Fused StringBuilder + native single-block toString; setLength zero-fi…
shai-almog Jul 2, 2026
65a965f
Diverging array checks in frameless loops: quicksort below HotSpot
shai-almog Jul 2, 2026
088d89e
Implicit stack allocation of non-escaping StringBuilders + two GC-tri…
shai-almog Jul 2, 2026
287369b
Merge remote-tracking branch 'origin/master' into parparvm-perf-tier1
shai-almog Jul 2, 2026
d58d816
String/StringBuilder call-site intrinsics; native-bracket elision; GC…
shai-almog Jul 2, 2026
a2148bd
Fix Linux/Windows portability of the conservative-GC + allocator code
shai-almog Jul 2, 2026
ecaa19e
Fix remaining CI failures: Win32 shim gaps, JS delegate retention, st…
shai-almog Jul 2, 2026
64946a6
Fix missing include when trivial-accessor inlining crosses classes
shai-almog Jul 2, 2026
59ea779
Fix two more trivial-accessor inlining bugs: setter arity, fold order…
shai-almog Jul 2, 2026
f363d3f
Fix setjmp/longjmp UB in try/catch codegen: restoreTo must be volatile
shai-almog Jul 2, 2026
acd947f
Fix mid-line preprocessor directive from the ctor-inlining emission
shai-almog Jul 2, 2026
e094586
iOS port: migrate the ellipsis-string pin to the immortal-root registry
shai-almog Jul 3, 2026
3a2eb81
Preallocate StackOverflowError: throwing at exhaustion must not build…
shai-almog Jul 3, 2026
ba4ed19
Fix the two SpotBugs gate violations in BytecodeMethod
shai-almog Jul 3, 2026
4f911a8
Benchmark suite in-repo; charAt logical-length bound; tagged ints def…
shai-almog Jul 3, 2026
39e18bb
Developer guide: satisfy the prose quality gates on the new section
shai-almog Jul 3, 2026
1669554
Refresh Linux picker goldens: the old ones encoded the case-conversio…
shai-almog Jul 3, 2026
736f43b
watch tests: capture app console + instrument toast/annotation state
shai-almog Jul 3, 2026
86bbe64
VM: release the class-init monitor when a static initializer throws
shai-almog Jul 3, 2026
5f0af69
Merge remote-tracking branch 'origin/master' into parparvm-perf-tier1
shai-almog Jul 3, 2026
3cdc797
signed bytes on ARM-Linux; deterministic toast test; linux suite diag…
shai-almog Jul 3, 2026
c879be9
VM: key monitor reentrancy on the pthread, not the thread-state id
shai-almog Jul 3, 2026
6a0070c
CN1_MONITOR_SELF: use the compat shim's pthread_self().id on Windows
shai-almog Jul 3, 2026
81af321
linux harness: create CN1_APP_LOG_TEE parent dirs
shai-almog Jul 3, 2026
1bcf273
JS port: protect runtime-delegate twins from identifier minification
shai-almog Jul 3, 2026
d2b2608
linux CI: gdb hang watchdog for the suite wedge
shai-almog Jul 3, 2026
7072d13
VM: frameless SOE guard must not misfire on foreign stacks
shai-almog Jul 3, 2026
66378a1
linux CI: the suite wedge is a silent crash -- capture cores + exit s…
shai-almog Jul 3, 2026
64c1dce
linux CI: richer GC-crash post-mortem
shai-almog Jul 3, 2026
163a5aa
toast test: hold for the slide animation before capturing
shai-almog Jul 3, 2026
30257f5
VM: acquire-load the mark word in parallel GC marking (arm64 heap cor…
shai-almog Jul 3, 2026
3ad6797
VM: default parallel GC marking to serial (arm64 isolation experiment)
shai-almog Jul 3, 2026
2763ccf
VM: exempt conservative stack scan from ASan (enables meaningful ASan…
shai-almog Jul 3, 2026
52bd25b
ToastBar: add non-animated show; make the TOP-position screenshot det…
shai-almog Jul 3, 2026
ef6e7b6
Revert ToastBar test changes to the known-good baseline
shai-almog Jul 3, 2026
c9d3b55
TEMP: Linux x64 ASan diagnostic workflow
shai-almog Jul 4, 2026
3a5b59c
linux-asan-x64: push-trigger on the feature branch (workflow_dispatch…
shai-almog Jul 4, 2026
c400885
linux-asan-x64: build the maven plugin before suite classes (mirror p…
shai-almog Jul 4, 2026
094245a
Remove temp Linux x64 ASan diagnostic workflow
shai-almog Jul 4, 2026
27a3332
VM: CN1_BIBOP_VALIDATE invariant checks for the x64 allocator crash
shai-almog Jul 4, 2026
68db022
TEMP: Linux x64 BiBOP-validate diagnostic workflow (x3 suite runs, re…
shai-almog Jul 4, 2026
0d1f7a1
CN1_BIBOP_VALIDATE: validate the object at the mark-drain source
shai-almog Jul 4, 2026
9c5ab69
CN1_BIBOP_VALIDATE: catch stale-mark + out-of-text markFunction at drain
shai-almog Jul 4, 2026
78752a2
VM FIX: gcMarkObject must reject freed BiBOP slots (x64 GC crash)
shai-almog Jul 4, 2026
de65c2c
Remove temp x64 BiBOP-validate diagnostic workflow (bug fixed + confi…
shai-almog Jul 4, 2026
0abf15f
Windows port: offscreen WIC capture for the cn1ss suite + BiBOP no-fa…
shai-almog Jul 5, 2026
1ab06af
GC forensics: pin the intermittent Linux gcMarkObject mid-mark SIGSEGV
shai-almog Jul 5, 2026
ff7a1f1
GC: SATB write barrier to close the concurrent-mark cross-thread race
shai-almog Jul 5, 2026
9ccb524
GC forensics: name the corrupt-child culprit (parent class + mark cal…
shai-almog Jul 5, 2026
2faff80
ci: post-mortem prints the mark drain-parent + its class name
shai-almog Jul 5, 2026
60ef4c7
GC: belt pass -- guarantee mark-drain completeness before sweep
shai-almog Jul 5, 2026
58b71b4
ci: A/B the O(1) all-dead reclaim (-DCN1_BIBOP_NO_FASTSWEEP) as crash…
shai-almog Jul 5, 2026
952ae3d
GC forensics: name the drain-incompleteness (belt-recovered class -> …
shai-almog Jul 5, 2026
8b6a56f
GC: revert looped belt to single-pass (looping livelocks vs active mu…
shai-almog Jul 5, 2026
0171685
GC: drain grace-object subtrees before sweep (fixes swept-while-reach…
shai-almog Jul 5, 2026
6dd95de
GC: add SATB insertion barrier to close the grace-object residual
shai-almog Jul 5, 2026
ffde9e2
GC: keep SATB armed through grace pass + belt (drain the log last)
shai-almog Jul 5, 2026
4888b66
GC: stop-the-world final mark -- loop belt to a true fixpoint (deadlo…
shai-almog Jul 5, 2026
275b672
Revert "GC: stop-the-world final mark -- loop belt to a true fixpoint…
shai-almog Jul 5, 2026
8055d28
GC: poor-man's generational adoption -- mature surviving BiBOP subtre…
shai-almog Jul 5, 2026
2a8e47a
GC: teach the remaining -4 (adopted) sentinel sites + VALIDATE guards
shai-almog Jul 5, 2026
7340a05
ci(linux): drop the temporary CN1_BIBOP_VALIDATE diagnostic from the …
shai-almog Jul 5, 2026
9c9bccf
GC: defer adoption registration out of the mark (fix reentrant allObj…
shai-almog Jul 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion .github/workflows/linux-build-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ jobs:
working-directory: vm
env:
CN1_SHOT_OUTPUT_DIR: ${{ github.workspace }}/artifacts/linux-port/raw
# Full app stdout/stderr -- the only evidence when the suite wedges
# mid-run (uploaded with the screenshot artifact below).
CN1_APP_LOG_TEE: ${{ github.workspace }}/artifacts/linux-port/raw/app-output.log
# Build the native ELF (and the demo) against an old glibc for portability.
CN1_CC: /usr/local/bin/cn1-zig-cc
# After the suite runs, the capture test relinks the same objects into a
Expand All @@ -215,13 +218,37 @@ jobs:
LIBGL_ALWAYS_SOFTWARE: '1'
run: |
set -e
sudo apt-get install -y --no-install-recommends gdb >/dev/null 2>&1 || true
Xvfb :99 -screen 0 1200x1600x24 >/tmp/xvfb-run.log 2>&1 &
export DISPLAY=:99
sleep 2
# The suite intermittently DIES mid-run with no output (gdb-attach
# watchdog found the pid already gone -- a silent crash, not a hang).
# Enable core dumps and post-mortem them into the artifact.
ulimit -c unlimited
echo '/tmp/cn1-cores/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern >/dev/null
mkdir -p /tmp/cn1-cores
rc=0
mvn -B clean package -pl JavaAPI -am -DskipTests
mvn -B test -pl tests -am \
'-Dtest=CleanTargetLinuxIntegrationTest#capturesHelloSuiteOverWebSocketLinux' \
'-Dsurefire.failIfNoSpecifiedTests=false'
'-Dsurefire.failIfNoSpecifiedTests=false' || rc=$?
for core in /tmp/cn1-cores/core.*; do
[ -f "$core" ] || continue
elf="$(/usr/bin/find /tmp -maxdepth 4 -name LinuxHelloMain -type f 2>/dev/null | head -1)"
mkdir -p "$(dirname "$CN1_APP_LOG_TEE")"
{
echo "=== post-mortem of $core (elf=$elf) ==="
gdb "$elf" "$core" -batch -ex 'set pagination off' \
-ex 'thread apply all bt' \
-ex 'thread 1' -ex 'bt full' \
-ex 'frame 0' -ex 'info args' \
-ex 'frame 1' -ex 'info locals' -ex 'info args' \
-ex 'p gcMarkWorklistTop' -ex 'p currentGcMarkValue' \
2>&1
} >> "$(dirname "$CN1_APP_LOG_TEE")/crash-stacks.txt" || true
done
exit $rc

- name: Upload screenshot artifact (${{ matrix.arch }})
if: always()
Expand Down Expand Up @@ -268,6 +295,7 @@ jobs:
docker run --rm \
-v "$GITHUB_WORKSPACE":/cn1 -w /cn1 \
-e CN1_SHOT_OUTPUT_DIR=/cn1/artifacts/linux-port/raw-musl \
-e CN1_APP_LOG_TEE=/cn1/artifacts/linux-port/raw-musl/app-output.log \
-e LIBGL_ALWAYS_SOFTWARE=1 \
docker.io/library/alpine:3.20 sh -ec '
sed -i "s|^#\(.*/community\)|\1|" /etc/apk/repositories
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/parparvm-tests-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,22 @@ jobs:
mvn -B clean package -pl JavaAPI -am -DskipTests
mvn -B test -pl tests -am '-Dtest=CleanTargetIntegrationTest#capturesHelloSuiteOverWebSocket' '-Dsurefire.failIfNoSpecifiedTests=false'

# Preserve the native cn1WindowsLog output so the offscreen-capture path is
# confirmable on the green x64 gate too (compare against the arm64 leg).
- name: Collect native windows log (x64)
if: always()
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path artifacts/windows-port/raw | Out-Null
$log = Join-Path $env:TEMP 'cn1windows.log'
if (Test-Path $log) {
Copy-Item $log artifacts/windows-port/raw/cn1windows-native.log -Force
Write-Host "collected native log ($((Get-Item $log).Length) bytes)"
} else {
"no native cn1windows.log found at $log" | Out-File artifacts/windows-port/raw/cn1windows-native.log
Write-Host "no native log at $log"
}

- name: Upload screenshot artifact (x64)
if: always()
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -474,6 +490,24 @@ jobs:
mvn -B clean package -pl JavaAPI -am -DskipTests
mvn -B test -pl tests -am '-Dtest=CleanTargetIntegrationTest#capturesHelloSuiteOverWebSocket' '-Dsurefire.failIfNoSpecifiedTests=false'

# Preserve the native cn1WindowsLog output (%TEMP%\cn1windows.log) so an
# offscreen-target / capture failure is diagnosable from the artifact, and
# so the raw dir is never empty (the arm64 artifact would otherwise not be
# produced when the suite stalls before writing any PNG).
- name: Collect native windows log (arm64)
if: always()
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path artifacts/windows-port/raw | Out-Null
$log = Join-Path $env:TEMP 'cn1windows.log'
if (Test-Path $log) {
Copy-Item $log artifacts/windows-port/raw/cn1windows-native.log -Force
Write-Host "collected native log ($((Get-Item $log).Length) bytes)"
} else {
"no native cn1windows.log found at $log" | Out-File artifacts/windows-port/raw/cn1windows-native.log
Write-Host "no native log at $log"
}

- name: Upload screenshot artifact (arm64)
if: always()
uses: actions/upload-artifact@v4
Expand Down
36 changes: 36 additions & 0 deletions CodenameOne/src/com/codename1/annotations/Fused.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.codename1.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/// Marks a class whose constructor-created primitive-array fields are fully
/// ENCAPSULATED, letting ParparVM allocate each instance TOGETHER with those
/// arrays as a single heap block ("fused object"): one allocation instead of
/// several, one object for the garbage collector instead of several, and the
/// arrays share the owner's cache lines. A fused array keeps a completely
/// ordinary header -- all reading code, `System.arraycopy`, iteration and
/// bounds checks work unchanged -- but it has no independent GC identity: it
/// is never separately tracked, marked for reclamation, or swept; it simply
/// lives and dies with its owner.
///
/// The translator fuses a constructor-assigned field when the constructor
/// contains an unconditional `this.f = new T[n]` where `T` is a primitive type
/// and `n` is a constructor parameter or constant (bounds-check guards that
/// throw are fine before it). Constructors keep chaining normally, and every
/// other instantiation path -- reflection, deserialization, oversized arrays
/// that do not fit a fused block -- transparently falls back to ordinary
/// separate allocations with identical semantics.
///
/// THE CONTRACT: the marked class must never let a fused array reference
/// escape into another object's field, an array element, or a static that can
/// outlive the instance. Holding it in locals, passing it as a call argument,
/// or copying its contents out is always safe (the VM keeps the whole block
/// alive through any reference into it held on a thread stack). Typical
/// candidates: string/buffer classes owning their `char[]`, image types owning
/// their pixel `int[]`/`byte[]` data.
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Fused {
}
10 changes: 10 additions & 0 deletions Ports/WindowsPort/nativeSources/cn1_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,16 @@ typedef struct {
JAVA_INT shotW;
JAVA_INT shotH;

/* Offscreen-capture mode (the cn1ss WebSocket screenshot suite): a real
* (hidden) window is still created so the message pump, DPI and exact client
* size are identical to a normal run, but windowGraphics is pointed at an
* offscreen WIC bitmap of that same client size instead of the HWND target.
* That makes captureWindowToPngBytes read back real frames (the proven WIC
* path) instead of falling back to a fresh per-screenshot mutable-image
* repaint -- which is the expensive step that stalled the slow windows-11-arm
* runner mid-suite. Unlike `headless` there is no single-shot auto-exit. */
volatile LONG offscreenCapture;

/* Pending window resize. WM_SIZE (main thread) records the new size here and
* the EDT applies the Direct2D Resize between its own frames -- resizing the
* HWND render target from another thread while the EDT is mid-BeginDraw is
Expand Down
29 changes: 28 additions & 1 deletion Ports/WindowsPort/nativeSources/cn1_windows_screenshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,19 @@ JAVA_OBJECT com_codename1_impl_windows_WindowsNative_captureWindowToPngBytes___R
CODENAME_ONE_THREAD_STATE) {
CN1Graphics* g = cn1Win.windowGraphics;
if (g == NULL || g->wicBitmap == NULL) {
cn1WindowsLog("captureWindowToPngBytes: window target is not WIC-backed");
/* Detailed reason so a capture miss is diagnosable from the log rather
* than a bare "not WIC-backed" (which read as an every-run condition in
* the old windowed WebSocket path). */
if (g == NULL) {
cn1WindowsLog("captureWindowToPngBytes: windowGraphics is NULL "
"(initDisplay never created a target)");
} else {
cn1WindowsLog(cn1Win.offscreenCapture
? "captureWindowToPngBytes: offscreen capture requested but wicBitmap is NULL "
"(offscreen target creation failed at initDisplay)"
: "captureWindowToPngBytes: window target is not WIC-backed "
"(HWND target -- caller falls back to mutable-image capture)");
}
return JAVA_NULL;
}
cn1WinEndFrame(g);
Expand All @@ -284,6 +296,21 @@ JAVA_VOID com_codename1_impl_windows_WindowsNative_enableHeadlessScreenshot___ja
cn1Win.headless = 1;
}

/*
* Enables offscreen-capture mode for the long-running cn1ss WebSocket screenshot
* suite (call before initDisplay). A hidden window is still created -- so the
* message pump, DPI and exact client size match a normal run -- but the EDT
* paints into an offscreen WIC bitmap of that client size, so
* captureWindowToPngBytes returns a real rendered frame every time instead of
* falling back to a per-screenshot mutable-image repaint. Unlike
* enableHeadlessScreenshot there is no shotPath and no single-shot auto-exit; the
* process stays alive for the whole suite.
*/
JAVA_VOID com_codename1_impl_windows_WindowsNative_enableOffscreenCapture__(
CODENAME_ONE_THREAD_STATE) {
cn1Win.offscreenCapture = 1;
}

} /* extern "C" */

#endif /* _WIN32 */
23 changes: 19 additions & 4 deletions Ports/WindowsPort/nativeSources/cn1_windows_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,16 +753,31 @@ JAVA_VOID com_codename1_impl_windows_WindowsNative_initDisplay___java_lang_Strin
return;
}
cn1WindowsLog("initDisplay: render target created");
cn1Win.windowGraphics = cn1WinCreateGraphics((ID2D1RenderTarget*) g_hwndTarget);
if (cn1Win.offscreenCapture) {
/* Render into an offscreen WIC bitmap sized to the real client area, so
* captureWindowToPngBytes reads back the proven WIC frame instead of a
* per-screenshot mutable-image repaint. The HWND target stays created
* (the window is valid, just never shown or drawn to). */
cn1Win.windowGraphics = cn1WinCreateOffscreenGraphics(cn1Win.width, cn1Win.height);
cn1WindowsLog(cn1Win.windowGraphics != NULL
? "initDisplay: offscreen capture target created"
: "initDisplay: offscreen capture target FAILED");
} else {
cn1Win.windowGraphics = cn1WinCreateGraphics((ID2D1RenderTarget*) g_hwndTarget);
}

/* WIC factory for the image layer. The DirectWrite factory is created lazily
* inside the C++ text layer (cn1_windows_dwrite.cpp), not here. */
CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory, (void**) &cn1Win.wicFactory);

ShowWindow(cn1Win.hwnd, SW_SHOW);
UpdateWindow(cn1Win.hwnd);
cn1WindowsLog("initDisplay: window shown");
if (!cn1Win.offscreenCapture) {
ShowWindow(cn1Win.hwnd, SW_SHOW);
UpdateWindow(cn1Win.hwnd);
cn1WindowsLog("initDisplay: window shown");
} else {
cn1WindowsLog("initDisplay: offscreen capture -- window kept hidden");
}
}

JAVA_INT com_codename1_impl_windows_WindowsNative_getDisplayWidth___R_int(CODENAME_ONE_THREAD_STATE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@ public static native void setTransform(long graphics, float m00, float m10, floa
*/
public static native void enableHeadlessScreenshot(String path, int width, int height);

/**
* Enables offscreen-capture mode for the long-running cn1ss WebSocket
* screenshot suite (call before {@code initDisplay}). A hidden window is
* still created -- so the message pump, DPI and exact client size match a
* normal run -- but the EDT paints into an offscreen WIC bitmap of that
* client size, so {@link #captureWindowToPngBytes()} returns a real rendered
* frame every time instead of falling back to a per-screenshot mutable-image
* repaint (the expensive step that stalled the slow windows-11-arm runner
* mid-suite). Unlike {@link #enableHeadlessScreenshot} there is no auto-exit.
*/
public static native void enableOffscreenCapture();

/**
* Encodes a {@code width*height} block of straight-alpha ARGB pixels (CN1
* getRGB layout) to PNG and returns the bytes. Backs the port's ImageIO.
Expand Down
18 changes: 10 additions & 8 deletions Ports/iOSPort/nativeSources/IOSNative.m
Original file line number Diff line number Diff line change
Expand Up @@ -8534,6 +8534,9 @@ JAVA_OBJECT com_codename1_impl_ios_IOSNative_sqlCursorValueAtColumnString___long
JAVA_OBJECT str = __NEW_INSTANCE_java_lang_String(threadStateData);
struct obj__java_lang_String* ss = (struct obj__java_lang_String*)str;
ss->java_lang_String_nsString = (JAVA_LONG)ns;
// String has no finalizer anymore: the peer is released by the VM reclaim
// path, which needs the page flagged (see cn1BibopNoteNativePeer).
cn1BibopNoteNativePeer(str);

NSUInteger len = [ns length];
JAVA_OBJECT destArr = __NEW_ARRAY_JAVA_CHAR(threadStateData, len);
Expand Down Expand Up @@ -12975,10 +12978,11 @@ JAVA_INT drawLabelText(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, J
if ((!isTickerRunning) && endsWith3Points) {
if(threePoints == JAVA_NULL) {
threePoints = newStringFromCString(threadStateData, "...");
removeObjectFromHeapCollection(threadStateData, threePoints);
removeObjectFromHeapCollection(threadStateData, ((struct obj__java_lang_String*)threePoints)->java_lang_String_value);
((struct obj__java_lang_String*)threePoints)->java_lang_String_value->__codenameOneReferenceCount = 999999;
threePoints->__codenameOneReferenceCount = 999999;
// permanent cache: the old removeObjectFromHeapCollection +
// refcount=999999 pin is gone (the header field was relocated
// off-object and BiBOP objects are page-swept); the immortal
// root registry marks it and its value array every cycle
cn1AddImmortalRoot(threePoints);
threePointsWidth = com_codename1_impl_ios_IOSImplementation_stringWidth___java_lang_Object_java_lang_String_R_int(threadStateData, __cn1ThisObject, nativeFont, threePoints);
}

Expand All @@ -12990,10 +12994,8 @@ JAVA_INT drawLabelText(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT __cn1ThisObject, J
} else if (endsWith3Points) {
if(threePoints == JAVA_NULL) {
threePoints = newStringFromCString(threadStateData, "...");
removeObjectFromHeapCollection(threadStateData, threePoints);
removeObjectFromHeapCollection(threadStateData, ((struct obj__java_lang_String*)threePoints)->java_lang_String_value);
((struct obj__java_lang_String*)threePoints)->java_lang_String_value->__codenameOneReferenceCount = 999999;
threePoints->__codenameOneReferenceCount = 999999;
// permanent cache: see the RTL branch above
cn1AddImmortalRoot(threePoints);
threePointsWidth = com_codename1_impl_ios_IOSImplementation_stringWidth___java_lang_Object_java_lang_String_R_int(threadStateData, __cn1ThisObject, nativeFont, threePoints);
}
JAVA_INT index = 1;
Expand Down
1 change: 1 addition & 0 deletions docs/developer-guide/languagetool-accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -669,3 +669,4 @@ foldables?
bitmask
DeX
Siri
devirtualization
Loading
Loading