Switch -Xjnitrace over to using a custom JNI bridge.
This now works without needing to specify -Xint:portable, and no longer needs
to be manually enabled at compile-time.
If you're using -Xjnitrace, you'll pay to look up the real JNI bridge on every
invocation of a native method, but doing so leads to a really simple
implementation, and you're writing to the log on every invocation anyway, so
-Xjnitrace and performance don't go together anyway.
Bug: 2846017
Change-Id: I3108c4f35f27b72e8849c41077ae3e8768550e96
diff --git a/vm/Dvm.mk b/vm/Dvm.mk
index ba580d0..8626375 100644
--- a/vm/Dvm.mk
+++ b/vm/Dvm.mk
@@ -32,7 +32,6 @@
# Optional features. These may impact the size or performance of the VM.
#
LOCAL_CFLAGS += -DWITH_PROFILER -DWITH_DEBUGGER
-#LOCAL_CFLAGS += -DWITH_JNI_TRACE
# 0=full cache, 1/2=reduced, 3=no cache
LOCAL_CFLAGS += -DDVM_RESOLVER_CACHE=0
diff --git a/vm/Init.c b/vm/Init.c
index d73bec7..06ceabc 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -111,9 +111,7 @@
dvmFprintf(stderr,
" -Xjnigreflimit:N (must be multiple of 100, >= 200)\n");
dvmFprintf(stderr, " -Xjniopts:{warnonly,forcecopy}\n");
-#if defined(WITH_JNI_TRACE)
dvmFprintf(stderr, " -Xjnitrace:substring (eg NativeClass or nativeMethod)\n");
-#endif
dvmFprintf(stderr, " -Xdeadlockpredict:{off,warn,err,abort}\n");
dvmFprintf(stderr, " -Xstacktracefile:<filename>\n");
dvmFprintf(stderr, " -Xgc:[no]precise\n");
@@ -179,9 +177,6 @@
#ifdef WITH_JNI_STACK_CHECK
" jni_stack_check"
#endif
-#ifdef WITH_JNI_TRACE
- " jni_trace"
-#endif
#ifdef EASY_GDB
" easy_gdb"
#endif
@@ -891,12 +886,8 @@
return -1;
}
gDvm.jniGrefLimit = lim;
-
-#if defined(WITH_JNI_TRACE)
} else if (strncmp(argv[i], "-Xjnitrace:", 11) == 0) {
gDvm.jniTrace = strdup(argv[i] + 11);
-#endif
-
} else if (strcmp(argv[i], "-Xlog-stdio") == 0) {
gDvm.logStdio = true;
diff --git a/vm/Jni.c b/vm/Jni.c
index 77aeb69..8967f46 100644
--- a/vm/Jni.c
+++ b/vm/Jni.c
@@ -1333,10 +1333,10 @@
}
/*
- * Point "method->nativeFunc" at the JNI bridge, and overload "method->insns"
- * to point at the actual function.
+ * Returns the appropriate JNI bridge for 'method', also taking into account
+ * the -Xcheck:jni setting.
*/
-void dvmUseJNIBridge(Method* method, void* func)
+static DalvikBridgeFunc dvmSelectJNIBridge(const Method* method)
{
enum {
kJNIGeneral = 0,
@@ -1388,11 +1388,39 @@
}
}
- if (dvmIsCheckJNIEnabled()) {
- dvmSetNativeFunc(method, checkFunc[kind], func);
- } else {
- dvmSetNativeFunc(method, stdFunc[kind], func);
- }
+ return dvmIsCheckJNIEnabled() ? checkFunc[kind] : stdFunc[kind];
+}
+
+/*
+ * Trace a call into native code.
+ */
+static void dvmTraceCallJNIMethod(const u4* args, JValue* pResult,
+ const Method* method, Thread* self)
+{
+ dvmLogNativeMethodEntry(method, args);
+ DalvikBridgeFunc bridge = dvmSelectJNIBridge(method);
+ (*bridge)(args, pResult, method, self);
+ dvmLogNativeMethodExit(method, self, *pResult);
+}
+
+/**
+ * Returns true if the -Xjnitrace setting implies we should trace 'method'.
+ */
+static bool shouldTrace(Method* method)
+{
+ return gDvm.jniTrace && strstr(method->clazz->descriptor, gDvm.jniTrace);
+}
+
+/*
+ * Point "method->nativeFunc" at the JNI bridge, and overload "method->insns"
+ * to point at the actual function.
+ */
+void dvmUseJNIBridge(Method* method, void* func)
+{
+ DalvikBridgeFunc bridge = shouldTrace(method)
+ ? dvmTraceCallJNIMethod
+ : dvmSelectJNIBridge(method);
+ dvmSetNativeFunc(method, bridge, func);
}
/*
diff --git a/vm/Native.c b/vm/Native.c
index a641c25..4793ab3 100644
--- a/vm/Native.c
+++ b/vm/Native.c
@@ -943,10 +943,10 @@
#define LOGI_NATIVE(...) LOG(LOG_INFO, LOG_TAG "-native", __VA_ARGS__)
-void dvmLogNativeMethodEntry(const Method* method, u4* fp)
+void dvmLogNativeMethodEntry(const Method* method, const u4* args)
{
char thisString[32] = { 0 };
- u4* sp = &fp[method->registersSize - method->insSize];
+ const u4* sp = args; // &args[method->registersSize - method->insSize];
if (!dvmIsStaticMethod(method)) {
sprintf(thisString, "this=0x%08x ", *sp++);
}
diff --git a/vm/Native.h b/vm/Native.h
index 5739647..a5e9ca1 100644
--- a/vm/Native.h
+++ b/vm/Native.h
@@ -114,7 +114,7 @@
* Used to implement -Xjnitrace.
*/
struct Thread;
-void dvmLogNativeMethodEntry(const Method* method, u4* newFp);
+void dvmLogNativeMethodEntry(const Method* method, const u4* newFp);
void dvmLogNativeMethodExit(const Method* method, struct Thread* self,
const JValue retval);
diff --git a/vm/mterp/c/gotoTargets.c b/vm/mterp/c/gotoTargets.c
index 589f974..842171d 100644
--- a/vm/mterp/c/gotoTargets.c
+++ b/vm/mterp/c/gotoTargets.c
@@ -917,14 +917,6 @@
TRACE_METHOD_ENTER(self, methodToCall);
#endif
-#if defined(WITH_JNI_TRACE)
- bool trace = gDvm.jniTrace &&
- strstr(methodToCall->clazz->descriptor, gDvm.jniTrace);
- if (trace) {
- dvmLogNativeMethodEntry(methodToCall, newFp);
- }
- else
-#endif
{
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
@@ -956,12 +948,6 @@
dvmPopJniLocals(self, newSaveArea);
self->curFrame = fp;
-#if defined(WITH_JNI_TRACE)
- if (trace) {
- dvmLogNativeMethodExit(methodToCall, self, retval);
- }
-#endif
-
/*
* If the native code threw an exception, or interpreted code
* invoked by the native call threw one and nobody has cleared
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 8f7f4ec..4a7a5a9 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -4051,14 +4051,6 @@
TRACE_METHOD_ENTER(self, methodToCall);
#endif
-#if defined(WITH_JNI_TRACE)
- bool trace = gDvm.jniTrace &&
- strstr(methodToCall->clazz->descriptor, gDvm.jniTrace);
- if (trace) {
- dvmLogNativeMethodEntry(methodToCall, newFp);
- }
- else
-#endif
{
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
@@ -4090,12 +4082,6 @@
dvmPopJniLocals(self, newSaveArea);
self->curFrame = fp;
-#if defined(WITH_JNI_TRACE)
- if (trace) {
- dvmLogNativeMethodExit(methodToCall, self, retval);
- }
-#endif
-
/*
* If the native code threw an exception, or interpreted code
* invoked by the native call threw one and nobody has cleared
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 92b97b0..44916fb 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -4335,14 +4335,6 @@
TRACE_METHOD_ENTER(self, methodToCall);
#endif
-#if defined(WITH_JNI_TRACE)
- bool trace = gDvm.jniTrace &&
- strstr(methodToCall->clazz->descriptor, gDvm.jniTrace);
- if (trace) {
- dvmLogNativeMethodEntry(methodToCall, newFp);
- }
- else
-#endif
{
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
@@ -4374,12 +4366,6 @@
dvmPopJniLocals(self, newSaveArea);
self->curFrame = fp;
-#if defined(WITH_JNI_TRACE)
- if (trace) {
- dvmLogNativeMethodExit(methodToCall, self, retval);
- }
-#endif
-
/*
* If the native code threw an exception, or interpreted code
* invoked by the native call threw one and nobody has cleared
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index 9be8a8e..e863abe 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -4074,14 +4074,6 @@
TRACE_METHOD_ENTER(self, methodToCall);
#endif
-#if defined(WITH_JNI_TRACE)
- bool trace = gDvm.jniTrace &&
- strstr(methodToCall->clazz->descriptor, gDvm.jniTrace);
- if (trace) {
- dvmLogNativeMethodEntry(methodToCall, newFp);
- }
- else
-#endif
{
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
@@ -4113,12 +4105,6 @@
dvmPopJniLocals(self, newSaveArea);
self->curFrame = fp;
-#if defined(WITH_JNI_TRACE)
- if (trace) {
- dvmLogNativeMethodExit(methodToCall, self, retval);
- }
-#endif
-
/*
* If the native code threw an exception, or interpreted code
* invoked by the native call threw one and nobody has cleared
diff --git a/vm/mterp/out/InterpC-x86-atom.c b/vm/mterp/out/InterpC-x86-atom.c
index 13d05cc..46e25b0 100644
--- a/vm/mterp/out/InterpC-x86-atom.c
+++ b/vm/mterp/out/InterpC-x86-atom.c
@@ -2245,14 +2245,6 @@
TRACE_METHOD_ENTER(self, methodToCall);
#endif
-#if defined(WITH_JNI_TRACE)
- bool trace = gDvm.jniTrace &&
- strstr(methodToCall->clazz->descriptor, gDvm.jniTrace);
- if (trace) {
- dvmLogNativeMethodEntry(methodToCall, newFp);
- }
- else
-#endif
{
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
@@ -2284,12 +2276,6 @@
dvmPopJniLocals(self, newSaveArea);
self->curFrame = fp;
-#if defined(WITH_JNI_TRACE)
- if (trace) {
- dvmLogNativeMethodExit(methodToCall, self, retval);
- }
-#endif
-
/*
* If the native code threw an exception, or interpreted code
* invoked by the native call threw one and nobody has cleared
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index 1ce0302..6fc1ce1 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -2182,14 +2182,6 @@
TRACE_METHOD_ENTER(self, methodToCall);
#endif
-#if defined(WITH_JNI_TRACE)
- bool trace = gDvm.jniTrace &&
- strstr(methodToCall->clazz->descriptor, gDvm.jniTrace);
- if (trace) {
- dvmLogNativeMethodEntry(methodToCall, newFp);
- }
- else
-#endif
{
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
@@ -2221,12 +2213,6 @@
dvmPopJniLocals(self, newSaveArea);
self->curFrame = fp;
-#if defined(WITH_JNI_TRACE)
- if (trace) {
- dvmLogNativeMethodExit(methodToCall, self, retval);
- }
-#endif
-
/*
* If the native code threw an exception, or interpreted code
* invoked by the native call threw one and nobody has cleared