Merge "Actually use --copy-and-update-profile-key argument in profman..."
diff --git a/Android.bp b/Android.bp
index ad42d3f..bb92e5f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,7 +1,6 @@
 // TODO: These should be handled with transitive static library dependencies
 art_static_dependencies = [
     // Note: the order is important because of static linking resolution.
-    "libdexfile",
     "libziparchive",
     "libnativehelper",
     "libnativebridge",
diff --git a/Android.mk b/Android.mk
index 361ceec..2489308 100644
--- a/Android.mk
+++ b/Android.mk
@@ -79,6 +79,7 @@
 include $(art_path)/oatdump/Android.mk
 include $(art_path)/tools/Android.mk
 include $(art_path)/tools/ahat/Android.mk
+include $(art_path)/tools/amm/Android.mk
 include $(art_path)/tools/dexfuzz/Android.mk
 include $(art_path)/libart_fake/Android.mk
 
@@ -486,8 +487,10 @@
                         $(ART_TARGET_SHARED_LIBRARY_BENCHMARK) \
                         $(TARGET_CORE_IMG_OUT_BASE).art \
                         $(TARGET_CORE_IMG_OUT_BASE)-interpreter.art
+	# remove libartd.so and libdexfiled.so from public.libraries.txt because golem builds
+	# won't have it.
 	sed -i '/libartd.so/d' $(TARGET_OUT)/etc/public.libraries.txt
-	# remove libartd.so from public.libraries.txt because golem builds won't have it.
+	sed -i '/libdexfiled.so/d' $(TARGET_OUT)/etc/public.libraries.txt
 
 ########################################################################
 # Phony target for building what go/lem requires on host.
diff --git a/compiler/Android.bp b/compiler/Android.bp
index 4539659..ba08d79 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -184,7 +184,6 @@
     },
     generated_sources: ["art_compiler_operator_srcs"],
     shared_libs: [
-        "libdexfile",
         "libbase",
         "libcutils",  // for atrace.
         "liblzma",
@@ -250,6 +249,7 @@
     },
     shared_libs: [
         "libart",
+        "libdexfile",
     ],
 
     pgo: {
@@ -295,6 +295,7 @@
     },
     shared_libs: [
         "libartd",
+        "libdexfiled",
     ],
 }
 
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 43ca2cf..f91d37b 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4567,7 +4567,7 @@
                                                kFieldClinitCheckRequirementSize>;
 
   // Cached values of the resolved method, to avoid needing the mutator lock.
-  MethodReference target_method_;
+  const MethodReference target_method_;
   DispatchInfo dispatch_info_;
 };
 std::ostream& operator<<(std::ostream& os, HInvokeStaticOrDirect::MethodLoadKind rhs);
diff --git a/dex2oat/Android.bp b/dex2oat/Android.bp
index ab06ddd..dd16ba4 100644
--- a/dex2oat/Android.bp
+++ b/dex2oat/Android.bp
@@ -152,7 +152,7 @@
         "libartd-compiler",
         "libartd-dexlayout",
         "libartd",
-        "libdexfile",
+        "libdexfiled",
         "libbase",
         "liblz4",
         "libsigchain",
@@ -185,6 +185,7 @@
         "libart-compiler",
         "libart-dexlayout",
         "libart",
+        "libdexfile",
         "libvixl-arm",
         "libvixl-arm64",
     ] + art_static_dependencies,
@@ -216,6 +217,7 @@
         "libartd-compiler",
         "libartd-dexlayout",
         "libartd",
+        "libdexfiled",
         "libvixld-arm",
         "libvixld-arm64",
     ] + art_static_dependencies,
diff --git a/dexdump/Android.bp b/dexdump/Android.bp
index f6b7a6b..eca0844 100644
--- a/dexdump/Android.bp
+++ b/dexdump/Android.bp
@@ -45,6 +45,7 @@
     host_supported: true,
     device_supported: false,
     static_libs: [
+        "libdexfile",
         "libbase",
     ] + art_static_dependencies,
     target: {
diff --git a/dexlayout/Android.bp b/dexlayout/Android.bp
index 3ea7f4b..bea61d0 100644
--- a/dexlayout/Android.bp
+++ b/dexlayout/Android.bp
@@ -27,7 +27,6 @@
     ],
     export_include_dirs: ["."],
     shared_libs: [
-        "libdexfile",
         "libbase",
     ],
     static_libs: ["libz"],
@@ -36,7 +35,10 @@
 art_cc_library {
     name: "libart-dexlayout",
     defaults: ["libart-dexlayout-defaults"],
-    shared_libs: ["libart"],
+    shared_libs: [
+        "libart",
+        "libdexfile",
+    ],
 
     pgo: {
         instrumentation: true,
@@ -51,7 +53,10 @@
       "libart-dexlayout-defaults",
       "art_debug_defaults",
     ],
-    shared_libs: ["libartd"],
+    shared_libs: [
+        "libartd",
+        "libdexfiled",
+    ],
 }
 
 cc_defaults {
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index bcf2bdb..90c603f 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -93,6 +93,14 @@
     },
 }
 
+art_cc_library {
+    name: "libdexfiled",
+    defaults: [
+        "art_debug_defaults",
+        "libdexfile_defaults",
+    ],
+}
+
 art_cc_test {
     name: "art_libdexfile_tests",
     defaults: [
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index 18eb903..6a704c1 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -45,6 +45,21 @@
 static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong");
 static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial");
 
+void DexFile::UnHideAccessFlags(ClassDataItemIterator& class_it) {
+  uint8_t* data = const_cast<uint8_t*>(class_it.DataPointer());
+  uint32_t new_flag = class_it.GetMemberAccessFlags();
+  bool is_method = class_it.IsAtMethod();
+  // Go back 1 uleb to start.
+  data = ReverseSearchUnsignedLeb128(data);
+  if (is_method) {
+    // Methods have another uleb field before the access flags
+    data = ReverseSearchUnsignedLeb128(data);
+  }
+  DCHECK_EQ(HiddenApiAccessFlags::RemoveFromDex(DecodeUnsignedLeb128WithoutMovingCursor(data)),
+            new_flag);
+  UpdateUnsignedLeb128(data, new_flag);
+}
+
 uint32_t DexFile::CalculateChecksum() const {
   return CalculateChecksum(Begin(), Size());
 }
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index a38e76c..a62ab62 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -35,6 +35,7 @@
 
 namespace art {
 
+class ClassDataItemIterator;
 class CompactDexFile;
 enum InvokeType : uint32_t;
 class MemMap;
@@ -1000,6 +1001,9 @@
     return container_.get();
   }
 
+  // Changes the dex file pointed to by class_it to not have any hiddenapi flags.
+  static void UnHideAccessFlags(ClassDataItemIterator& class_it);
+
  protected:
   // First Dex format version supporting default methods.
   static const uint32_t kDefaultMethodsVersion = 37;
diff --git a/oatdump/Android.bp b/oatdump/Android.bp
index c93c172..012100d 100644
--- a/oatdump/Android.bp
+++ b/oatdump/Android.bp
@@ -51,7 +51,7 @@
         "libartd",
         "libartd-compiler",
         "libartd-disassembler",
-        "libdexfile",
+        "libdexfiled",
         "libbase",
     ],
 }
@@ -76,6 +76,7 @@
     ],
     static_libs: [
         "libart",
+        "libdexfile",
         "libart-compiler",
         "libart-disassembler",
         "libvixl-arm",
@@ -106,6 +107,7 @@
     ],
     static_libs: [
         "libartd",
+        "libdexfiled",
         "libartd-compiler",
         "libartd-disassembler",
         "libvixld-arm",
diff --git a/openjdkjvmti/Android.bp b/openjdkjvmti/Android.bp
index 1500bca..1553b78 100644
--- a/openjdkjvmti/Android.bp
+++ b/openjdkjvmti/Android.bp
@@ -58,7 +58,6 @@
         "libopenjdkjvmti_headers",
     ],
     shared_libs: [
-        "libdexfile",
         "libbase",
     ],
 }
