Revert "ART: Remove VERIFY_ERROR_UNRESOLVED_CATCH"
This reverts commit 7a82acc7ee79b198f7b4638a15cb1c3d1625ab6c.
Reason for revert: NO_CLASS doesn't have the right semantics for the compiler
Bug: 121245951
Change-Id: I8dbeb7fbd6a697fe536535f1c696187041d7fcab
Test: m test-art-host
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 8396fe9..b644dba 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3829,13 +3829,12 @@
// We need to post a failure. The compiler currently does not handle unreachable
// code correctly.
- Fail(VERIFY_ERROR_NO_CLASS, /*pending_exc=*/ false)
- << "Unresolved catch handler, fail for compiler";
+ Fail(VERIFY_ERROR_UNRESOLVED_CATCH) << "Unresolved catch handler, fail for compiler";
return std::make_pair(false, unresolved);
}
// Soft-fail, but do not handle this with a synthetic throw.
- Fail(VERIFY_ERROR_NO_CLASS, /*pending_exc=*/ false) << "Unresolved catch handler";
+ Fail(VERIFY_ERROR_UNRESOLVED_CATCH) << "Unresolved catch handler";
if (common_super != nullptr) {
unresolved = &unresolved->Merge(*common_super, ®_types_, this);
}
@@ -5514,72 +5513,70 @@
reg_types_.VisitRoots(visitor, root_info);
}
-std::ostream& MethodVerifier::Fail(VerifyError error, bool pending_exc) {
+std::ostream& MethodVerifier::Fail(VerifyError error) {
// Mark the error type as encountered.
encountered_failure_types_ |= static_cast<uint32_t>(error);
- if (pending_exc) {
- switch (error) {
- case VERIFY_ERROR_NO_CLASS:
- case VERIFY_ERROR_NO_FIELD:
- case VERIFY_ERROR_NO_METHOD:
- case VERIFY_ERROR_ACCESS_CLASS:
- case VERIFY_ERROR_ACCESS_FIELD:
- case VERIFY_ERROR_ACCESS_METHOD:
- case VERIFY_ERROR_INSTANTIATION:
- case VERIFY_ERROR_CLASS_CHANGE:
- case VERIFY_ERROR_FORCE_INTERPRETER:
- case VERIFY_ERROR_LOCKING:
- if (Runtime::Current()->IsAotCompiler() || !can_load_classes_) {
- // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx,
- // class change and instantiation errors into soft verification errors so that we
- // re-verify at runtime. We may fail to find or to agree on access because of not yet
- // available class loaders, or class loaders that will differ at runtime. In these cases,
- // we don't want to affect the soundness of the code being compiled. Instead, the
- // generated code runs "slow paths" that dynamically perform the verification and cause
- // the behavior to be that akin to an interpreter.
- error = VERIFY_ERROR_BAD_CLASS_SOFT;
- } else {
- // If we fail again at runtime, mark that this instruction would throw and force this
- // method to be executed using the interpreter with checks.
- flags_.have_pending_runtime_throw_failure_ = true;
+ switch (error) {
+ case VERIFY_ERROR_NO_CLASS:
+ case VERIFY_ERROR_NO_FIELD:
+ case VERIFY_ERROR_NO_METHOD:
+ case VERIFY_ERROR_ACCESS_CLASS:
+ case VERIFY_ERROR_ACCESS_FIELD:
+ case VERIFY_ERROR_ACCESS_METHOD:
+ case VERIFY_ERROR_INSTANTIATION:
+ case VERIFY_ERROR_CLASS_CHANGE:
+ case VERIFY_ERROR_FORCE_INTERPRETER:
+ case VERIFY_ERROR_LOCKING:
+ if (Runtime::Current()->IsAotCompiler() || !can_load_classes_) {
+ // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx,
+ // class change and instantiation errors into soft verification errors so that we re-verify
+ // at runtime. We may fail to find or to agree on access because of not yet available class
+ // loaders, or class loaders that will differ at runtime. In these cases, we don't want to
+ // affect the soundness of the code being compiled. Instead, the generated code runs "slow
+ // paths" that dynamically perform the verification and cause the behavior to be that akin
+ // to an interpreter.
+ error = VERIFY_ERROR_BAD_CLASS_SOFT;
+ } else {
+ // If we fail again at runtime, mark that this instruction would throw and force this
+ // method to be executed using the interpreter with checks.
+ flags_.have_pending_runtime_throw_failure_ = true;
- // We need to save the work_line if the instruction wasn't throwing before. Otherwise
- // we'll try to merge garbage.
- // Note: this assumes that Fail is called before we do any work_line modifications.
- // Note: this can fail before we touch any instruction, for the signature of a method. So
- // add a check.
- if (work_insn_idx_ < dex::kDexNoIndex) {
- const Instruction& inst = code_item_accessor_.InstructionAt(work_insn_idx_);
- int opcode_flags = Instruction::FlagsOf(inst.Opcode());
+ // We need to save the work_line if the instruction wasn't throwing before. Otherwise we'll
+ // try to merge garbage.
+ // Note: this assumes that Fail is called before we do any work_line modifications.
+ // Note: this can fail before we touch any instruction, for the signature of a method. So
+ // add a check.
+ if (work_insn_idx_ < dex::kDexNoIndex) {
+ const Instruction& inst = code_item_accessor_.InstructionAt(work_insn_idx_);
+ int opcode_flags = Instruction::FlagsOf(inst.Opcode());
- if ((opcode_flags & Instruction::kThrow) == 0 &&
- GetInstructionFlags(work_insn_idx_).IsInTry()) {
- saved_line_->CopyFromLine(work_line_.get());
- }
+ if ((opcode_flags & Instruction::kThrow) == 0 &&
+ GetInstructionFlags(work_insn_idx_).IsInTry()) {
+ saved_line_->CopyFromLine(work_line_.get());
}
}
- break;
-
- // Indication that verification should be retried at runtime.
- case VERIFY_ERROR_BAD_CLASS_SOFT:
- if (!allow_soft_failures_) {
- flags_.have_pending_hard_failure_ = true;
- }
- break;
-
- // Hard verification failures at compile time will still fail at runtime, so the class is
- // marked as rejected to prevent it from being compiled.
- case VERIFY_ERROR_BAD_CLASS_HARD: {
- flags_.have_pending_hard_failure_ = true;
- break;
}
- }
- } else if (kIsDebugBuild) {
- CHECK_NE(error, VERIFY_ERROR_BAD_CLASS_SOFT);
- CHECK_NE(error, VERIFY_ERROR_BAD_CLASS_HARD);
- }
+ break;
+ // Indication that verification should be retried at runtime.
+ case VERIFY_ERROR_BAD_CLASS_SOFT:
+ if (!allow_soft_failures_) {
+ flags_.have_pending_hard_failure_ = true;
+ }
+ break;
+
+ // Hard verification failures at compile time will still fail at runtime, so the class is
+ // marked as rejected to prevent it from being compiled.
+ case VERIFY_ERROR_BAD_CLASS_HARD: {
+ flags_.have_pending_hard_failure_ = true;
+ break;
+ }
+
+ case VERIFY_ERROR_UNRESOLVED_CATCH:
+ // Nothing to do, just remember the failure type.
+ break;
+ }
failures_.push_back(error);
std::string location(StringPrintf("%s: [0x%X] ", dex_file_->PrettyMethod(dex_method_idx_).c_str(),
work_insn_idx_));