Selectively allow dead reference elimination

Allow dead reference elimination in methods not containing
@ReachabilitySensitive accesses or calls, when the class is marked
@DeadReferenceSafe.

Add 1339-dead-reference-safe to aggressively check that everything
works as intended.

Bug: 111453875

Test: art/test/testrunner/testrunner.py --host --64 -t 1339-dead-reference-safe

Detect ReachabilitySensitive annotations.

Change-Id: I70c20431fdbcfcfd2692b2255d12ad59e37cb669
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 8440e9a..96d6d2a 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1789,6 +1789,14 @@
     invoke_type = kVirtual;
   }
 
+  bool caller_dead_reference_safe = graph_->IsDeadReferenceSafe();
+  const dex::ClassDef& callee_class = resolved_method->GetClassDef();
+  // MethodContainsRSensitiveAccess is currently slow, but HasDeadReferenceSafeAnnotation()
+  // is currently rarely true.
+  bool callee_dead_reference_safe =
+      annotations::HasDeadReferenceSafeAnnotation(callee_dex_file, callee_class)
+      && !annotations::MethodContainsRSensitiveAccess(callee_dex_file, callee_class, method_index);
+
   const int32_t caller_instruction_counter = graph_->GetCurrentInstructionId();
   HGraph* callee_graph = new (graph_->GetAllocator()) HGraph(
       graph_->GetAllocator(),
@@ -1797,6 +1805,7 @@
       method_index,
       codegen_->GetCompilerOptions().GetInstructionSet(),
       invoke_type,
+      callee_dead_reference_safe,
       graph_->IsDebuggable(),
       /* osr= */ false,
       caller_instruction_counter);
@@ -2023,6 +2032,13 @@
     inline_stats_->AddTo(stats_);
   }
 
+  if (caller_dead_reference_safe && !callee_dead_reference_safe) {
+    // Caller was dead reference safe, but is not anymore, since we inlined dead
+    // reference unsafe code. Prior transformations remain valid, since they did not
+    // affect the inlined code.
+    graph_->MarkDeadReferenceUnsafe();
+  }
+
   return true;
 }