@@ -70,6 +69,7 @@
         "libart",
         "libart-compiler",
         "libart-dexlayout",
+        "libdexfile",
     ],
 }
 
@@ -83,5 +83,6 @@
         "libartd",
         "libartd-compiler",
         "libartd-dexlayout",
+        "libdexfiled",
     ],
 }
diff --git a/openjdkjvmti/fixed_up_dex_file.cc b/openjdkjvmti/fixed_up_dex_file.cc
index 427d87e..90c6449 100644
--- a/openjdkjvmti/fixed_up_dex_file.cc
+++ b/openjdkjvmti/fixed_up_dex_file.cc
@@ -40,6 +40,7 @@
 #include "dex/compact_dex_level.h"
 #include "dex_to_dex_decompiler.h"
 #include "dexlayout.h"
+#include "leb128.h"
 #include "oat_file.h"
 #include "vdex_file.h"
 
@@ -50,21 +51,41 @@
       dex_file->CalculateChecksum();
 }
 
-static void DoDexUnquicken(const art::DexFile& new_dex_file,
-                           const art::DexFile& original_dex_file) {
+static void UnhideApis(const art::DexFile& target_dex_file) {
+  for (uint32_t i = 0; i < target_dex_file.NumClassDefs(); ++i) {
+    const uint8_t* class_data = target_dex_file.GetClassData(target_dex_file.GetClassDef(i));
+    if (class_data != nullptr) {
+      for (art::ClassDataItemIterator class_it(target_dex_file, class_data);
+           class_it.HasNext();
+           class_it.Next()) {
+        art::DexFile::UnHideAccessFlags(class_it);
+      }
+    }
+  }
+}
+
+static const art::VdexFile* GetVdex(const art::DexFile& original_dex_file) {
   const art::OatDexFile* oat_dex = original_dex_file.GetOatDexFile();
   if (oat_dex == nullptr) {
-    return;
+    return nullptr;
   }
   const art::OatFile* oat_file = oat_dex->GetOatFile();
   if (oat_file == nullptr) {
-    return;
+    return nullptr;
   }
-  const art::VdexFile* vdex = oat_file->GetVdexFile();
-  if (vdex == nullptr) {
-    return;
+  return oat_file->GetVdexFile();
+}
+
+static void DoDexUnquicken(const art::DexFile& new_dex_file,
+                           const art::DexFile& original_dex_file) {
+  const art::VdexFile* vdex = GetVdex(original_dex_file);
+  if (vdex != nullptr) {
+    vdex->UnquickenDexFile(new_dex_file, original_dex_file, /* decompile_return_instruction */true);
+  } else {
+    // The dex file isn't quickened since it is being used directly. We might still have hiddenapis
+    // so we need to get rid of those.
+    UnhideApis(new_dex_file);
   }
-  vdex->UnquickenDexFile(new_dex_file, original_dex_file, /* decompile_return_instruction */true);
 }
 
 static void DCheckVerifyDexFile(const art::DexFile& dex) {
diff --git a/profman/Android.bp b/profman/Android.bp
index 6592b9d..163be2b 100644
--- a/profman/Android.bp
+++ b/profman/Android.bp
@@ -31,7 +31,6 @@
     },
 
     shared_libs: [
-        "libdexfile",
         "libbase",
     ],
 }
@@ -41,6 +40,7 @@
     defaults: ["profman-defaults"],
     shared_libs: [
         "libart",
+        "libdexfile",
     ],
 }
 
@@ -52,6 +52,7 @@
     ],
     shared_libs: [
         "libartd",
+        "libdexfiled",
     ],
 }
 
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 110b04f..1ac770f 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -409,7 +409,6 @@
         "jni_platform_headers",
     ],
     shared_libs: [
-        "libdexfile",
         "libnativebridge",
         "libnativeloader",
         "libbacktrace",
@@ -430,10 +429,7 @@
     // ART's macros.h depends on libbase's macros.h.
     // Note: runtime_options.h depends on cmdline. But we don't really want to export this
     //       generically. dex2oat takes care of it itself.
-    export_shared_lib_headers: [
-        "libbase",
-        "libdexfile",
-    ],
+    export_shared_lib_headers: ["libbase"],
 }
 
 gensrcs {
@@ -490,6 +486,8 @@
     strip: {
         keep_symbols: true,
     },
+    shared_libs: ["libdexfile"],
+    export_shared_lib_headers: ["libdexfile"],
 }
 
 art_cc_library {
@@ -498,6 +496,8 @@
         "art_debug_defaults",
         "libart_defaults",
     ],
