Add compiler support for @NeverInline

This change sets methods as not inlineable if they are annotated with
@NeverInline. This is done by adding a new method in
dex_file_annotations.h that checks if a method is annotated, similar
to @NeverCompile.

Bug: 246530973
Change-Id: I5851fd85367f49d7af3201a7a3ef766f669401e9
diff --git a/build/boot/boot-image-profile.txt b/build/boot/boot-image-profile.txt
index a842df1..9475526 100644
--- a/build/boot/boot-image-profile.txt
+++ b/build/boot/boot-image-profile.txt
@@ -10406,6 +10406,7 @@
 Ldalvik/annotation/optimization/CriticalNative;
 Ldalvik/annotation/optimization/FastNative;
 Ldalvik/annotation/optimization/NeverCompile;
+Ldalvik/annotation/optimization/NeverInline;
 Ldalvik/system/AppSpecializationHooks;
 Ldalvik/system/BaseDexClassLoader$Reporter;
 Ldalvik/system/BaseDexClassLoader;
diff --git a/build/boot/preloaded-classes b/build/boot/preloaded-classes
index 84928ea..f335ba9 100644
--- a/build/boot/preloaded-classes
+++ b/build/boot/preloaded-classes
@@ -466,6 +466,7 @@
 dalvik.annotation.optimization.CriticalNative
 dalvik.annotation.optimization.FastNative
 dalvik.annotation.optimization.NeverCompile
+dalvik.annotation.optimization.NeverInline
 dalvik.system.AppSpecializationHooks
 dalvik.system.BaseDexClassLoader$Reporter
 dalvik.system.BaseDexClassLoader
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index cdd8fb2..cfde561 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1379,6 +1379,15 @@
     return false;
   }
 
+  if (annotations::MethodIsNeverInline(*method->GetDexFile(),
+                                       method->GetClassDef(),
+                                       method->GetDexMethodIndex())) {
+    LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedNeverInlineAnnotation)
+        << "Method " << method->PrettyMethod()
+        << " has the @NeverInline annotation so it won't be inlined";
+    return false;
+  }
+
   return true;
 }
 
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index 5e316ba..18b3a60 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -96,6 +96,7 @@
   kNotInlinedTryCatchCallee,
   kNotInlinedRegisterAllocator,
   kNotInlinedCannotBuild,
+  kNotInlinedNeverInlineAnnotation,
   kNotInlinedNotCompilable,
   kNotInlinedNotVerified,
   kNotInlinedCodeItem,
diff --git a/runtime/dex/dex_file_annotations.cc b/runtime/dex/dex_file_annotations.cc
index 3dd8ae1..3380008 100644
--- a/runtime/dex/dex_file_annotations.cc
+++ b/runtime/dex/dex_file_annotations.cc
@@ -1342,6 +1342,20 @@
       WellKnownClasses::dalvik_annotation_optimization_NeverCompile);
 }
 
+bool MethodIsNeverInline(const DexFile& dex_file,
+                         const dex::ClassDef& class_def,
+                         uint32_t method_index) {
+  const dex::AnnotationSetItem* annotation_set =
+      FindAnnotationSetForMethod(dex_file, class_def, method_index);
+  if (annotation_set == nullptr) {
+    return false;
+  }
+  return IsMethodBuildAnnotationPresent(
+      dex_file,
+      *annotation_set,
+      "Ldalvik/annotation/optimization/NeverInline;",
+      WellKnownClasses::dalvik_annotation_optimization_NeverInline);
+}
 
 bool FieldIsReachabilitySensitive(const DexFile& dex_file,
                                   const dex::ClassDef& class_def,
diff --git a/runtime/dex/dex_file_annotations.h b/runtime/dex/dex_file_annotations.h
index 75951a7..ea11e10 100644
--- a/runtime/dex/dex_file_annotations.h
+++ b/runtime/dex/dex_file_annotations.h
@@ -91,6 +91,11 @@
 bool MethodIsNeverCompile(const DexFile& dex_file,
                           const dex::ClassDef& class_def,
                           uint32_t method_index);
+// Is the method from the `dex_file` with the given `field_index`
+// annotated with @dalvik.annotation.optimization.NeverInline?
+bool MethodIsNeverInline(const DexFile& dex_file,
+                         const dex::ClassDef& class_def,
+                         uint32_t method_index);
 // Is the field from the `dex_file` with the given `field_index`
 // annotated with @dalvik.annotation.optimization.ReachabilitySensitive?
 bool FieldIsReachabilitySensitive(const DexFile& dex_file,
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index cf9e321..fc79149 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -44,6 +44,7 @@
 jclass WellKnownClasses::dalvik_annotation_optimization_CriticalNative;
 jclass WellKnownClasses::dalvik_annotation_optimization_FastNative;
 jclass WellKnownClasses::dalvik_annotation_optimization_NeverCompile;
+jclass WellKnownClasses::dalvik_annotation_optimization_NeverInline;
 jclass WellKnownClasses::dalvik_system_BaseDexClassLoader;
 jclass WellKnownClasses::dalvik_system_DelegateLastClassLoader;
 jclass WellKnownClasses::dalvik_system_DexClassLoader;
@@ -345,6 +346,8 @@
   dalvik_annotation_optimization_FastNative = CacheClass(env, "dalvik/annotation/optimization/FastNative");
   dalvik_annotation_optimization_NeverCompile =
       CacheClass(env, "dalvik/annotation/optimization/NeverCompile");
+  dalvik_annotation_optimization_NeverInline =
+      CacheClass(env, "dalvik/annotation/optimization/NeverInline");
   dalvik_system_BaseDexClassLoader = CacheClass(env, "dalvik/system/BaseDexClassLoader");
   dalvik_system_DelegateLastClassLoader = CacheClass(env, "dalvik/system/DelegateLastClassLoader");
   dalvik_system_DexClassLoader = CacheClass(env, "dalvik/system/DexClassLoader");
@@ -551,6 +554,7 @@
   dalvik_annotation_optimization_CriticalNative = nullptr;
   dalvik_annotation_optimization_FastNative = nullptr;
   dalvik_annotation_optimization_NeverCompile = nullptr;
+  dalvik_annotation_optimization_NeverInline = nullptr;
   dalvik_system_BaseDexClassLoader = nullptr;
   dalvik_system_DelegateLastClassLoader = nullptr;
   dalvik_system_DexClassLoader = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index c334f5d..f575317 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -57,6 +57,7 @@
   static jclass dalvik_annotation_optimization_CriticalNative;
   static jclass dalvik_annotation_optimization_FastNative;
   static jclass dalvik_annotation_optimization_NeverCompile;
+  static jclass dalvik_annotation_optimization_NeverInline;
   static jclass dalvik_system_BaseDexClassLoader;
   static jclass dalvik_system_DelegateLastClassLoader;
   static jclass dalvik_system_DexClassLoader;