Fix "Never Interpret" option for all interpreters
CL 196596 added support for an option to bypass interpretation.
However, it only covers 2 our of 3 interpreters (missing mterp).
This change moves the control up a level to the common interpreter
entry where it will take effect before we select which interpreter
to use.
Also, it corrects a somewhat academic bug in that the existing
code that assumes that (dex_pc == 0) means that we just entered a
method. If a method's dex code internally branched to address 0,
we could issue bogus method entry events. By moving this test up
a level, we should avoid this situation. Note, though, that dx
would never generate this pattern, and it's hard to imagine even
hand-generated dex code that would trigger a deoptimization in this
situation.
Change-Id: I6684bbf63570e02f5b01ce423c656889a890de7d
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index ec63fdf..dca792c 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -26,6 +26,7 @@
#include "stack.h"
#include "unstarted_runtime.h"
#include "mterp/mterp.h"
+#include "jit/jit.h"
namespace art {
namespace interpreter {
@@ -280,6 +281,33 @@
ShadowFrame& shadow_frame, JValue result_register) {
DCHECK(!shadow_frame.GetMethod()->IsAbstract());
DCHECK(!shadow_frame.GetMethod()->IsNative());
+ if (LIKELY(shadow_frame.GetDexPC() == 0)) { // Entering the method, but not via deoptimization.
+ if (kIsDebugBuild) {
+ self->AssertNoPendingException();
+ }
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ ArtMethod *method = shadow_frame.GetMethod();
+
+ if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
+ instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ method, 0);
+ }
+
+ if (UNLIKELY(Runtime::Current()->GetJit() != nullptr &&
+ Runtime::Current()->GetJit()->JitAtFirstUse() &&
+ method->HasAnyCompiledCode())) {
+ JValue result;
+
+ // Pop the shadow frame before calling into compiled code.
+ self->PopShadowFrame();
+ ArtInterpreterToCompiledCodeBridge(self, code_item, &shadow_frame, &result);
+ // Push the shadow frame back as the caller will expect it.
+ self->PushShadowFrame(&shadow_frame);
+
+ return result;
+ }
+ }
+
shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
bool transaction_active = Runtime::Current()->IsActiveTransaction();