+    shared_libs: ["libdexfiled"],
+    export_shared_lib_headers: ["libdexfiled"],
 }
 
 art_cc_library {
diff --git a/runtime/base/stringpiece.cc b/runtime/base/stringpiece.cc
index 672431c..aea4e74 100644
--- a/runtime/base/stringpiece.cc
+++ b/runtime/base/stringpiece.cc
@@ -23,13 +23,6 @@
 
 namespace art {
 
-#if !defined(NDEBUG)
-char StringPiece::operator[](size_type i) const {
-  CHECK_LT(i, length_);
-  return ptr_[i];
-}
-#endif
-
 void StringPiece::CopyToString(std::string* target) const {
   target->assign(ptr_, length_);
 }
diff --git a/runtime/base/stringpiece.h b/runtime/base/stringpiece.h
index 46743e9..e7109dc 100644
--- a/runtime/base/stringpiece.h
+++ b/runtime/base/stringpiece.h
@@ -20,6 +20,8 @@
 #include <string.h>
 #include <string>
 
+#include <android-base/logging.h>
+
 namespace art {
 
 // A string-like object that points to a sized piece of memory.
@@ -84,13 +86,10 @@
     length_ = len;
   }
 
-#if defined(NDEBUG)
   char operator[](size_type i) const {
+    DCHECK_LT(i, length_);
     return ptr_[i];
   }
-#else
-  char operator[](size_type i) const;
-#endif
 
   void remove_prefix(size_type n) {
     ptr_ += n;
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 5549122..05f099f 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -46,6 +46,7 @@
 #include "well_known_classes.h"
 
 namespace art {
+namespace {
 
 using android::base::StringAppendF;
 using android::base::StringPrintf;
@@ -1211,7 +1212,7 @@
     // this particular instance of JNIEnv.
     if (env != threadEnv) {
       // Get the thread owning the JNIEnv that's being used.
-      Thread* envThread = reinterpret_cast<JNIEnvExt*>(env)->self_;
+      Thread* envThread = reinterpret_cast<JNIEnvExt*>(env)->GetSelf();
       AbortF("thread %s using JNIEnv* from thread %s",
              ToStr<Thread>(*self).c_str(), ToStr<Thread>(*envThread).c_str());
       return false;
@@ -1223,7 +1224,7 @@
     case kFlag_CritOkay:    // okay to call this method
       break;
     case kFlag_CritBad:     // not okay to call
-      if (threadEnv->critical_ > 0) {
+      if (threadEnv->GetCritical() > 0) {
         AbortF("thread %s using JNI after critical get",
                ToStr<Thread>(*self).c_str());
         return false;
@@ -1231,25 +1232,25 @@
       break;
     case kFlag_CritGet:     // this is a "get" call
       // Don't check here; we allow nested gets.
-      if (threadEnv->critical_ == 0) {
-        threadEnv->critical_start_us_ = self->GetCpuMicroTime();
+      if (threadEnv->GetCritical() == 0) {
+        threadEnv->SetCriticalStartUs(self->GetCpuMicroTime());
       }
-      threadEnv->critical_++;
+      threadEnv->SetCritical(threadEnv->GetCritical() + 1);
       break;
     case kFlag_CritRelease:  // this is a "release" call
-      if (threadEnv->critical_ == 0) {
+      if (threadEnv->GetCritical() == 0) {
         AbortF("thread %s called too many critical releases",
                ToStr<Thread>(*self).c_str());
         return false;
-      } else if (threadEnv->critical_ == 1) {
+      } else if (threadEnv->GetCritical() == 1) {
         // Leaving the critical region, possibly warn about long critical regions.
-        uint64_t critical_duration_us = self->GetCpuMicroTime() - threadEnv->critical_start_us_;
+        uint64_t critical_duration_us = self->GetCpuMicroTime() - threadEnv->GetCriticalStartUs();
         if (critical_duration_us > kCriticalWarnTimeUs) {
           LOG(WARNING) << "JNI critical lock held for "
                        << PrettyDuration(UsToNs(critical_duration_us)) << " on " << *self;
         }
       }
-      threadEnv->critical_--;
+      threadEnv->SetCritical(threadEnv->GetCritical() - 1);
       break;
     default:
       LOG(FATAL) << "Bad flags (internal error): " << flags_;
@@ -2621,7 +2622,7 @@
   }
 
   static const JNINativeInterface* baseEnv(JNIEnv* env) {
-    return reinterpret_cast<JNIEnvExt*>(env)->unchecked_functions_;
+    return reinterpret_cast<JNIEnvExt*>(env)->GetUncheckedFunctions();
   }
 
   static jobject NewRef(const char* function_name, JNIEnv* env, jobject obj, IndirectRefKind kind) {
@@ -3847,10 +3848,6 @@
   CheckJNI::GetObjectRefType,
 };
 
-const JNINativeInterface* GetCheckJniNativeInterface() {
-  return &gCheckNativeInterface;
-}
-
 class CheckJII {
  public:
   static jint DestroyJavaVM(JavaVM* vm) {
@@ -3922,6 +3919,12 @@
   CheckJII::AttachCurrentThreadAsDaemon
 };
 
+}  // anonymous namespace
+
+const JNINativeInterface* GetCheckJniNativeInterface() {
+  return &gCheckNativeInterface;
+}
+
 const JNIInvokeInterface* GetCheckJniInvokeInterface() {
   return &gCheckInvokeInterface;
 }
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index cd6e8d5..ae06f8f 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -226,14 +226,7 @@
     const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
     ObjPtr<mirror::Class> klass = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader);
     if (klass != nullptr) {
-      if (klass->IsInterface()) {
-        resolved = klass->FindInterfaceMethod(dex_cache, method_idx, pointer_size);
-      } else {
-        resolved = klass->FindClassMethod(dex_cache, method_idx, pointer_size);
-      }
-      if (resolved != nullptr) {
-        dex_cache->SetResolvedMethod(method_idx, resolved, pointer_size);
-      }
+      resolved = FindResolvedMethod(klass, dex_cache, class_loader, method_idx);
     }
   }
   return resolved;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c4b1bf8..6262728 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -7939,6 +7939,38 @@
   return oss.str();
 }
 
+ArtMethod* ClassLinker::FindResolvedMethod(ObjPtr<mirror::Class> klass,
+                                           ObjPtr<mirror::DexCache> dex_cache,
+                                           ObjPtr<mirror::ClassLoader> class_loader,
+                                           uint32_t method_idx) {
+  // Search for the method using dex_cache and method_idx. The Class::Find*Method()
+  // functions can optimize the search if the dex_cache is the same as the DexCache
+  // of the class, with fall-back to name and signature search otherwise.
+  ArtMethod* resolved = nullptr;
+  if (klass->IsInterface()) {
+    resolved = klass->FindInterfaceMethod(dex_cache, method_idx, image_pointer_size_);
+  } else {
+    resolved = klass->FindClassMethod(dex_cache, method_idx, image_pointer_size_);
+  }
+  DCHECK(resolved == nullptr || resolved->GetDeclaringClassUnchecked() != nullptr);
+  if (resolved != nullptr) {
+    // In case of jmvti, the dex file gets verified before being registered, so first
+    // check if it's registered before checking class tables.
+    const DexFile& dex_file = *dex_cache->GetDexFile();
+    CHECK(!IsDexFileRegistered(Thread::Current(), dex_file) ||
+          FindClassTable(Thread::Current(), dex_cache) == ClassTableForClassLoader(class_loader))
+        << "DexFile referrer: " << dex_file.GetLocation()
+        << " ClassLoader: " << DescribeLoaders(class_loader, "");
+    // Be a good citizen and update the dex cache to speed subsequent calls.
+    dex_cache->SetResolvedMethod(method_idx, resolved, image_pointer_size_);
+    const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
+    CHECK(LookupResolvedType(method_id.class_idx_, dex_cache, class_loader) != nullptr)
+        << "Class: " << klass->PrettyClass() << ", "
+        << "DexFile referrer: " << dex_file.GetLocation();
+  }
+  return resolved;
+}
+
 template <ClassLinker::ResolveMode kResolveMode>
 ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx,
                                       Handle<mirror::DexCache> dex_cache,
@@ -7971,6 +8003,7 @@
           << resolved->PrettyMethod() << ";" << resolved
           << "/0x" << std::hex << resolved->GetAccessFlags()
           << " ReferencedClass: " << descriptor
+          << " DexFile referrer: " << dex_file.GetLocation()
           << " ClassLoader: " << DescribeLoaders(class_loader.Get(), descriptor);
     }
   } else {
@@ -7991,19 +8024,7 @@
   }
 
   if (!valid_dex_cache_method) {
-    // Search for the method using dex_cache and method_idx. The Class::Find*Method()
-    // functions can optimize the search if the dex_cache is the same as the DexCache
-    // of the class, with fall-back to name and signature search otherwise.
-    if (klass->IsInterface()) {
-      resolved = klass->FindInterfaceMethod(dex_cache.Get(), method_idx, pointer_size);
-    } else {
-      resolved = klass->FindClassMethod(dex_cache.Get(), method_idx, pointer_size);
-    }
-    DCHECK(resolved == nullptr || resolved->GetDeclaringClassUnchecked() != nullptr);
-    if (resolved != nullptr) {
-      // Be a good citizen and update the dex cache to speed subsequent calls.
-      dex_cache->SetResolvedMethod(method_idx, resolved, pointer_size);
-    }
+    resolved = FindResolvedMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx);
   }
 
   // Note: We can check for IllegalAccessError only if we have a referrer.
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 16fa1ce..6bb924f 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -312,6 +312,13 @@
                                   ObjPtr<mirror::ClassLoader> class_loader)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Find a method with the given index from class `klass`, and update the dex cache.
+  ArtMethod* FindResolvedMethod(ObjPtr<mirror::Class> klass,
+                                ObjPtr<mirror::DexCache> dex_cache,
+                                ObjPtr<mirror::ClassLoader> class_loader,
+                                uint32_t method_idx)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   // Resolve a method with a given ID from the DexFile associated with the given DexCache
   // and ClassLoader, storing the result in DexCache. The ClassLinker and ClassLoader are
   // used as in ResolveType. What is unique is the method type argument which is used to
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 9ef7d42..404c535 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -99,14 +99,13 @@
                << "This must be due to playing wrongly with class loaders";
   }
 
-  inlined_method = klass->FindClassMethod(dex_cache, method_index, kRuntimePointerSize);
+  inlined_method = class_linker->FindResolvedMethod(klass, dex_cache, class_loader, method_index);
   if (inlined_method == nullptr) {
     LOG(FATAL) << "Could not find an inlined method from an .oat file: the class " << descriptor
                << " does not have " << dex_file->GetMethodName(method_id)
                << dex_file->GetMethodSignature(method_id) << " declared. "
                << "This must be due to duplicate classes or playing wrongly with class loaders";
   }
-  dex_cache->SetResolvedMethod(method_index, inlined_method, kRuntimePointerSize);
 
   return inlined_method;
 }
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 24cedb0..0ae6dbf 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -269,7 +269,20 @@
         }
       } else {
         CHECK_NE(return_pc, 0U);
-        CHECK(!reached_existing_instrumentation_frames_);
+        if (UNLIKELY(reached_existing_instrumentation_frames_)) {
+          std::string thread_name;
+          GetThread()->GetThreadName(thread_name);
+          uint32_t dex_pc = dex::kDexNoIndex;
+          if (last_return_pc_ != 0 &&
+              GetCurrentOatQuickMethodHeader() != nullptr) {
+            dex_pc = GetCurrentOatQuickMethodHeader()->ToDexPc(m, last_return_pc_);
+          }
+          LOG(FATAL) << "While walking " << thread_name << " found existing instrumentation frames."
+                     << " method is " << GetMethod()->PrettyMethod()
+                     << " return_pc is " << std::hex << return_pc
+                     << " dex pc: " << dex_pc;
+          UNREACHABLE();
+        }
         InstrumentationStackFrame instrumentation_frame(
             m->IsRuntimeMethod() ? nullptr : GetThisObject(),
             m,
diff --git a/runtime/java_vm_ext.h b/runtime/java_vm_ext.h
index 8c81c25..ac20afe 100644
--- a/runtime/java_vm_ext.h
+++ b/runtime/java_vm_ext.h
@@ -225,7 +225,7 @@
 
   // Extra checking.
   bool check_jni_;
-  bool force_copy_;
+  const bool force_copy_;
   const bool tracing_enabled_;
 
   // Extra diagnostics.
diff --git a/runtime/jni_env_ext.h b/runtime/jni_env_ext.h
index 0e8fd03..291ac48 100644
--- a/runtime/jni_env_ext.h
+++ b/runtime/jni_env_ext.h
@@ -96,6 +96,15 @@
   }
 
   Thread* GetSelf() const { return self_; }
+  uint32_t GetCritical() const { return critical_; }
+  void SetCritical(uint32_t new_critical) { critical_ = new_critical; }
+  uint64_t GetCriticalStartUs() const { return critical_start_us_; }
+  void SetCriticalStartUs(uint64_t new_critical_start_us) {
+    critical_start_us_ = new_critical_start_us;
+  }
+  const JNINativeInterface* GetUncheckedFunctions() const {
+    return unchecked_functions_;
+  }
   JavaVMExt* GetVm() const { return vm_; }
 
   bool IsRuntimeDeleted() const { return runtime_deleted_; }
@@ -190,9 +199,7 @@
   // If we are a JNI env for a daemon thread with a deleted runtime.
   bool runtime_deleted_;
 
-  friend class CheckJNI;
   friend class JNI;
-  friend class ScopedCheck;
   friend class ScopedJniEnvLocalRefState;
   friend class Thread;
   ART_FRIEND_TEST(JniInternalTest, JNIEnvExtOffsets);
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 57a429c..505b745 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -405,18 +405,15 @@
   }
   const DexFile* dex_file = dex_cache->GetDexFile();
   const DexFile::MethodId& method_id = dex_file->GetMethodId(method_idx);
