summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter_switch_impl.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2018-10-05 23:41:16 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2018-10-05 23:41:16 +0000
commit068a9bec8d637ce907f6c2829b772a99cae60611 (patch)
treef099925c0269895935c9eea9a0caca8e8f801dce /runtime/interpreter/interpreter_switch_impl.cc
parentbc550bbbf2fcd82b5b888683a4e3708a26d0efe6 (diff)
parentf67d0cbf2743b29aa6e1be7ae2f71762b8762785 (diff)
Merge "Revert "JVMTI PopFrame support""
Diffstat (limited to 'runtime/interpreter/interpreter_switch_impl.cc')
-rw-r--r--runtime/interpreter/interpreter_switch_impl.cc118
1 files changed, 27 insertions, 91 deletions
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index cb64ff402a..04935cfe42 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -24,39 +24,16 @@
#include "interpreter_common.h"
#include "jit/jit.h"
#include "jvalue-inl.h"
-#include "nth_caller_visitor.h"
#include "safe_math.h"
#include "shadow_frame-inl.h"
-#include "thread.h"
namespace art {
namespace interpreter {
-#define CHECK_FORCE_RETURN() \
- do { \
- if (UNLIKELY(shadow_frame.GetForcePopFrame())) { \
- DCHECK(PrevFrameWillRetry(self, shadow_frame)) \
- << "Pop frame forced without previous frame ready to retry instruction!"; \
- DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); \
- if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) { \
- SendMethodExitEvents(self, \
- instrumentation, \
- shadow_frame, \
- shadow_frame.GetThisObject(accessor.InsSize()), \
- shadow_frame.GetMethod(), \
- inst->GetDexPc(insns), \
- JValue()); \
- } \
- ctx->result = JValue(); /* Handled in caller. */ \
- return; \
- } \
- } while (false)
-
#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
do { \
DCHECK(self->IsExceptionPending()); \
self->AllowThreadSuspension(); \
- CHECK_FORCE_RETURN(); \
if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
/* Structured locking is to be enforced for abnormal termination, too. */ \
DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
@@ -67,7 +44,6 @@ namespace interpreter {
ctx->result = JValue(); /* Handled in caller. */ \
return; \
} else { \
- CHECK_FORCE_RETURN(); \
int32_t displacement = \
static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
inst = inst->RelativeAt(displacement); \
@@ -76,39 +52,8 @@ namespace interpreter {
#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
-#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, _next_function) \
- do { \
- if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) { \
- /* Don't need to do anything except clear the flag and exception. We leave the */ \
- /* instruction the same so it will be re-executed on the next go-around. */ \
- DCHECK(inst->IsInvoke()); \
- shadow_frame.SetForceRetryInstruction(false); \
- if (UNLIKELY(_is_exception_pending)) { \
- DCHECK(self->IsExceptionPending()); \
- if (kIsDebugBuild) { \
- LOG(WARNING) << "Suppressing exception for instruction-retry: " \
- << self->GetException()->Dump(); \
- } \
- self->ClearException(); \
- } \
- } else if (UNLIKELY(_is_exception_pending)) { \
- /* Should have succeeded. */ \
- DCHECK(!shadow_frame.GetForceRetryInstruction()); \
- HANDLE_PENDING_EXCEPTION(); \
- } else { \
- inst = inst->_next_function(); \
- } \
- } while (false)
-
-#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(_is_exception_pending) \
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_4xx)
-#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(_is_exception_pending) \
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_3xx)
-
#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
do { \
- /* Should only be on invoke instructions. */ \
- DCHECK(!shadow_frame.GetForceRetryInstruction()); \
if (UNLIKELY(_is_exception_pending)) { \
HANDLE_PENDING_EXCEPTION(); \
} else { \
@@ -122,22 +67,17 @@ namespace interpreter {
}
// Code to run before each dex instruction.
-#define PREAMBLE_SAVE(save_ref) \
+#define PREAMBLE_SAVE(save_ref) \
{ \
- /* We need to put this before & after the instrumentation to avoid having to put in a */ \
- /* post-script macro. */ \
- CHECK_FORCE_RETURN(); \
- if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
- if (UNLIKELY(!DoDexPcMoveEvent(self, \
- accessor, \
- shadow_frame, \
- dex_pc, \
- instrumentation, \
- save_ref))) { \
- HANDLE_PENDING_EXCEPTION(); \
- break; \
- } \
- CHECK_FORCE_RETURN(); \
+ if (UNLIKELY(instrumentation->HasDexPcListeners()) && \
+ UNLIKELY(!DoDexPcMoveEvent(self, \
+ accessor, \
+ shadow_frame, \
+ dex_pc, \
+ instrumentation, \
+ save_ref))) { \
+ HANDLE_PENDING_EXCEPTION(); \
+ break; \
} \
} \
do {} while (false)
@@ -241,8 +181,7 @@ NO_INLINE static bool SendMethodExitEvents(Thread* self,
const JValue& result)
REQUIRES_SHARED(Locks::mutator_lock_) {
bool had_event = false;
- // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
- if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
+ if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
had_event = true;
instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
}
@@ -282,9 +221,6 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
uint16_t inst_data;
jit::Jit* jit = Runtime::Current()->GetJit();
- DCHECK(!shadow_frame.GetForceRetryInstruction())
- << "Entered interpreter from invoke without retry instruction being handled!";
-
do {
dex_pc = inst->GetDexPc(insns);
shadow_frame.SetDexPC(dex_pc);
@@ -1671,84 +1607,84 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
PREAMBLE();
bool success = DoInvoke<kVirtual, false, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_VIRTUAL_RANGE: {
PREAMBLE();
bool success = DoInvoke<kVirtual, true, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_SUPER: {
PREAMBLE();
bool success = DoInvoke<kSuper, false, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_SUPER_RANGE: {
PREAMBLE();
bool success = DoInvoke<kSuper, true, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_DIRECT: {
PREAMBLE();
bool success = DoInvoke<kDirect, false, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_DIRECT_RANGE: {
PREAMBLE();
bool success = DoInvoke<kDirect, true, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_INTERFACE: {
PREAMBLE();
bool success = DoInvoke<kInterface, false, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_INTERFACE_RANGE: {
PREAMBLE();
bool success = DoInvoke<kInterface, true, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_STATIC: {
PREAMBLE();
bool success = DoInvoke<kStatic, false, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_STATIC_RANGE: {
PREAMBLE();
bool success = DoInvoke<kStatic, true, do_access_check>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_VIRTUAL_QUICK: {
PREAMBLE();
bool success = DoInvokeVirtualQuick<false>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
PREAMBLE();
bool success = DoInvokeVirtualQuick<true>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_POLYMORPHIC: {
@@ -1756,7 +1692,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
bool success = DoInvokePolymorphic<false /* is_range */>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
break;
}
case Instruction::INVOKE_POLYMORPHIC_RANGE: {
@@ -1764,7 +1700,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
bool success = DoInvokePolymorphic<true /* is_range */>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
break;
}
case Instruction::INVOKE_CUSTOM: {
@@ -1772,7 +1708,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
bool success = DoInvokeCustom<false /* is_range */>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::INVOKE_CUSTOM_RANGE: {
@@ -1780,7 +1716,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
bool success = DoInvokeCustom<true /* is_range */>(
self, shadow_frame, inst, inst_data, &result_register);
- POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
+ POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
break;
}
case Instruction::NEG_INT: