Stable checkpoint: game reaches playable 3D gameplay on ARM64
Verified live on a Pixel 6a: the game passes its EULA, loads the prologue and renders real 3D gameplay, with zero heap exhaustion, zero faults and zero rejected frees over a full session. Root causes fixed in this state, each backed by a measurement (details and the list of refuted theories live in ARM64_TRANSLATION_LAYER.md): * JNI varargs float->double promotion. C promotes float to double in any varargs call and every Call*Method form is varargs, so reading one 4-byte slot yielded the double's always-zero low half. EVERY float argument passed to Java was silently becoming 0; text was just where it showed. * GuestHeap ~4x memory overhead. Power-of-two size classes carving the full class, plus segregated free lists that could never share memory between sizes. Reworked to exact sizing with O(log n) best-fit reuse and splitting (deliberately not a linear scan - this allocator already had an O(n) perf cliff in its history). Peak live now 207MB against the real A9's 199MB, fragmentation ~2.5MB. Also fixed: realloc reading past the old block on shrink, a 32-bit overflow in calloc, and drifting payload alignment. * Unbounded FMOD fake-handle leak into the never-freeing permanent arena, which is why enlarging that arena had not helped. * Frame presentation, corrected against A9 ground truth: the real frame has three default-framebuffer colour clears and ONE present at the end; this engine had been presenting on each of them. Load-time acceleration (zlib_accel.cpp): host zlib now serves inflate and crc32, the latter measured by the block profiler as the single hottest guest routine at 17.7%. Streams are only taken over when this layer saw their own inflateInit2_, so unknown streams (libpng's, among others) still run the original emulated path. name_lookup_accel.cpp is present but its hook is NOT registered - it crashed on bad assumptions about guest table lifetime and is kept as a starting point, with both mistakes recorded in its comments. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# Standalone armeabi-v7a tracing agent for the native ARM32 investigation
|
||||
# (see ARM64_TRANSLATION_LAYER.md's "Native ARM32 tracing harness" plan).
|
||||
# Deliberately NOT wired into the main Gradle build (settings.gradle.kts) -
|
||||
# this is a diagnostic-only artifact built and pushed to the device
|
||||
# independently via build.sh, never bundled into any APK. Runs exclusively
|
||||
# on the "native32" flavor's real, unmodified libapp.so on the Galaxy A9.
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
project(trace_agent)
|
||||
|
||||
add_library(trace_agent SHARED
|
||||
libc_gles_trace.cpp
|
||||
jni_trace.cpp
|
||||
)
|
||||
|
||||
# Deliberately NOT linking against libGLESv2.so here, even though the GLES
|
||||
# wrappers exist below - confirmed live on-device that an eager DT_NEEDED
|
||||
# dependency on it crashes the WHOLE process immediately on launch (exit
|
||||
# code 1, right after Zygote's early "-Xcheck:jni" specialization, well
|
||||
# before any Activity/EGL/GL context exists to make libGLESv2.so resolvable
|
||||
# that early). Each GLES wrapper already resolves its real implementation
|
||||
# lazily via dlsym(RTLD_NEXT, ...) on first real call - by then the app's
|
||||
# own GL usage has long since loaded libGLESv2.so itself, so no explicit
|
||||
# link-time dependency is needed at all. <GLES2/gl2.h> is included only for
|
||||
# its type definitions (GLenum/GLuint/...), not any function linkage.
|
||||
find_library(log-lib log)
|
||||
find_library(dl-lib dl)
|
||||
|
||||
target_link_libraries(trace_agent
|
||||
${log-lib}
|
||||
${dl-lib}
|
||||
)
|
||||
|
||||
target_compile_options(trace_agent PRIVATE -Wall -Wno-unused-parameter)
|
||||
Reference in New Issue
Block a user