-  ObjPtr<mirror::Class> klass = Runtime::Current()->GetClassLinker()->LookupResolvedType(
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+
+  ObjPtr<mirror::Class> klass = class_linker->LookupResolvedType(
       method_id.class_idx_, dex_cache, /* class_loader */ nullptr);
   if (klass == nullptr) {
     return;
   }
-  ArtMethod* method = klass->IsInterface()
-      ? klass->FindInterfaceMethod(dex_cache, method_idx, kRuntimePointerSize)
-      : klass->FindClassMethod(dex_cache, method_idx, kRuntimePointerSize);
-  if (method == nullptr) {
-    return;
-  }
-  dex_cache->SetResolvedMethod(method_idx, method, kRuntimePointerSize);
+  // Call FindResolvedMethod to populate the dex cache.
+  class_linker->FindResolvedMethod(klass, dex_cache, /* class_loader */ nullptr, method_idx);
 }
 
 struct DexCacheStats {
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 0829c54..443c35f 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -263,18 +263,6 @@
   UnquickenDexFile(target_dex_file, source_dex_file.Begin(), decompile_return_instruction);
 }
 
-static void UpdateAccessFlags(uint8_t* data, uint32_t new_flag, bool is_method) {
-  // Go back 1 uleb to start.
-  data = ReverseSearchUnsignedLeb128(data);
-  if (is_method) {
-    // Methods have another uleb field before the access flags
-    data = ReverseSearchUnsignedLeb128(data);
-  }
-  DCHECK_EQ(HiddenApiAccessFlags::RemoveFromDex(DecodeUnsignedLeb128WithoutMovingCursor(data)),
-            new_flag);
-  UpdateUnsignedLeb128(data, new_flag);
-}
-
 void VdexFile::UnquickenDexFile(const DexFile& target_dex_file,
                                 const uint8_t* source_dex_begin,
                                 bool decompile_return_instruction) const {
@@ -312,14 +300,8 @@
                 quicken_data,
                 decompile_return_instruction);
           }
-          UpdateAccessFlags(const_cast<uint8_t*>(class_it.DataPointer()),
-                            class_it.GetMemberAccessFlags(),
-                            /*is_method*/ true);
-        } else {
-          UpdateAccessFlags(const_cast<uint8_t*>(class_it.DataPointer()),
-                            class_it.GetMemberAccessFlags(),
-                            /*is_method*/ false);
         }
+        DexFile::UnHideAccessFlags(class_it);
       }
     }
   }
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 3e9dfd1..66e578f 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3899,21 +3899,13 @@
   }
   ObjPtr<mirror::Class> klass = klass_type.GetClass();
   const RegType& referrer = GetDeclaringClass();
-  auto* cl = Runtime::Current()->GetClassLinker();
-  auto pointer_size = cl->GetImagePointerSize();
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  PointerSize pointer_size = class_linker->GetImagePointerSize();
 
   ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx, pointer_size);
   if (res_method == nullptr) {
-    // Try to find the method with the appropriate lookup for the klass type (interface or not).
-    // If this lookup does not match `method_type`, errors shall be reported below.
-    if (klass->IsInterface()) {
-      res_method = klass->FindInterfaceMethod(dex_cache_.Get(), dex_method_idx, pointer_size);
-    } else {
-      res_method = klass->FindClassMethod(dex_cache_.Get(), dex_method_idx, pointer_size);
-    }
-    if (res_method != nullptr) {
-      dex_cache_->SetResolvedMethod(dex_method_idx, res_method, pointer_size);
-    }
+    res_method = class_linker->FindResolvedMethod(
+        klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx);
   }
 
   // Record result of method resolution attempt. The klass resolution has recorded whether
diff --git a/test/912-classes/src-art/art/Test912.java b/test/912-classes/src-art/art/Test912.java
index ddfadf3..1a60185 100644
--- a/test/912-classes/src-art/art/Test912.java
+++ b/test/912-classes/src-art/art/Test912.java
@@ -398,6 +398,7 @@
     public static double dummy = Math.random();  // So it can't be compile-time initialized.
   }
 
+  @SuppressWarnings("RandomCast")
   private static class TestForInitFail {
     public static int dummy = ((int)Math.random())/0;  // So it throws when initializing.
   }
diff --git a/test/983-source-transform-verify/source_transform.cc b/test/983-source-transform-verify/source_transform.cc
index dfefce2..9e65a99 100644
--- a/test/983-source-transform-verify/source_transform.cc
+++ b/test/983-source-transform-verify/source_transform.cc
@@ -14,30 +14,13 @@
  * limitations under the License.
  */
 
-#include <inttypes.h>
+#include "source_transform.h"
 
-#include <cstdio>
-#include <cstring>
-#include <iostream>
-#include <vector>
+#include "jni.h"
 
 #include "android-base/stringprintf.h"
-#include "jni.h"
 #include "jvmti.h"
