Task #58 asked whether the engine induces the __dynamic_cast flood or the game does. A native LD_PRELOAD interposer added to trace_agent answers it: native ARM32 on the A9 calls it up to 824,200/sec, against this engine's 284,986/sec. The game is simply that RTTI-heavy, and native absorbs it because a real call costs tens of nanoseconds. Our rate is not demand, it is supply - the shim boundary is throttling the guest. (Interposing __dynamic_cast collides with libc++abi.a, which the NDK links statically into the agent; resolved with --allow-multiple-definition scoped to that target, since our object precedes the archive and wins.) That makes a guest-side implementation interesting: Shim_dynamic_cast is already a pure guest-memory walk - it reads the object's vtable, vtable[-1] (dynamic type) and vtable[-2] (offset-to-top), then compares type_info records. Nothing comes from the host, so the same algorithm could run as emulated ARM32 with NO boundary crossing at all. Whether that is worth doing depends on how big it would have to be, so this adds a temporary shape survey. Measured over a prologue load, 2.7M calls: exact (depth 0) 84.2% one base 0.4% deeper 0.0% (max depth reached all run: 3) not found 15.4% 84% of calls need NO hierarchy walk - the object's dynamic type already IS the target. A guest fast path of roughly six instructions (load vtable, compare vtable[-1] to the target, return ptr + vtable[-2]) with a fallback to this shim would eliminate 84% of dynamic_cast crossings, which is ~41% of ALL shim crossings given dynamic_cast is 49% of them. Also confirms there is no implementation to reuse inside libapp.so: not only __dynamic_cast but the type_info vtables themselves (__class_type_info, __si_class_type_info, __vmi_class_type_info, __pointer_type_info) are all UND - this engine supplies them from rtti_shims.cpp. Survey left in the tree behind kSurveyDynamicCast, default off. Co-Authored-By: Claude <noreply@anthropic.com>
42 lines
2.0 KiB
CMake
42 lines
2.0 KiB
CMake
# 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)
|
|
|
|
# __dynamic_cast is also defined in libc++abi.a, which the NDK links
|
|
# statically into this agent. Interposing it (task #58 - counting the real
|
|
# call rate on native hardware) therefore produces a duplicate-symbol link
|
|
# error. Our definition comes from this target's own objects, which the
|
|
# linker sees before the archive, so it wins; the archive copy is simply
|
|
# left unused. Scoped to this target rather than set globally.
|
|
target_link_options(trace_agent PRIVATE "-Wl,--allow-multiple-definition")
|