diff options
-rw-r--r-- | src/interpreter/interpreter.cc | 7 | ||||
-rw-r--r-- | src/jni_internal.cc | 20 |
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, |