ART: Introduce CompatThrow

Add an "virtual" instruction flag to signal a historical throw
that is not captured by kThrow. Both kinds of instructions need
to capture the work line at the beginning of a verification step.

Long-term, remove CompatThrow.

"Annotate" return-object.

Bug: 121245951
Test: m test-art-host
Change-Id: I07e9f07da3ebcc9ccd1191ffc2c145b2c83a84f8
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index c4be933..6080875 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -120,6 +120,18 @@
   kAccPut
 };
 
+// Instruction types that are not marked as throwing (because they normally would not), but for
+// historical reasons may do so. These instructions cannot be marked kThrow as that would introduce
+// a general flow that is unwanted.
+//
+// Note: Not implemented as Instruction::Flags value as that set is full and we'd need to increase
+//       the struct size (making it a non-power-of-two) for a single element.
+//
+// Note: This should eventually be removed.
+constexpr bool IsCompatThrow(Instruction::Code opcode) {
+  return opcode == Instruction::Code::RETURN_OBJECT;
+}
+
 template <bool kVerifierDebug>
 class MethodVerifier final : public ::art::verifier::MethodVerifier {
  public:
@@ -2052,7 +2064,8 @@
    * from the "successful" code path (e.g. a check-cast that "improves"
    * a type) to be visible to the exception handler.
    */
-  if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) {
+  if (((opcode_flags & Instruction::kThrow) != 0 || IsCompatThrow(inst->Opcode())) &&
+      CurrentInsnFlags()->IsInTry()) {
     saved_line_->CopyFromLine(work_line_.get());
   } else if (kIsDebugBuild) {
     saved_line_->FillWithGarbage();
@@ -5557,6 +5570,7 @@
             int opcode_flags = Instruction::FlagsOf(inst.Opcode());
 
             if ((opcode_flags & Instruction::kThrow) == 0 &&
+                !impl::IsCompatThrow(inst.Opcode()) &&
                 GetInstructionFlags(work_insn_idx_).IsInTry()) {
               saved_line_->CopyFromLine(work_line_.get());
             }