summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,