From 62fb91a4693ee19266efd80f7d8007c82ac1c55a Mon Sep 17 00:00:00 2001 From: LoveSy Date: Fri, 29 Jan 2021 16:07:12 +0800 Subject: [PATCH] Optimize record pending --- .../src/main/cpp/main/include/art/runtime/class_linker.h | 2 +- core/src/main/cpp/main/src/jni/pending_hooks.cpp | 9 +++++++-- core/src/main/cpp/main/src/jni/pending_hooks.h | 2 ++ .../main/java/de/robv/android/xposed/PendingHooks.java | 5 +++-- .../main/java/de/robv/android/xposed/XposedBridge.java | 2 +- .../java/io/github/lsposed/lspd/util/ClassUtils.java | 4 ++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/core/src/main/cpp/main/include/art/runtime/class_linker.h b/core/src/main/cpp/main/include/art/runtime/class_linker.h index 1bdcb561..e06eb49b 100644 --- a/core/src/main/cpp/main/include/art/runtime/class_linker.h +++ b/core/src/main/cpp/main/include/art/runtime/class_linker.h @@ -65,7 +65,7 @@ namespace art { "_ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv", bool, ShouldUseInterpreterEntrypoint, (void * art_method, const void *quick_code), { - if (quick_code != nullptr && UNLIKELY(lspd::isHooked(art_method))) { + if (quick_code != nullptr && UNLIKELY(lspd::isHooked(art_method) || lspd::IsMethodPending(art_method))) { return false; } return backup(art_method, quick_code); diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.cpp b/core/src/main/cpp/main/src/jni/pending_hooks.cpp index e45b2844..76e8b16d 100644 --- a/core/src/main/cpp/main/src/jni/pending_hooks.cpp +++ b/core/src/main/cpp/main/src/jni/pending_hooks.cpp @@ -12,6 +12,7 @@ namespace lspd { namespace { std::unordered_set pending_classes_; + std::unordered_set pending_methods_; std::unordered_set hooked_methods_; } @@ -20,6 +21,10 @@ namespace lspd { return pending_classes_.count(clazz); } + bool IsMethodPending(void* art_method) { + return pending_methods_.erase(art_method) > 0; + } + void DonePendingHook(void *clazz) { pending_classes_.erase(clazz); } @@ -31,7 +36,7 @@ namespace lspd { if (auto def = mirror_class.GetClassDef(); LIKELY(def)) { LOGD("record pending: %p (%s) with %p", class_ptr, mirror_class.GetDescriptor().c_str(), method); // Add it for ShouldUseInterpreterEntrypoint - recordHooked(method); + pending_methods_.insert(method); pending_classes_.insert(def); } else { LOGW("fail to record pending for : %p (%s)", class_ptr, @@ -40,7 +45,7 @@ namespace lspd { } static JNINativeMethod gMethods[] = { - NATIVE_METHOD(PendingHooks, recordPendingMethodNative, "(Ljava/lang/reflect/Member;Ljava/lang/Class;)V"), + NATIVE_METHOD(PendingHooks, recordPendingMethodNative, "(Ljava/lang/reflect/Method;Ljava/lang/Class;)V"), }; void RegisterPendingHooks(JNIEnv *env) { diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.h b/core/src/main/cpp/main/src/jni/pending_hooks.h index 9fe2ae49..f3824698 100644 --- a/core/src/main/cpp/main/src/jni/pending_hooks.h +++ b/core/src/main/cpp/main/src/jni/pending_hooks.h @@ -15,4 +15,6 @@ namespace lspd { void DonePendingHook(void *clazz); + bool IsMethodPending(void* art_method); + } // namespace lspd diff --git a/core/src/main/java/de/robv/android/xposed/PendingHooks.java b/core/src/main/java/de/robv/android/xposed/PendingHooks.java index b2e83516..a49dfdb5 100644 --- a/core/src/main/java/de/robv/android/xposed/PendingHooks.java +++ b/core/src/main/java/de/robv/android/xposed/PendingHooks.java @@ -1,6 +1,7 @@ package de.robv.android.xposed; import java.lang.reflect.Member; +import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -22,7 +23,7 @@ public final class PendingHooks { } } - public synchronized static void recordPendingMethod(Member hookMethod, + public synchronized static void recordPendingMethod(Method hookMethod, XposedBridge.AdditionalHookInfo additionalInfo) { ConcurrentHashMap pending = sPendingHooks.computeIfAbsent(hookMethod.getDeclaringClass(), @@ -41,5 +42,5 @@ public final class PendingHooks { sPendingHooks.clear(); } - private static native void recordPendingMethodNative(Member hookMethod, Class clazz); + private static native void recordPendingMethodNative(Method hookMethod, Class clazz); } diff --git a/core/src/main/java/de/robv/android/xposed/XposedBridge.java b/core/src/main/java/de/robv/android/xposed/XposedBridge.java index d2bf4020..bc07c705 100644 --- a/core/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/core/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -241,7 +241,7 @@ public final class XposedBridge { if (reflectMethod != null) { hookMethodNative(reflectMethod, declaringClass, slot, additionalInfo); } else { - PendingHooks.recordPendingMethod(hookMethod, additionalInfo); + PendingHooks.recordPendingMethod((Method)hookMethod, additionalInfo); } } diff --git a/core/src/main/java/io/github/lsposed/lspd/util/ClassUtils.java b/core/src/main/java/io/github/lsposed/lspd/util/ClassUtils.java index aa0bac18..f6083dec 100644 --- a/core/src/main/java/io/github/lsposed/lspd/util/ClassUtils.java +++ b/core/src/main/java/io/github/lsposed/lspd/util/ClassUtils.java @@ -2,8 +2,8 @@ package io.github.lsposed.lspd.util; import android.os.Build; -import java.lang.reflect.Constructor; import java.lang.reflect.Member; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import de.robv.android.xposed.XposedHelpers; @@ -46,7 +46,7 @@ public class ClassUtils { } public static boolean shouldDelayHook(Member hookMethod) { - if (hookMethod == null || hookMethod instanceof Constructor) { + if (!(hookMethod instanceof Method)) { return false; } Class declaringClass = hookMethod.getDeclaringClass();