# 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
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");
#ifdef WITH_JNI_STACK_CHECK
" jni_stack_check"
#endif
-#ifdef WITH_JNI_TRACE
- " jni_trace"
-#endif
#ifdef EASY_GDB
" easy_gdb"
#endif
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;
}
/*
- * 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,
}
}
- 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);
}
/*
#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++);
}
* 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);
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);
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
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);
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
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);
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
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);
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
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);
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
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);
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