diff options
author | 2013-07-08 13:09:25 -0700 | |
---|---|---|
committer | 2013-07-08 13:24:53 -0700 | |
commit | 3dd9f76ff8fa99be9ff6b18354528c5def7b26f7 (patch) | |
tree | 12803784ef0801e7962812370dadea9fd17e8768 | |
parent | 9dacec7d3ec1f9b6efdb61fd494f0192c85183bf (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.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, |