-
-#include "base/macros.h"
-#include "bytecode_utils.h"
-#include "dex/code_item_accessors-inl.h"
-#include "dex/art_dex_file_loader.h"
-#include "dex/dex_file.h"
-#include "dex/dex_file_loader.h"
-#include "dex/dex_instruction.h"
-#include "jit/jit.h"
-#include "native_stack_dump.h"
-#include "runtime.h"
-#include "scoped_thread_state_change-inl.h"
-#include "thread-current-inl.h"
-#include "thread_list.h"
+#include "scoped_local_ref.h"
 
 // Test infrastructure
 #include "jvmti_helper.h"
@@ -48,9 +31,18 @@
 
 constexpr bool kSkipInitialLoad = true;
 
+static void Println(JNIEnv* env, const char* msg) {
+  ScopedLocalRef<jclass> test_klass(env, env->FindClass("art/Test983"));
+  jmethodID println_method = env->GetStaticMethodID(test_klass.get(),
+                                                    "doPrintln",
+                                                    "(Ljava/lang/String;)V");
+  ScopedLocalRef<jstring> data(env, env->NewStringUTF(msg));
+  env->CallStaticVoidMethod(test_klass.get(), println_method, data.get());
+}
+
 // The hook we are using.
 void JNICALL CheckDexFileHook(jvmtiEnv* jvmti_env ATTRIBUTE_UNUSED,
-                              JNIEnv* jni_env ATTRIBUTE_UNUSED,
+                              JNIEnv* env,
                               jclass class_being_redefined,
                               jobject loader ATTRIBUTE_UNUSED,
                               const char* name,
@@ -60,78 +52,24 @@
                               jint* new_class_data_len ATTRIBUTE_UNUSED,
                               unsigned char** new_class_data ATTRIBUTE_UNUSED) {
   if (kSkipInitialLoad && class_being_redefined == nullptr) {
-    // Something got loaded concurrently. Just ignore it for now.
+    // Something got loaded concurrently. Just ignore it for now. To make sure the test is
+    // repeatable we only care about things that come from RetransformClasses.
     return;
   }
-  std::cout << "Dex file hook for " << name << std::endl;
+  Println(env, android::base::StringPrintf("Dex file hook for %s", name).c_str());
   if (IsJVM()) {
     return;
   }
 
-  // Due to b/72402467 the class_data_len might just be an estimate.
-  CHECK_GE(static_cast<size_t>(class_data_len), sizeof(DexFile::Header));
-  const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(class_data);
-  uint32_t header_file_size = header->file_size_;
-  CHECK_LE(static_cast<jint>(header_file_size), class_data_len);
-  class_data_len = static_cast<jint>(header_file_size);
-
-  const ArtDexFileLoader dex_file_loader;
-  std::string error;
-  std::unique_ptr<const DexFile> dex(dex_file_loader.Open(class_data,
-                                                          class_data_len,
-                                                          "fake_location.dex",
-                                                          /*location_checksum*/ 0,
-                                                          /*oat_dex_file*/ nullptr,
-                                                          /*verify*/ true,
-                                                          /*verify_checksum*/ true,
-                                                          &error));
-  if (dex.get() == nullptr) {
-    std::cout << "Failed to verify dex file for " << name << " because " << error << std::endl;
-    return;
-  }
-  for (uint32_t i = 0; i < dex->NumClassDefs(); i++) {
-    const DexFile::ClassDef& def = dex->GetClassDef(i);
-    const uint8_t* data_item = dex->GetClassData(def);
-    if (data_item == nullptr) {
-      continue;
-    }
-    for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) {
-      if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) {
-        continue;
-      }
-      for (const DexInstructionPcPair& pair :
-          art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) {
-        const Instruction& inst = pair.Inst();
-        int forbiden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly);
-        if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER ||
-            (inst.GetVerifyExtraFlags() & forbiden_flags) != 0) {
-          std::cout << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex())
-                    << " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : "
-                    << inst.DumpString(dex.get()) << std::endl;
-          continue;
-        }
-      }
-    }
-  }
+  VerifyClassData(class_data_len, class_data);
 }
 
 // Get all capabilities except those related to retransformation.
-jint OnLoad(JavaVM* vm,
-            char* options ATTRIBUTE_UNUSED,
-            void* reserved ATTRIBUTE_UNUSED) {
-  if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
-    printf("Unable to get jvmti env!\n");
-    return 1;
-  }
-  SetStandardCapabilities(jvmti_env);
+extern "C" JNIEXPORT void JNICALL Java_art_Test983_setupLoadHook(JNIEnv* env, jclass) {
   jvmtiEventCallbacks cb;
   memset(&cb, 0, sizeof(cb));
   cb.ClassFileLoadHook = CheckDexFileHook;
-  if (jvmti_env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
-    printf("Unable to set class file load hook cb!\n");
-    return 1;
-  }
-  return 0;
+  JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEventCallbacks(&cb, sizeof(cb)));
 }
 
 }  // namespace Test983SourceTransformVerify
diff --git a/test/983-source-transform-verify/source_transform.h b/test/983-source-transform-verify/source_transform.h
index db9415a..2206498 100644
--- a/test/983-source-transform-verify/source_transform.h
+++ b/test/983-source-transform-verify/source_transform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
 namespace art {
 namespace Test983SourceTransformVerify {
 
-jint OnLoad(JavaVM* vm, char* options, void* reserved);
+void VerifyClassData(jint class_data_len, const unsigned char* class_data);
 
 }  // namespace Test983SourceTransformVerify
 }  // namespace art
diff --git a/test/983-source-transform-verify/source_transform_art.cc b/test/983-source-transform-verify/source_transform_art.cc
new file mode 100644
index 0000000..5353370
--- /dev/null
+++ b/test/983-source-transform-verify/source_transform_art.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "source_transform.h"
+
+#include <inttypes.h>
+
+#include <memory>
+
+#include <android-base/logging.h>
+
+#include "dex/code_item_accessors-inl.h"
+#include "dex/art_dex_file_loader.h"
+#include "dex/dex_file.h"
+#include "dex/dex_file_loader.h"
+#include "dex/dex_instruction.h"
+
+namespace art {
+namespace Test983SourceTransformVerify {
+
+// The hook we are using.
+void VerifyClassData(jint class_data_len, const unsigned char* class_data) {
+  // Due to b/72402467 the class_data_len might just be an estimate.
+  CHECK_GE(static_cast<size_t>(class_data_len), sizeof(DexFile::Header));
+  const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(class_data);
+  uint32_t header_file_size = header->file_size_;
+  CHECK_LE(static_cast<jint>(header_file_size), class_data_len);
+  class_data_len = static_cast<jint>(header_file_size);
+
+  const ArtDexFileLoader dex_file_loader;
+  std::string error;
+  std::unique_ptr<const DexFile> dex(dex_file_loader.Open(class_data,
+                                                          class_data_len,
+                                                          "fake_location.dex",
+                                                          /*location_checksum*/ 0,
+                                                          /*oat_dex_file*/ nullptr,
+                                                          /*verify*/ true,
+                                                          /*verify_checksum*/ true,
+                                                          &error));
+  CHECK(dex.get() != nullptr) << "Failed to verify dex: " << error;
+  for (uint32_t i = 0; i < dex->NumClassDefs(); i++) {
+    const DexFile::ClassDef& def = dex->GetClassDef(i);
+    const uint8_t* data_item = dex->GetClassData(def);
+    if (data_item == nullptr) {
+      continue;
+    }
+    for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) {
+      if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) {
+        continue;
+      }
+      for (const DexInstructionPcPair& pair :
+          art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) {
+        const Instruction& inst = pair.Inst();
+        int forbidden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly);
+        if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER ||
+            (inst.GetVerifyExtraFlags() & forbidden_flags) != 0) {
+          LOG(FATAL) << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex())
+                     << " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : "
+                     << inst.DumpString(dex.get()) << std::endl;
+        }
+      }
+    }
+  }
+}
+
+}  // namespace Test983SourceTransformVerify
+}  // namespace art
diff --git a/test/983-source-transform-verify/source_transform_slicer.cc b/test/983-source-transform-verify/source_transform_slicer.cc
new file mode 100644
index 0000000..abf32e7
--- /dev/null
+++ b/test/983-source-transform-verify/source_transform_slicer.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "source_transform.h"
+
+#pragma clang diagnostic push
+// slicer defines its own CHECK. b/65422458
+#pragma push_macro("CHECK")
+#undef CHECK
+
+// Slicer's headers have code that triggers these warnings. b/65298177
+#pragma clang diagnostic ignored "-Wsign-compare"
+#include "reader.h"
+
+#pragma pop_macro("CHECK")
+#pragma clang diagnostic pop
+
+namespace art {
+namespace Test983SourceTransformVerify {
+
+// The hook we are using.
+void VerifyClassData(jint class_data_len, const unsigned char* class_data) {
+  dex::Reader reader(class_data, class_data_len);
+  reader.CreateFullIr();  // This will verify all bytecode.
+}
+
+}  // namespace Test983SourceTransformVerify
+}  // namespace art
diff --git a/test/983-source-transform-verify/src/art/Test983.java b/test/983-source-transform-verify/src/art/Test983.java
index faae96a..7dc47ab 100644
--- a/test/983-source-transform-verify/src/art/Test983.java
+++ b/test/983-source-transform-verify/src/art/Test983.java
@@ -27,7 +27,15 @@
     doTest();
   }
 
+  private native static void setupLoadHook();
+
+  /* called from JNI */
+  public static void doPrintln(String str) {
+    System.out.println(str);
+  }
+
   public static void doTest() {
+    setupLoadHook();
     Redefinition.enableCommonRetransformation(true);
     Redefinition.doCommonClassRetransformation(Transform.class);
     Redefinition.doCommonClassRetransformation(Object.class);
diff --git a/test/Android.bp b/test/Android.bp
index 5f39ffe..9d44e09 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -62,7 +62,7 @@
         "libvixld-arm",
         "libvixld-arm64",
         "libart-gtest",
-        "libdexfile",
+        "libdexfiled",
 
         "libbase",
         "libicuuc",
@@ -114,7 +114,7 @@
     shared_libs: [
         "libartd",
         "libartd-compiler",
-        "libdexfile",
+        "libdexfiled",
     ],
     static_libs: [
         "libgtest",
@@ -151,7 +151,7 @@
     shared_libs: [
         "libartd",
         "libartd-compiler",
-        "libdexfile",
+        "libdexfiled",
         "libbase",
         "libbacktrace",
     ],
@@ -238,6 +238,7 @@
         "931-agent-thread/agent_thread.cc",
         "933-misc-events/misc_events.cc",
         "945-obsolete-native/obsolete_native.cc",
+        "983-source-transform-verify/source_transform.cc",
         "984-obsolete-invoke/obsolete_invoke.cc",
         "986-native-method-bind/native_bind.cc",
         "987-agent-bind/agent_bind.cc",
@@ -288,20 +289,22 @@
         "909-attach-agent/attach.cc",
         "912-classes/classes_art.cc",
         "936-search-onload/search_onload.cc",
-        "983-source-transform-verify/source_transform.cc",
+        "983-source-transform-verify/source_transform_art.cc",
         "1940-ddms-ext/ddm_ext.cc",
         "1944-sudden-exit/sudden_exit.cc",
     ],
     shared_libs: [
         "libbase",
-        "libdexfile",
     ],
 }
 
 art_cc_test_library {
     name: "libtiagent",
     defaults: ["libtiagent-defaults"],
-    shared_libs: ["libart"],
+    shared_libs: [
+        "libart",
+        "libdexfile",
+    ],
 }
 
 art_cc_test_library {
@@ -310,24 +313,32 @@
         "art_debug_defaults",
         "libtiagent-defaults",
     ],
-    shared_libs: ["libartd"],
+    shared_libs: [
+        "libartd",
+        "libdexfiled",
+    ],
 }
 
