summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Hao <jeffhao@google.com> 2013-07-08 13:09:25 -0700
committer Jeff Hao <jeffhao@google.com> 2013-07-08 13:24:53 -0700
commit3dd9f76ff8fa99be9ff6b18354528c5def7b26f7 (patch)
tree12803784ef0801e7962812370dadea9fd17e8768
parent9dacec7d3ec1f9b6efdb61fd494f0192c85183bf (diff)
Interpret methods invoked via JNI in interpreter only mode.
This fixes the issue of Dhrystone having the same performance in interpreter only mode. Main was executing compiled code since it uses CallStaticVoidMethod directly. Now a check for interpreter only mode in InvokeWithArgArray redirects it to the interpreter. Change-Id: If6e6d8ede5cd0d8ad687d161667056373b1b031c
-rw-r--r--src/interpreter/interpreter.cc7
-rw-r--r--src/jni_internal.cc20
2 files changed, 25 insertions, 2 deletions
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 21725dee72..a89fb113c3 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -348,6 +348,13 @@ static void InterpreterJni(Thread* self, AbstractMethod* method, StringPiece sho
jresult = fn(soa.Env(), rcvr.get());
}
result->SetL(soa.Decode<Object*>(jresult));
+ } else if (shorty == "V") {
+ typedef void (fnptr)(JNIEnv*, jobject);
+ const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod());
+ ScopedLocalRef<jobject> rcvr(soa.Env(),
+ soa.AddLocalReference<jobject>(receiver));
+ ScopedThreadStateChange tsc(self, kNative);
+ fn(soa.Env(), rcvr.get());
} else if (shorty == "LL") {
typedef jobject (fnptr)(JNIEnv*, jobject, jobject);
const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod());
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 50b28b8d7e..5ea1f77172 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -29,6 +29,7 @@
#include "class_linker.h"
#include "dex_file-inl.h"
#include "gc/accounting/card_table-inl.h"
+#include "interpreter/interpreter.h"
#include "invoke_arg_array_builder.h"
#include "jni.h"
#include "mirror/class-inl.h"
@@ -130,10 +131,25 @@ static void CheckMethodArguments(AbstractMethod* m, uint32_t* args)
void InvokeWithArgArray(const ScopedObjectAccess& soa, AbstractMethod* method,
ArgArray* arg_array, JValue* result, char result_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ uint32_t* args = arg_array->GetArray();
if (UNLIKELY(soa.Env()->check_jni)) {
- CheckMethodArguments(method, arg_array->GetArray());
+ CheckMethodArguments(method, args);
+ }
+ // Check interpreter only mode for methods invoked through JNI.
+ // TODO: Check that this catches all remaining paths to invoke.
+ // TODO: Move check up a level to avoid building arg array and then shadow frame?
+ if (Runtime::Current()->GetInstrumentation()->InterpretOnly()) {
+ Object* receiver = method->IsStatic() ? NULL : reinterpret_cast<Object*>(args[0]);
+ if (!method->IsStatic()) {
+ args++;
+ }
+ ManagedStack fragment;
+ soa.Self()->PushManagedStackFragment(&fragment);
+ art::interpreter::EnterInterpreterFromInvoke(soa.Self(), method, receiver, args, result);
+ soa.Self()->PopManagedStackFragment(fragment);
+ } else {
+ method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type);
}
- method->Invoke(soa.Self(), arg_array->GetArray(), arg_array->GetNumBytes(), result, result_type);
}
static JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj,