Skip to content

Commit

Permalink
Add interface to deopt method (LSPosed#1124)
Browse files Browse the repository at this point in the history
Co-authored-by: 残页 <[email protected]>
Co-authored-by: Wang Han <[email protected]>
  • Loading branch information
3 people authored Sep 17, 2021
1 parent 8ae4738 commit 42e8573
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
10 changes: 1 addition & 9 deletions core/src/main/cpp/main/src/jni/art_class_linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,10 @@
#include "art_class_linker.h"

namespace lspd {

static std::unordered_set<void *> deopted_methods;

LSP_DEF_NATIVE_METHOD(void, ClassLinker, setEntryPointsToInterpreter, jobject method) {
void *reflected_method = yahfa::getArtMethod(env, method);
if (deopted_methods.contains(reflected_method)) {
LOGD("method %p has been deopted before, skip...", reflected_method);
return;
}
LOGD("deoptimizing method: %p", reflected_method);
art::ClassLinker::Current()->SetEntryPointsToInterpreter(reflected_method);
deopted_methods.insert(reflected_method);
LOGD("method deoptimized: %p", reflected_method);
}

Expand All @@ -51,4 +43,4 @@ namespace lspd {
REGISTER_LSP_NATIVE_METHODS(ClassLinker);
}

}
} // namespace lspd
18 changes: 18 additions & 0 deletions core/src/main/java/de/robv/android/xposed/XposedBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -147,6 +148,23 @@ public synchronized static void log(Throwable t) {
Log.e(TAG, logStr);
}

/**
* Deoptimize a method to avoid callee being inlined.
*
* @param deoptimizedMethod The method to deoptmize. Generally it should be a caller of a method
* that is inlined.
*/
public static void deoptimizeMethod(Member deoptimizedMethod) {
if (!(deoptimizedMethod instanceof Executable)) {
throw new IllegalArgumentException("Only methods and constructors can be deoptimized: " + deoptimizedMethod.toString());
} else if (Modifier.isAbstract(deoptimizedMethod.getModifiers())) {
throw new IllegalArgumentException("Cannot deoptimize abstract methods: " + deoptimizedMethod);
} else if (Proxy.isProxyClass(deoptimizedMethod.getDeclaringClass())) {
throw new IllegalArgumentException("Cannot deoptimize methods from proxy class: " + deoptimizedMethod);
}
YahfaHooker.deoptMethodNative((Executable) deoptimizedMethod);
}

/**
* Hook any method (or constructor) with the specified callback. See below for some wrappers
* that make it easier to find a method/constructor in one step.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static synchronized void hookMethod(Executable hookMethod, XposedBridge.A
Utils.logD("hooking " + hookMethod);

if (hookedInfo.containsKey(hookMethod)) {
Utils.logW("already hook method:" + hookMethod);
Utils.logW("already hook method:" + hookMethod, new IllegalStateException());
return;
}

Expand Down

0 comments on commit 42e8573

Please sign in to comment.