-art_cc_test_library {
+cc_library_static {
     name: "libctstiagent",
     defaults: ["libtiagent-base-defaults"],
+    host_supported: false,
+    srcs: [
+        "983-source-transform-verify/source_transform_slicer.cc",
+    ],
     whole_static_libs: [
-        "libdexfile",
-        "libz",
-        "libziparchive",
+        "slicer",
+        "libz",  // for slicer (using adler32).
     ],
     static_libs: [
         "libbase",
-        "libcutils",
-        "libutils",
     ],
-    shared_libs: [
-        "liblog",
+    header_libs: [
+        // This is needed to resolve the base/ header file in libdexfile. Unfortunately there are
+        // many problems with how we export headers that are making doing this the 'right' way
+        // difficult.
+        // TODO: move those headers to art/ rather than under runtime.
+        "libart_runtime_headers",
     ],
     export_include_dirs: ["ti-agent"],
 }
@@ -413,7 +424,6 @@
         "708-jit-cache-churn/jit.cc",
     ],
     shared_libs: [
-        "libdexfile",
         "libbacktrace",
         "libbase",
         "libnativehelper",
@@ -423,7 +433,10 @@
 art_cc_test_library {
     name: "libarttest",
     defaults: ["libarttest-defaults"],
-    shared_libs: ["libart"],
+    shared_libs: [
+        "libart",
+        "libdexfile",
+    ],
 }
 
 art_cc_test_library {
@@ -432,7 +445,10 @@
         "art_debug_defaults",
         "libarttest-defaults",
     ],
-    shared_libs: ["libartd"],
+    shared_libs: [
+        "libartd",
+        "libdexfiled",
+    ],
 }
 
 art_cc_test_library {
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index bb6ace1..b8427f4 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -850,7 +850,7 @@
     fi
 
     # System libraries needed by libarttestd.so
-    PUBLIC_LIBS=libart.so:libartd.so:libc++.so:libbacktrace.so:libdexfile.so:libbase.so:libnativehelper.so
+    PUBLIC_LIBS=libart.so:libartd.so:libc++.so:libbacktrace.so:libdexfile.so:libdexfiled.so:libbase.so:libnativehelper.so
 
     # Create a script with the command. The command can get longer than the longest
     # allowed adb command and there is no way to get the exit status from a adb shell
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index 9a7352e..bfd165d 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -28,7 +28,6 @@
 #include "901-hello-ti-agent/basics.h"
 #include "909-attach-agent/attach.h"
 #include "936-search-onload/search_onload.h"
-#include "983-source-transform-verify/source_transform.h"
 #include "1919-vminit-thread-start-timing/vminit.h"
 
 namespace art {
@@ -83,7 +82,6 @@
   { "939-hello-transformation-bcp", common_redefine::OnLoad, nullptr },
   { "941-recursive-obsolete-jit", common_redefine::OnLoad, nullptr },
   { "943-private-recursive-jit", common_redefine::OnLoad, nullptr },
-  { "983-source-transform-verify", Test983SourceTransformVerify::OnLoad, nullptr },
   { "1919-vminit-thread-start-timing", Test1919VMInitThreadStart::OnLoad, nullptr },
 };
 
diff --git a/tools/amm/AmmTest/AndroidManifest.xml b/tools/amm/AmmTest/AndroidManifest.xml
new file mode 100644
index 0000000..16529bc
--- /dev/null
+++ b/tools/amm/AmmTest/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.amm.test">
+
+  <application
+    android:label="AmmTest"
+    android:debuggable="true">
+
+    <activity android:name="com.android.amm.test.MainActivity">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>
diff --git a/tools/amm/AmmTest/aahat.png b/tools/amm/AmmTest/aahat.png
new file mode 100644
index 0000000..01b92f4
--- /dev/null
+++ b/tools/amm/AmmTest/aahat.png
Binary files differ
diff --git a/tools/amm/AmmTest/jni/ammtest.c b/tools/amm/AmmTest/jni/ammtest.c
new file mode 100644
index 0000000..9d48475
--- /dev/null
+++ b/tools/amm/AmmTest/jni/ammtest.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni.h"
+
+// A large uninitialized array gets put in the .bss section:
+char uninit[3 * 4096];
+
+// A large initialized array gets put in the .data section:
+char init[2 * 4096] =
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.."
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789..";
+
+// A large constant initialized array gets put in the .rodata section:
+const char cinit[1 * 4096] =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.."
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789..";
+
+JNIEXPORT jint JNICALL
+Java_com_android_amm_test_SoCodeUse_nGetANumber(JNIEnv* env, jclass cls) {
+  (void) env;
+  (void) cls;
+
+  uninit[4096] = init[123] + cinit[123];
+  return 42;
+}
+
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/BitmapUse.java b/tools/amm/AmmTest/src/com/android/amm/test/BitmapUse.java
new file mode 100644
index 0000000..d8eba2e
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/BitmapUse.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.amm.test;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+/**
+ * Exercise loading of a bitmap.
+ */
+class BitmapUse {
+
+  private Bitmap mBitmap;
+
+  public BitmapUse() {
+    ClassLoader loader = BitmapUse.class.getClassLoader();
+    mBitmap = BitmapFactory.decodeStream(loader.getResourceAsStream("aahat.png"), null, null);
+  }
+}
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/MainActivity.java b/tools/amm/AmmTest/src/com/android/amm/test/MainActivity.java
new file mode 100644
index 0000000..4577f4b
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/MainActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.amm.test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+
+public class MainActivity extends Activity {
+
+  private BitmapUse mBitmapUse;
+  private SoCodeUse mSoCodeUse;
+  private TextureViewUse mTextureViewUse;
+  private SurfaceViewUse mSurfaceViewUse;
+  private ThreadedRendererUse mThreadedRendererUse;
+
+  @Override
+  public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+
+    mBitmapUse = new BitmapUse();
+    mSoCodeUse = new SoCodeUse();
+
+    LinearLayout ll = new LinearLayout(this);
+    mTextureViewUse = new TextureViewUse(this, ll, 200, 500);
+    mSurfaceViewUse = new SurfaceViewUse(this, ll, 240, 250);
+    setContentView(ll);
+
+    mThreadedRendererUse = new ThreadedRendererUse(this, 122, 152);
+  }
+}
+
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/SoCodeUse.java b/tools/amm/AmmTest/src/com/android/amm/test/SoCodeUse.java
new file mode 100644
index 0000000..9636c0f
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/SoCodeUse.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.amm.test;
+
+class SoCodeUse {
+  private int value;
+
+  public SoCodeUse() {
+    // TODO: Figure out how to cause the native library to be unloaded when
+    // the SoCodeUse instance goes away?
+    System.loadLibrary("ammtestjni");
+    value = nGetANumber();
+  }
+
+  private static native int nGetANumber();
+}
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/SurfaceViewUse.java b/tools/amm/AmmTest/src/com/android/amm/test/SurfaceViewUse.java
new file mode 100644
index 0000000..0c17c77
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/SurfaceViewUse.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.amm.test;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+
+class SurfaceViewUse {
+
+  private SurfaceView mSurfaceView;
+
+  /**
+   * Constructs a SurfaceView object with given dimensions.
+   * The surface view is added to the given ViewGroup object, which should be
+   * included in the main display.
+   */
+  public SurfaceViewUse(Context context, ViewGroup vg, int width, int height) {
+    mSurfaceView = new SurfaceView(context);
+    vg.addView(mSurfaceView, width, height);
+    mSurfaceView.post(new CycleRunnable());
+  }
+
+  // To force as many graphics buffers as will ever be used to actually be
+  // used, we cycle the color of the surface view a handful of times right
+  // when things start up.
+  private class CycleRunnable implements Runnable {
+    private int mCycles = 0;
+    private int mRed = 255;
+    private int mGreen = 0;
+    private int mBlue = 255;
+
+    public void run() {
+      if (mCycles < 10) {
+        mCycles++;
+        updateSurfaceView();
+        mSurfaceView.post(this);
+      }
+    }
+
+    private void updateSurfaceView() {
+      SurfaceHolder holder = mSurfaceView.getHolder();
+      Canvas canvas = holder.lockHardwareCanvas();
+      if (canvas != null) {
+        canvas.drawRGB(mRed, mGreen, mBlue);
+        int tmp = mRed;
+        holder.unlockCanvasAndPost(canvas);
+        mRed = mGreen;
+        mGreen = mBlue;
+        mBlue = tmp;
+      }
+    }
+  }
+}
+
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/TextureViewUse.java b/tools/amm/AmmTest/src/com/android/amm/test/TextureViewUse.java
new file mode 100644
index 0000000..51ffcd2
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/TextureViewUse.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.amm.test;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.view.TextureView;
+import android.view.ViewGroup;
+
+class TextureViewUse {
+
+  private TextureView mTextureView;
+
+  /**
+   * Constructs a TextureView object with given dimensions.
+   * The texture view is added to the given ViewGroup object, which should be
+   * included in the main display.
+   */
+  public TextureViewUse(Context context, ViewGroup vg, int width, int height) {
+    mTextureView = new TextureView(context);
+    vg.addView(mTextureView, width, height);
+    mTextureView.post(new CycleRunnable());
+  }
+
+  // To force as many graphics buffers as will ever be used to actually be
+  // used, we cycle the color of the texture view a handful of times right
+  // when things start up.
+  private class CycleRunnable implements Runnable {
+    private int mCycles = 0;
+    private int mRed = 255;
+    private int mGreen = 255;
+    private int mBlue = 0;
+
+    public void run() {
+      if (mCycles < 10) {
+        mCycles++;
+        updateTextureView();
+        mTextureView.post(this);
+      }
+    }
+
+    private void updateTextureView() {
+      Canvas canvas = mTextureView.lockCanvas();
+      if (canvas != null) {
+        canvas.drawRGB(mRed, mGreen, mBlue);
+        int tmp = mRed;
+        mTextureView.unlockCanvasAndPost(canvas);
+        mRed = mGreen;
+        mGreen = mBlue;
+        mBlue = tmp;
+      }
+    }
+  }
+}
+
diff --git a/tools/amm/AmmTest/src/com/android/amm/test/ThreadedRendererUse.java b/tools/amm/AmmTest/src/com/android/amm/test/ThreadedRendererUse.java
new file mode 100644
index 0000000..9c25612
--- /dev/null
+++ b/tools/amm/AmmTest/src/com/android/amm/test/ThreadedRendererUse.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.amm.test;
+
+import android.content.Context;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+class ThreadedRendererUse {
+
+  private TextView mTextView;
+
+  /**
+   * Cause a threaded renderer EGL allocation to be used, with given
+   * dimensions.
+   */
+  public ThreadedRendererUse(Context context, int width, int height) {
+    mTextView = new TextView(context);
+    mTextView.setText("TRU");
+    mTextView.setBackgroundColor(0xffff0000);
+
+    // Adding a view to the WindowManager (as opposed to the app's root view
+    // hierarchy) causes a ThreadedRenderer and EGL allocations under the cover.
+    // We use a TextView here to trigger the use case, but we could use any
+    // other kind of view as well.
+    WindowManager wm = context.getSystemService(WindowManager.class);
+    WindowManager.LayoutParams layout = new WindowManager.LayoutParams();
+    layout.width = width;
+    layout.height = height;
+    wm.addView(mTextView, layout);
+
+    mTextView.post(new CycleRunnable());
+  }
+
+  // To force as many graphics buffers as will ever be used to actually be
+  // used, we cycle the text of the text view a handful of times right
+  // when things start up.
+  private class CycleRunnable implements Runnable {
+    private int mCycles = 0;
+
+    public void run() {
+      if (mCycles < 10) {
+        mCycles++;
+        mTextView.setText("TRU " + mCycles);
+        mTextView.post(this);
+      }
+    }
+  }
+}
+
diff --git a/tools/amm/Android.mk b/tools/amm/Android.mk
new file mode 100644
index 0000000..47030c5
--- /dev/null
+++ b/tools/amm/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# --- ammtestjni.so -------------
+include $(CLEAR_VARS)
+LOCAL_MODULE := libammtestjni
+LOCAL_SRC_FILES := $(call all-c-files-under, AmmTest/jni)
+LOCAL_SDK_VERSION := current
+include $(BUILD_SHARED_LIBRARY)
+
+# --- AmmTest.apk --------------
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := AmmTest
+LOCAL_MODULE_TAGS := samples tests
+LOCAL_SRC_FILES := $(call all-java-files-under, AmmTest/src)
+LOCAL_SDK_VERSION := current
+LOCAL_JNI_SHARED_LIBRARIES := libammtestjni
+LOCAL_JAVA_RESOURCE_FILES := $(LOCAL_PATH)/AmmTest/aahat.png
+LOCAL_MANIFEST_FILE := AmmTest/AndroidManifest.xml
+include $(BUILD_PACKAGE)
+
diff --git a/tools/amm/README.md b/tools/amm/README.md
new file mode 100644
index 0000000..17f94a8
--- /dev/null
+++ b/tools/amm/README.md
@@ -0,0 +1,16 @@
+# Actionable Memory Metric
+
+The goal of the actionable memory metric (AMM) is to provide a view of an
+application's memory use that application developers can track, understand,
+and control. AMM can be thought of as a Java heap dump augmented with models
+for non-Java allocations that app developers have some control of.
+
+There are two components of the actionable memory metric:
+1. The value of the metric.
+2. An actionable breakdown of the value of the metric.
+
+The metric is made up of a collection of separate models for different
+categories of memory use. Each model contributes to the value and actionable
+breakdown of the overall metric.
+
+See models/ for a list of models proposed for the actionable memory metric.
diff --git a/tools/amm/models/Bitmap.md b/tools/amm/models/Bitmap.md
new file mode 100644
index 0000000..49a0b9d
--- /dev/null
+++ b/tools/amm/models/Bitmap.md
@@ -0,0 +1,15 @@
+# Bitmap Model
+
+The value of the Bitmap model is the sum of bytes used for native pixel data
+of instances of `android.graphics.Bitmap`. It is calculated by summing for
+each instance `x` of `android.graphics.Bitmap`:
+
+    x.getAllocationByteCount()
+
+The actionable breakdown of the Bitmap model is a breakdown by
+`android.graphics.Bitmap` instance, including width, height, and ideally a
+thumbnail image of each bitmap.
+
+For example, an 800 x 600 bitmap instance using the `ARGB_8888` pixel format
+with native pixel data will be shown as an 800 x 600 bitmap instance taking up
+1875 kB.
diff --git a/tools/amm/models/DexCode.md b/tools/amm/models/DexCode.md
new file mode 100644
index 0000000..a907280
--- /dev/null
+++ b/tools/amm/models/DexCode.md
@@ -0,0 +1,17 @@
+# Dex Code Model
+
+The value of the Dex Code model is the sum of the original uncompressed file
+sizes of all loaded dex files. It is calculated using the best approximation
+of the dex file size available to us on device. On Android O, for example,
+this can be approximated as the virtual size of the corresponding memory
+mapped `.vdex` file read from `/proc/self/maps`. Different Android platform
+versions and scenarios may require different approximations.
+
+The actionable breakdown of the dex code model is a breakdown by
+`dalvik.system.DexFile` instance. Further breakdown of individual dex files
+can be achieved using tools such as dexdump.
+
+For example, for an application `AmmTest.apk` that has a single `classes.dex` file
+that is 500 KB uncompressed, the `DexFile` instance for
+`/data/app/com.android.amm.test-_uHI4CJWpeoztbjN6Tr-Nw==/base.apk` is shown as
+Taking up 500 KB (or the best available approximation thereof).
diff --git a/tools/amm/models/Graphics.md b/tools/amm/models/Graphics.md
new file mode 100644
index 0000000..b327961
--- /dev/null
+++ b/tools/amm/models/Graphics.md
@@ -0,0 +1,22 @@
+# Graphics Models
+
+There are three components to the graphics model, each modeling EGL memory
+use:
+1. For each `android.view.TextureView` instance:
+    2 * (4 * width * height)
+
+2. For each `android.view.Surface$HwuiContext` instance:
+    3 * (4 * width * height)
+
+3. For each initialized `android.view.ThreadedRenderer`:
+    3 * (4 * width * height)
+
+Note: 4 is the number of bytes per pixel. 2 or 3 is the maximum number of
+buffers that may be allocated.
+
+The actionable breakdown is the breakdown by `TextureView`,
+`Surface$HwuiContext` and `ThreadedRenderer` instance, with further details
+about the width and height associated with each instance.
+
+For example, an application with a single 64x256 `TextureView` instance will
+be shown as taking up 128 KB.
diff --git a/tools/amm/models/JavaHeap.md b/tools/amm/models/JavaHeap.md
new file mode 100644
index 0000000..c34c186
--- /dev/null
+++ b/tools/amm/models/JavaHeap.md
@@ -0,0 +1,8 @@
+# Java Heap Model
+
+The value of the Java heap model is the sum of bytes of Java objects allocated
+on the Java heap. It can be calculated using:
+
+    Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
+
+A Java heap dump is used for an actionable breakdown of the Java heap.
diff --git a/tools/amm/models/SoCode.md b/tools/amm/models/SoCode.md
new file mode 100644
index 0000000..5d3184e
--- /dev/null
+++ b/tools/amm/models/SoCode.md
@@ -0,0 +1,17 @@
+# Shared Native Code Model
+
+The value of the Shared Native Code model is the sum of the virtual memory
+sizes of all loaded `.so` files. It is calculated by reading `/proc/self/maps`.
+
+The actionable breakdown of the shared native code model is a breakdown by
+library name. Unfortunately, due to technical limitations, this does not
+include information about what caused a library to be loaded, whether the
+library was loaded by the app or the platform, the library dependency graph,
+or what is causing a library to remain loaded. Individual `.so` files can be
+further broken down using tools such as `readelf`.
+
+For example, for an application `AmmTest.apk` that includes `libammtestjni.so` as a
+native library that loads 36 KB worth of memory regions, `BaseClassLoader` will
+be shown with library
+`/data/app/com.android.amm.test-_uHI4CJWpeoztbjN6Tr-Nw==/lib/arm64/libammtestjni.so`
+taking up 36 KB.
diff --git a/tools/hiddenapi/Android.bp b/tools/hiddenapi/Android.bp
index f9824f1..af87d31 100644
--- a/tools/hiddenapi/Android.bp
+++ b/tools/hiddenapi/Android.bp
@@ -30,7 +30,6 @@
     },
 
     shared_libs: [
-        "libdexfile",
         "libbase",
     ],
 }
@@ -40,6 +39,7 @@
     defaults: ["hiddenapi-defaults"],
     shared_libs: [
         "libart",
+        "libdexfile",
     ],
 }
 
@@ -51,6 +51,7 @@
     ],
     shared_libs: [
         "libartd",
+        "libdexfiled",
     ],
 }
 
diff --git a/tools/public.libraries.buildbot.txt b/tools/public.libraries.buildbot.txt
index 734fd1e..de636a8 100644
--- a/tools/public.libraries.buildbot.txt
+++ b/tools/public.libraries.buildbot.txt
@@ -1,6 +1,7 @@
 libart.so
 libartd.so
 libdexfile.so
+libdexfiled.so
 libbacktrace.so
 libc.so
 libc++.so