Simplify our intrinsic recognizer.

- Use the modifiers for storing the intrinsic kind.
- Delete dex_file_method_inliner and its associated map.

This work was also motivated by the fact that the inline
method analyzer leaks intrinsic tables, and even worse, might re-use
a table from one dex file to another unrelated dex file in the presence
of class unloading and the unlikely event of the dex files getting
the same address.

test: m test-art-host m test-art-target

Change-Id: Ia653d2c72df13889dc85dd8c84997582c034ea4b
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 3d2db69..7a8f479 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -137,7 +137,52 @@
     return (GetAccessFlags() & kAccFinal) != 0;
   }
 
+  bool IsIntrinsic() {
+    return (GetAccessFlags() & kAccIntrinsic) != 0;
+  }
+
+  void SetIntrinsic(uint32_t intrinsic) {
+    DCHECK(IsUint<8>(intrinsic));
+    uint32_t new_value = (GetAccessFlags() & kAccFlagsNotUsedByIntrinsic) |
+        kAccIntrinsic |
+        (intrinsic << POPCOUNT(kAccFlagsNotUsedByIntrinsic));
+    if (kIsDebugBuild) {
+      uint32_t java_flags = (GetAccessFlags() & kAccJavaFlagsMask);
+      bool is_constructor = IsConstructor();
+      bool is_synchronized = IsSynchronized();
+      bool skip_access_checks = SkipAccessChecks();
+      bool is_fast_native = IsFastNative();
+      bool is_copied = IsCopied();
+      bool is_miranda = IsMiranda();
+      bool is_default = IsDefault();
+      bool is_default_conflict = IsDefaultConflicting();
+      bool is_compilable = IsCompilable();
+      bool must_count_locks = MustCountLocks();
+      SetAccessFlags(new_value);
+      DCHECK_EQ(java_flags, (GetAccessFlags() & kAccJavaFlagsMask));
+      DCHECK_EQ(is_constructor, IsConstructor());
+      DCHECK_EQ(is_synchronized, IsSynchronized());
+      DCHECK_EQ(skip_access_checks, SkipAccessChecks());
+      DCHECK_EQ(is_fast_native, IsFastNative());
+      DCHECK_EQ(is_copied, IsCopied());
+      DCHECK_EQ(is_miranda, IsMiranda());
+      DCHECK_EQ(is_default, IsDefault());
+      DCHECK_EQ(is_default_conflict, IsDefaultConflicting());
+      DCHECK_EQ(is_compilable, IsCompilable());
+      DCHECK_EQ(must_count_locks, MustCountLocks());
+    } else {
+      SetAccessFlags(new_value);
+    }
+  }
+
+  uint32_t GetIntrinsic() {
+    DCHECK(IsIntrinsic());
+    return (GetAccessFlags() >> POPCOUNT(kAccFlagsNotUsedByIntrinsic)) & kAccMaxIntrinsic;
+  }
+
   bool IsCopied() {
+    static_assert((kAccCopied & kAccFlagsNotUsedByIntrinsic) == kAccCopied,
+                  "kAccCopied conflicts with intrinsic modifier");
     const bool copied = (GetAccessFlags() & kAccCopied) != 0;
     // (IsMiranda() || IsDefaultConflicting()) implies copied
     DCHECK(!(IsMiranda() || IsDefaultConflicting()) || copied)
@@ -146,6 +191,8 @@
   }
 
   bool IsMiranda() {
+    static_assert((kAccMiranda & kAccFlagsNotUsedByIntrinsic) == kAccMiranda,
+                  "kAccMiranda conflicts with intrinsic modifier");
     return (GetAccessFlags() & kAccMiranda) != 0;
   }
 
@@ -156,6 +203,9 @@
   }
 
   bool IsCompilable() {
+    if (IsIntrinsic()) {
+      return true;
+    }
     return (GetAccessFlags() & kAccCompileDontBother) == 0;
   }
 
@@ -163,11 +213,16 @@
   // multiple default methods. It cannot be invoked, throwing an IncompatibleClassChangeError if one
   // attempts to do so.
   bool IsDefaultConflicting() {
+    if (IsIntrinsic()) {
+      return false;
+    }
     return (GetAccessFlags() & kAccDefaultConflict) != 0u;
   }
 
   // This is set by the class linker.
   bool IsDefault() {
+    static_assert((kAccDefault & kAccFlagsNotUsedByIntrinsic) == kAccDefault,
+                  "kAccDefault conflicts with intrinsic modifier");
     return (GetAccessFlags() & kAccDefault) != 0;
   }
 
@@ -204,6 +259,9 @@
   // Should this method be run in the interpreter and count locks (e.g., failed structured-
   // locking verification)?
   bool MustCountLocks() {
+    if (IsIntrinsic()) {
+      return false;
+    }
     return (GetAccessFlags() & kAccMustCountLocks) != 0;
   }
 
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 8af9fa5..91e31d8 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -78,7 +78,6 @@
   kAllocSpaceLock,
   kBumpPointerSpaceBlockLock,
   kArenaPoolLock,
-  kDexFileMethodInlinerLock,
   kDexFileToMethodInlinerMapLock,
   kInternTableLock,
   kOatFileSecondaryLookupLock,
diff --git a/runtime/image.cc b/runtime/image.cc
index 7e6790a..299d5fd 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -25,7 +25,7 @@
 namespace art {
 
 const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '0', '\0' };
+const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '1', '\0' };
 
 ImageHeader::ImageHeader(uint32_t image_begin,
                          uint32_t image_size,
diff --git a/runtime/modifiers.h b/runtime/modifiers.h
index fd7a125..dd32df6 100644
--- a/runtime/modifiers.h
+++ b/runtime/modifiers.h
@@ -67,6 +67,7 @@
 
 // Set by the verifier for a method that could not be verified to follow structured locking.
 static constexpr uint32_t kAccMustCountLocks =        0x02000000;  // method (runtime)
+static constexpr uint32_t kAccIntrinsic  =            0x80000000;  // method (runtime)
 
 // Special runtime-only flags.
 // Interface and all its super-interfaces with default methods have been recursively initialized.
@@ -76,6 +77,9 @@
 // class/ancestor overrides finalize()
 static constexpr uint32_t kAccClassIsFinalizable        = 0x80000000;
 
+static constexpr uint32_t kAccFlagsNotUsedByIntrinsic   = 0x007FFFFF;
+static constexpr uint32_t kAccMaxIntrinsic              = 0xFF;
+
 // Valid (meaningful) bits for a field.
 static constexpr uint32_t kAccValidFieldFlags = kAccPublic | kAccPrivate | kAccProtected |
     kAccStatic | kAccFinal | kAccVolatile | kAccTransient | kAccSynthetic | kAccEnum;