Code cleanup around exception handling and stack walking.
- Remove unused code setting the method and dex pc below an upcall.
- Clear cur_oat_quick_method_header when stack walking to be consistent
in having a runtime method and a null oat method header.
Test: test.py
Change-Id: I87672d193eb2e62add3ae7b8a42f2202e8eb927c
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index bd69aa4..90732e1 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -53,7 +53,6 @@
handler_quick_frame_pc_(0),
handler_method_header_(nullptr),
handler_quick_arg0_(0),
- handler_method_(nullptr),
handler_dex_pc_(0),
clear_exception_(false),
handler_frame_depth_(kInvalidFrameDepth),
@@ -83,19 +82,6 @@
// This is the upcall, we remember the frame and last pc so that we may long jump to them.
exception_handler_->SetHandlerQuickFramePc(GetCurrentQuickFramePc());
exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame());
- exception_handler_->SetHandlerMethodHeader(GetCurrentOatQuickMethodHeader());
- uint32_t next_dex_pc;
- ArtMethod* next_art_method;
- bool has_next = GetNextMethodAndDexPc(&next_art_method, &next_dex_pc);
- // Report the method that did the down call as the handler.
- exception_handler_->SetHandlerDexPc(next_dex_pc);
- exception_handler_->SetHandlerMethod(next_art_method);
- if (!has_next) {
- // No next method? Check exception handler is set up for the unhandled exception handler
- // case.
- DCHECK_EQ(0U, exception_handler_->GetHandlerDexPc());
- DCHECK(nullptr == exception_handler_->GetHandlerMethod());
- }
return false; // End stack walk.
}
if (skip_frames_ != 0) {
@@ -124,7 +110,6 @@
uint32_t found_dex_pc = method->FindCatchBlock(to_find, dex_pc, &clear_exception);
exception_handler_->SetClearException(clear_exception);
if (found_dex_pc != dex::kDexNoIndex) {
- exception_handler_->SetHandlerMethod(method);
exception_handler_->SetHandlerDexPc(found_dex_pc);
exception_handler_->SetHandlerQuickFramePc(
GetCurrentOatQuickMethodHeader()->ToNativeQuickPc(
@@ -192,10 +177,11 @@
if (*handler_quick_frame_ == nullptr) {
LOG(INFO) << "Handler is upcall";
}
- if (handler_method_ != nullptr) {
- const DexFile* dex_file = handler_method_->GetDexFile();
- int line_number = annotations::GetLineNumFromPC(dex_file, handler_method_, handler_dex_pc_);
- LOG(INFO) << "Handler: " << handler_method_->PrettyMethod() << " (line: "
+ if (GetHandlerMethod() != nullptr) {
+ const DexFile* dex_file = GetHandlerMethod()->GetDexFile();
+ int line_number =
+ annotations::GetLineNumFromPC(dex_file, GetHandlerMethod(), handler_dex_pc_);
+ LOG(INFO) << "Handler: " << GetHandlerMethod()->PrettyMethod() << " (line: "
<< line_number << ")";
}
}
@@ -251,13 +237,13 @@
void QuickExceptionHandler::SetCatchEnvironmentForOptimizedHandler(StackVisitor* stack_visitor) {
DCHECK(!is_deoptimization_);
DCHECK(*handler_quick_frame_ != nullptr) << "Method should not be called on upcall exceptions";
- DCHECK(handler_method_ != nullptr && handler_method_header_->IsOptimized());
+ DCHECK(GetHandlerMethod() != nullptr && handler_method_header_->IsOptimized());
if (kDebugExceptionDelivery) {
self_->DumpStack(LOG_STREAM(INFO) << "Setting catch phis: ");
}
- CodeItemDataAccessor accessor(handler_method_->DexInstructionData());
+ CodeItemDataAccessor accessor(GetHandlerMethod()->DexInstructionData());
const size_t number_of_vregs = accessor.RegistersSize();
CodeInfo code_info(handler_method_header_);
@@ -659,11 +645,11 @@
if (smash_caller_saves) {
context_->SmashCallerSaves();
}
- if (handler_method_ != nullptr &&
+ if (!is_deoptimization_ &&
handler_method_header_ != nullptr &&
handler_method_header_->IsNterpMethodHeader()) {
context_->SetNterpDexPC(reinterpret_cast<uintptr_t>(
- handler_method_->DexInstructions().Insns() + handler_dex_pc_));
+ GetHandlerMethod()->DexInstructions().Insns() + handler_dex_pc_));
}
context_->DoLongJump();
UNREACHABLE();
diff --git a/runtime/quick_exception_handler.h b/runtime/quick_exception_handler.h
index 5579d36..4ff981d 100644
--- a/runtime/quick_exception_handler.h
+++ b/runtime/quick_exception_handler.h
@@ -99,11 +99,7 @@
}
ArtMethod* GetHandlerMethod() const {
- return handler_method_;
- }
-
- void SetHandlerMethod(ArtMethod* handler_quick_method) {
- handler_method_ = handler_quick_method;
+ return *handler_quick_frame_;
}
uint32_t GetHandlerDexPc() const {
@@ -154,8 +150,6 @@
const OatQuickMethodHeader* handler_method_header_;
// The value for argument 0.
uintptr_t handler_quick_arg0_;
- // The handler method to report to the debugger.
- ArtMethod* handler_method_;
// The handler's dex PC, zero implies an uncaught exception.
uint32_t handler_dex_pc_;
// Should the exception be cleared as the catch block has no move-exception?
diff --git a/runtime/stack.cc b/runtime/stack.cc
index a4ce99b..336b253 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -858,7 +858,7 @@
cur_shadow_frame_ = current_fragment->GetTopShadowFrame();
cur_quick_frame_ = current_fragment->GetTopQuickFrame();
cur_quick_frame_pc_ = 0;
- cur_oat_quick_method_header_ = nullptr;
+ DCHECK(cur_oat_quick_method_header_ == nullptr);
if (cur_quick_frame_ != nullptr) { // Handle quick stack frames.
// Can't be both a shadow and a quick fragment.
DCHECK(current_fragment->GetTopShadowFrame() == nullptr);
@@ -995,6 +995,8 @@
}
method = *cur_quick_frame_;
}
+ // We reached a transition frame, it doesn't have a method header.
+ cur_oat_quick_method_header_ = nullptr;
} else if (cur_shadow_frame_ != nullptr) {
do {
SanityCheckFrame();