From 3dd9f76ff8fa99be9ff6b18354528c5def7b26f7 Mon Sep 17 00:00:00 2001 From: Jeff Hao Date: Mon, 8 Jul 2013 13:09:25 -0700 Subject: 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 --- src/interpreter/interpreter.cc | 7 +++++++ src/jni_internal.cc | 20 ++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src') 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(jresult)); + } else if (shorty == "V") { + typedef void (fnptr)(JNIEnv*, jobject); + const fnptr* fn = reinterpret_cast(method->GetNativeMethod()); + ScopedLocalRef rcvr(soa.Env(), + soa.AddLocalReference(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(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(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, -- cgit v1.2.3-59-g8ed1b