fix(translator): always emit header declarations for native methods regardless of elimination status#4752
Closed
Copilot wants to merge 16 commits intosimd-revisitefrom
Closed
fix(translator): always emit header declarations for native methods regardless of elimination status#4752Copilot wants to merge 16 commits intosimd-revisitefrom
Copilot wants to merge 16 commits intosimd-revisitefrom
Conversation
Copilot
AI
changed the title
[WIP] Fix iOS build by adding missing native method declarations
fix(translator): always emit header declarations for native methods regardless of elimination status
Apr 15, 2026
Collaborator
|
Compared 37 screenshots: 37 matched. Benchmark Results
Detailed Performance Metrics
|
Contributor
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
…e64 SIMD in Java (#4745) * Add NEON-accelerated base64Encode/base64Decode to Simd API and wire into Base64 SIMD methods Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/c218992e-943a-4ce5-8d63-f82c0792416f Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Address code review: clarify loop conditions and comment in NEON base64 Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/c218992e-943a-4ce5-8d63-f82c0792416f Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Add new SIMD generic primitive declarations and remove base64 methods from IOSSimd - Added shl, shrLogical, addWrapping, subWrapping for byte arrays - Added offset-based overloads for unpackUnsignedByteToInt, add, cmpEq, cmpLt, select - Removed base64Encode and base64Decode declarations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Replace base64 overrides with generic SIMD primitive validation wrappers in JavaSESimd Remove base64Encode and base64Decode overrides. Add validation wrapper overrides for new generic Simd primitives: shl, shrLogical, addWrapping, subWrapping, unpackUnsignedByteToInt, add (int[]), cmpEq, cmpLt, and select. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Replace base64 NEON section with generic SIMD primitives in IOSSimd.m Remove NEON-accelerated Base64 encode/decode implementations and add NEON implementations for new generic Simd primitives: shl, shrLogical, addWrapping, subWrapping, unpackUnsignedByteToInt, add (int), cmpEq, cmpLt, and select (with offset parameters). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Remove base64 methods from Simd; add generic byte/int primitives; rewrite Base64 SIMD in Java - Remove base64Encode/base64Decode from Simd, IOSSimd, JavaSESimd, IOSSimd.m - Add generic byte shift primitives: shl(byte[]), shrLogical(byte[]) - Add wrapping byte arithmetic: addWrapping(byte[]), subWrapping(byte[]) - Add offset-based int overloads: unpackUnsignedByteToInt, add, cmpLt, cmpEq, select - Add NEON implementations for all new primitives in IOSSimd.m - Add validation wrappers in JavaSESimd.java - Rewrite encodeNoNewlineSimd in Java using int-domain SIMD compare/select - Rewrite decodeNoWhitespaceSimd in Java using int-domain SIMD shift/or - Update SimdTest with tests for new primitives - All 2345 tests pass Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/5fc6976c-f0ec-4638-b22b-2cbc9c9ca5dd Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Optimize SIMD Base64: replace slow scatter/gather + per-element SIMD calls with fast inline scalar Java The previous approach called 15+ individual Simd operations per 48-byte chunk (each a virtual dispatch + JNI transition on iOS), plus scalar scatter/gather loops for byte↔int conversion. This added ~2500 JNI transitions per encode of 8KB, making it 64-109% slower than the already-fast scalar code. Replace with the same 4x-unrolled table-lookup approach used by encodeNoNewline(), now with offset support. This matches the scalar CN1 encode/decode performance while maintaining the same API contract. Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/90b8c36e-8f20-47da-9fb4-56344f18a336 Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com> * Revert "Optimize SIMD Base64: replace slow scatter/gather + per-element SIMD calls with fast inline scalar Java" This reverts commit 00e5103. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com>
…odsToHeader Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/c81f55e4-6aa2-46d1-8562-28ad84032345 Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com>
… broke TreeMap compilation Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/4469cb06-502d-4670-b0cf-45ae7c65fb0e Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com>
…endencies When @concrete devirtualizes calls (e.g. Simd -> IOSSimd), the concrete class must be included as a dependency. Invoke.addDependencies runs at parse time when the target's @concrete annotation may not be loaded yet. Re-resolve in updateAllDependencies after all classes are parsed. Agent-Logs-Url: https://github.com/codenameone/CodenameOne/sessions/c4936dfb-670f-4728-93e8-2ace2e806d0b Co-authored-by: shai-almog <67850168+shai-almog@users.noreply.github.com>
bdaa1ae to
c19e90e
Compare
Collaborator
|
Compared 37 screenshots: 37 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Invoke.addDependencies()runs at parse time whenresolveConcreteInvokeOwner()may return null (because the target class's@Concreteannotation hasn't been parsed yet). Later,appendInstruction()resolves it correctly — so the generated code callsIOSSimdmethods, butSimdApiTest.mdoesn't#include "IOSSimd.h".ByteCodeClass.updateAllDependencies()(which runs after ALL classes are parsed), re-resolve concrete invoke dependencies so that concrete class headers are properly includedappendMethodsToHeader)Original prompt
Problem
The iOS build fails with:
The translator's
resolveConcreteInvokeOwnercorrectly devirtualizes calls toIOSSimd(becausehasDeclaredNonAbstractMethodreturnstruefor native overrides — native methods are never abstract). However, the generatedcom_codename1_impl_ios_IOSSimd.his missing declarations for those three native methods.Root Cause
In
ByteCodeClass.appendMethodsToHeader()(line 1662 ofByteCodeClass.java), every method inmethodsis iterated andm.appendMethodHeader(b)is called. There is no elimination guard — but native methods have no instructions and the optimizer marks them as eliminated via the dead-code elimination pass (since they have no call graph entries pointing to them when the only callers go throughSimd's virtual dispatch). Once eliminated, the vtable builder (fillVirtualMethodTable) skips them (if (bm.isEliminated()) continue), so they never enter the vtable and never trigger the header emission that way either.The fix is simple:
appendMethodsToHeadermust always emit header declarations for native methods, even if they are marked as eliminated, because native methods are implemented in external.m/.cfiles — the translator cannot know whether they are truly unused without scanning all native sources, and thehasDeclaredNonAbstractMethodpath can route devirtualized calls to them.Fix
In
vm/ByteCodeTranslator/src/com/codename1/tools/translator/ByteCodeClass.java, changeappendMethodsToHeaderfrom:to:
Note:
isNative()is already a public method onBytecodeMethod(it returnsnativeMethod).This is a targeted, minimal fix. Do not change any other logic. Do not refactor. Only modify the
appendMethodsToHeadermethod inByteCodeClass.java.The following is the prior conversation context from the user's chat exploration (may be truncated):
Assistant: Now let me look at the test to understand exactly what methods it's calling, and compare with what
IOSSimd.javahas vs whatSimd.javahas:Assistant: Now I have a clear picture. Let me compare
Simd.javavsIOSSimd.javacarefully to find what's missing inIOSSimd.java.Looking at
Simd.java, these methods exist but are missing fromIOSSimd.java:add(int[] srcA, int srcAOffset, int[] srcB, int srcBOffset, int[] dst, int dstOffset, int length)— present inSimd.java(line 228), but NOT inIOSSimd.javaWait — let me re-check the error messages and compare both files more carefully.
The failing calls in the test are:
com_codename1_impl_ios_IOSSimd_add___int_1ARRAY_int_1ARRAY_int_1ARRAY_int_int— this isadd(int[], int[], int[], int, int)com_codename1_impl_ios_IOSSimd_mul___float_1ARRAY_float_1ARRAY_float_1ARRAY_int_int— this ismul(float[], float[], float[], int, int)com_codename1_impl_ios_IOSSimd_add___byte_1ARRAY_byte_1ARRAY_byte_1ARRAY_int_int— this isadd(byte[], byte[], byte[], int, int)But
IOSSimd.javadoes declare all three of those (lines 42, 105, 177). The implementations are also inIOSSimd.m. So the.mfile is there, the.javais there — but the generated C code is calling them instead of the overridden method.The key insight from the error is:
com_codename1_impl_ios_IOSSimd_add___int_1ARRAY_...is undeclared (not just undefined)com_codename1_util_Simd_add___int_1ARRAY_...being declared incom_codename1_util_Simd.hThis means the bytecode translator is generating a
/* CustomInvoke */call directly to theIOSSimdnative peer — but it's using the wrong resolution. The translator is seeingIOSSimd.javamethods as overrides and generatingCustomInvokecalls to theIOSSimdversion, but there is noIOSSimd.hheader being generated/included for the test file.The real issue is: **
IOSSimd.javais missing the@Overrideannotation on som...This pull request was created from Copilot chat.