Propagate hotness counter for backup method to target to avoid crash

Fix #99

See https://5ec1cff.github.io/my-blog/2024/06/27/lsp-crash-analysis/
This commit is contained in:
LoveSy 2024-06-27 00:13:45 +08:00
parent 0d9faca38d
commit a7b0b022c2
No known key found for this signature in database
4 changed files with 65 additions and 3 deletions

View File

@ -16,8 +16,8 @@ if (LSPLANT_STANDALONE)
endif() endif()
set(SOURCES lsplant.cc) set(SOURCES lsplant.cc)
file(GLOB_RECURSE MODULE_SOURCES "*.cxx") file(GLOB_RECURSE MODULE_SOURCES CONFIGURE_DEPENDS "*.cxx")
file(GLOB_RECURSE MODULE_INTERFACES "*.ixx") file(GLOB_RECURSE MODULE_INTERFACES CONFIGURE_DEPENDS "*.ixx")
set(DEX_BUILDER_BUILD_SHARED OFF CACHE INTERNAL "" FORCE) set(DEX_BUILDER_BUILD_SHARED OFF CACHE INTERNAL "" FORCE)
add_subdirectory(external/dex_builder) add_subdirectory(external/dex_builder)

View File

@ -0,0 +1,56 @@
module;
#include "logging.hpp"
#include "utils/hook_helper.hpp"
export module jit;
import art_method;
import common;
import thread;
namespace lsplant::art::jit {
enum class CompilationKind {
kOsr [[maybe_unused]],
kBaseline [[maybe_unused]],
kOptimized,
};
export class Jit {
CREATE_MEM_HOOK_STUB_ENTRY(
"_ZN3art3jit3Jit27EnqueueOptimizedCompilationEPNS_9ArtMethodEPNS_6ThreadE", void,
EnqueueOptimizedCompilation, (Jit * thiz, ArtMethod *method, Thread *self), {
if (auto target = IsBackup(method); target) [[unlikely]] {
LOGD("Propagate enqueue compilation: %p -> %p", method, target);
method = target;
}
return backup(thiz, method, self);
});
CREATE_MEM_HOOK_STUB_ENTRY(
"_ZN3art3jit3Jit14AddCompileTaskEPNS_6ThreadEPNS_9ArtMethodENS_15CompilationKindEb", void,
AddCompileTask,
(Jit * thiz, Thread *self, ArtMethod *method, CompilationKind compilation_kind,
bool precompile),
{
if (compilation_kind == CompilationKind::kOptimized && !precompile/* && in_enqueue*/) {
if (auto backup = IsHooked(method); backup) [[unlikely]] {
LOGD("Propagate compile task: %p -> %p", method, backup);
method = backup;
}
}
return backup(thiz, self, method, compilation_kind, precompile);
});
public:
static bool Init(const HookHandler &handler) {
auto sdk_int = GetAndroidApiLevel();
if (sdk_int <= __ANDROID_API_U__) [[likely]] {
HookSyms(handler, EnqueueOptimizedCompilation);
HookSyms(handler, AddCompileTask);
}
return true;
}
};
} // namespace lsplant::art::jit

View File

@ -69,7 +69,7 @@ export {
return v + size - 1 - ((v + size - 1) & (size - 1)); return v + size - 1 - ((v + size - 1) & (size - 1));
} }
inline auto GetAndroidApiLevel() { [[gnu::const]] inline auto GetAndroidApiLevel() {
static auto kApiLevel = []() { static auto kApiLevel = []() {
std::array<char, PROP_VALUE_MAX> prop_value; std::array<char, PROP_VALUE_MAX> prop_value;
__system_property_get("ro.build.version.sdk", prop_value.data()); __system_property_get("ro.build.version.sdk", prop_value.data());

View File

@ -25,6 +25,7 @@ import scope_gc_critical_section;
import jit_code_cache; import jit_code_cache;
import jni_id_manager; import jni_id_manager;
import dex_file; import dex_file;
import jit;
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wunknown-pragmas"
@ -42,6 +43,7 @@ using art::Runtime;
using art::Thread; using art::Thread;
using art::gc::ScopedGCCriticalSection; using art::gc::ScopedGCCriticalSection;
using art::jit::JitCodeCache; using art::jit::JitCodeCache;
using art::jit::Jit;
using art::jni::JniIdManager; using art::jni::JniIdManager;
using art::mirror::Class; using art::mirror::Class;
using art::thread_list::ScopedSuspendAll; using art::thread_list::ScopedSuspendAll;
@ -286,6 +288,10 @@ bool InitNative(JNIEnv *env, const HookHandler &handler) {
LOGE("Failed to init jit code cache"); LOGE("Failed to init jit code cache");
return false; return false;
} }
if (!Jit::Init(handler)) {
LOGE("Failed to init jit");
return false;
}
if (!DexFile::Init(env, handler)) { if (!DexFile::Init(env, handler)) {
LOGE("Failed to init dex file"); LOGE("Failed to init dex file");
return false; return false;