Prototype remote raw-memory engine + live address tracking for MIDlet Memory Editor - #109
Draft
H3nb wants to merge 56 commits into
Draft
Prototype remote raw-memory engine + live address tracking for MIDlet Memory Editor#109H3nb wants to merge 56 commits into
H3nb wants to merge 56 commits into
Conversation
10 tasks
H3nb
force-pushed
the
feature/true-memory-editor
branch
from
August 26, 2026 04:40
71fcb25 to
06c6ee1
Compare
Rebuild the raw Memory Editor scanner core directly on 640fa1d, the parent of the emulation-speed commit. Keep only the native scanner, AIDL/service contract, managed self-test/session state, and debug service declaration. Deliberately omit the previous Activity/Compose editor UI so the next commit can replace it with a lower-allocation in-MicroActivity overlay.
H3nb
force-pushed
the
feature/true-memory-editor
branch
from
August 26, 2026 18:11
88d877c to
794e6ca
Compare
Install a debug-only bootstrap in :midlet that attaches a tiny trigger to MicroActivity and lazily warms a reusable classic-View editor before New Search is enabled. Keep subsequent game/editor round trips to VISIBLE/GONE, make result observation manual by default, preallocate result rows and primitive grouping buffers, retain optional Live mode as an explicit higher-allocation trade-off, and document the Android 16 vs Android 11 address-stability test.
Temporarily allow Android CI to run for the dedicated alpha-pre-emulation-speed PR base so the exact experimental tree can be linted, tested, and assembled. This workflow-only change will be removed after validation.
Treat ART GC-count growth as telemetry, not proof that retained addresses moved. Add a thin JNI alias facade so an early GC-triggered relocation request first tests the existing raw candidates, while a direct no-match immediately followed by relocation does not repeat the direct pass. Keep the established native scanner and locking implementation unchanged.
Keep only the tiny trigger state before first use, allocate all result buffers/callbacks/builders and reusable Views during a one-time pre-search warm-up, and avoid rebuilding layout/status on ordinary same-orientation reopen. Keep live observation opt-in and make the same-Activity panel visibly translucent over the running MIDlet.
H3nb
force-pushed
the
alpha-pre-emulation-speed
branch
from
August 27, 2026 16:53
164029a to
b21fb7d
Compare
H3nb
force-pushed
the
feature/true-memory-editor
branch
from
August 27, 2026 16:53
ad1b102 to
8bac5fb
Compare
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.
Status
Important
Draft / physical-device prototype. Do not merge yet.
The cross-process architecture is now proven on the physical Android 16 device. Same-UID
:memory_engine -> :midlet/proc/<pid>/maps,process_vm_readv,process_vm_writev, readback and restore all pass without root in multiple MIDlets.No
SYSTEM_ALERT_WINDOW, no second UI Activity, and no root requirement. The overlay remains a child View ofMicroActivityand dies naturally with the MIDlet.The PR base remains
alpha-pre-emulation-speed; emulation-speed commit4a4a1142b59e5c748b69de06597e80476e9ae4e8remains excluded from the performance baseline.Physical evidence
Remote access gate passed in both Bounce and Green Farm. A later Green Farm run demonstrated a real remote scanner host PID distinct from the MIDlet target PID.
Explicit Int32
The authoritative candidate was remotely edited and independent readback succeeded; the game value changed.
A normal direct refinement stayed remote and cheap:
Auto relocation
This is the intended semantic: the 52 fresh exact matches remained only a recovery pool; one logical old address group survived as four typed aliases.
Target-heap isolation
On the normal remote path, the in-process fallback scanner is not started. Candidate vectors, scan buffers, refinement state, relocation pools and visible-address recovery live in native memory in
:memory_engine.:midletkeeps only the game, classic overlay, target bridge andlibjlprobe.so.mincore()remains target-side because it operates on the caller address space; compressed resident runs are then scanned remotely.Live UI polling remains OFF by default so TextView/string churn does not become a new target ART-GC source. Physical testing observed
UI warm-up GC Δ: 0.Search semantics
:memory_engine.Next Scan first direct-refines retained addresses. If it returns zero and relocation context exists, the engine refreshes target resident runs and builds a fresh exact-value recovery pool. The fresh pool never becomes the result set by itself.
A valid no-match ends at 0 candidates. Previous stale results are not retained simply because relocation identity was unavailable.
Recovered buckets now retain fresh-pool per-type
Seenprovenance in diagnostics; global relocation counts/groups remain the authoritative relocation summary.Remote live address tracking
A raw address is treated as a mutable binding rather than logical identity. For up to 32 visible unique address groups,
libjlremote.sotracks:States:
The temporal signature uses 64 bytes before + 64 bytes after the value, excludes the 8-byte maximum target span, uses 4-byte lanes, ignores zero/
0xFFFFFFFF, and learns which lanes remain stable over time.GC telemetry is not proof of movement. The existing address remains
STABLEif its identity still validates. Recovery starts only when that binding fails.Recovery is bounded:
A -> Brebind rebases the identity signature to B.SUSPECT,AMBIGUOUS, andLOSTbindings are exposed as unreadable and cannot pass the exact-write guard.ANR-safe live pipeline
Full live-address recovery is never executed on the synchronous Binder/UI path.
The one-tick delay is intentional. It keeps full resident-ART recovery away from Android input dispatch.
Diagnostics now include:
The separate EventQueue ANR hardening remains: Android main/UI-thread events do not enter the synchronous immediate MIDlet callback path that previously waited behind a long game paint callback.
Next physical-device gate
Green Farm explicit Int32 live address
ENG✓, then confirmBackend: :memory_engine.liveStable > 0,liveRebinds=0.liveRecoveryScans > 0,liveRebinds > 0, andliveRelocated/subsequentliveStableevidence.Then repeat Auto refinement and the >25k regression. Search semantics must remain independent of visible live binding, and large untracked sets must never stick on the previous result.
There is still no Freeze and no blind mass write. Freeze remains gated on repeated successful live-address tests and must later suspend writes whenever identity is suspect/ambiguous/lost. Issue #108 remains the research/acceptance gate.