summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/interpreter.cc')
-rw-r--r--runtime/interpreter/interpreter.cc36
1 files changed, 32 insertions, 4 deletions
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index ec63fdf90e..3eff7fc69d 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 {
@@ -239,7 +240,7 @@ static std::ostream& operator<<(std::ostream& os, const InterpreterImplKind& rhs
}
#if !defined(__clang__)
-#if (defined(__arm__) || defined(__i386__))
+#if (defined(__arm__) || defined(__i386__) || defined(__aarch64__))
// TODO: remove when all targets implemented.
static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
#else
@@ -247,7 +248,7 @@ static constexpr InterpreterImplKind kInterpreterImplKind = kComputedGotoImplKin
#endif
#else
// Clang 3.4 fails to build the goto interpreter implementation.
-#if (defined(__arm__) || defined(__i386__))
+#if (defined(__arm__) || defined(__i386__) || defined(__aarch64__))
static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
#else
static constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImplKind;
@@ -280,6 +281,33 @@ static inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item,
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();
@@ -308,11 +336,11 @@ static inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item,
return result_register;
} else {
// Mterp didn't like that instruction. Single-step it with the reference interpreter.
- JValue res = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame,
+ result_register = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame,
result_register, true);
if (shadow_frame.GetDexPC() == DexFile::kDexNoIndex) {
// Single-stepped a return or an exception not handled locally. Return to caller.
- return res;
+ return result_register;
}
}
}