Revert "Revert "Reduce dirty image pages by improving binning""

This reverts commit 8ace610a222892f7b700e4f95e50fa6315ab85c0.

(cherry picked from commit 80c563ba136fd8da8791cf0f1a5f8f7026816ead)

Change-Id: I5b312f41d8b96eb189ea8b9d3a3ab861c5c9d515
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index c747ffa..8bb462c 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -576,7 +576,16 @@
       }
     } else if (object->GetClass<kVerifyNone>()->IsStringClass()) {
       bin = kBinString;  // Strings are almost always immutable (except for object header).
-    }  // else bin = kBinRegular
+    } else if (object->GetClass<kVerifyNone>() ==
+        Runtime::Current()->GetClassLinker()->GetClassRoot(ClassLinker::kJavaLangObject)) {
+      // Instance of java lang object, probably a lock object. This means it will be dirty when we
+      // synchronize on it.
+      bin = kBinMiscDirty;
+    } else if (object->IsDexCache()) {
+      // Dex file field becomes dirty when the image is loaded.
+      bin = kBinMiscDirty;
+    }
+    // else bin = kBinRegular
   }
 
   size_t oat_index = GetOatIndex(object);
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index f204b28..0cb6aea 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -149,16 +149,17 @@
   void RecordImageAllocations() SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Classify different kinds of bins that objects end up getting packed into during image writing.
+  // Ordered from dirtiest to cleanest (until ArtMethods).
   enum Bin {
-    // Likely-clean:
-    kBinString,                        // [String] Almost always immutable (except for obj header).
+    kBinMiscDirty,                // Dex caches, object locks, etc...
+    kBinClassVerified,            // Class verified, but initializers haven't been run
     // Unknown mix of clean/dirty:
     kBinRegular,
-    // Likely-dirty:
+    kBinClassInitialized,         // Class initializers have been run
     // All classes get their own bins since their fields often dirty
     kBinClassInitializedFinalStatics,  // Class initializers have been run, no non-final statics
-    kBinClassInitialized,         // Class initializers have been run
-    kBinClassVerified,            // Class verified, but initializers haven't been run
+    // Likely-clean:
+    kBinString,                        // [String] Almost always immutable (except for obj header).
     // Add more bins here if we add more segregation code.
     // Non mirror fields must be below.
     // ArtFields should be always clean.
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index c2a812e..cbd0c40 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -416,7 +416,8 @@
     // Look up local classes by their descriptor
     std::map<std::string, mirror::Class*> local_class_map;
 
-    std::unordered_set<mirror::Object*> dirty_objects;
+    // Use set to have sorted output.
+    std::set<mirror::Object*> dirty_objects;
 
     size_t dirty_object_bytes = 0;
     const uint8_t* begin_image_ptr = image_begin_unaligned;