Add layout scheme to dexlayout for dex file reordering.

Currently takes startup classes from profile and groups them together
with the lowest class indexes. Moves the ClassDef, ClassData, and
CodeItem sections.

Results gathered from 5 second systrace of app startup (no other input):
Maps
base.vdex - 24.70MB -> 19.35MB (30.50MB file size)
base.odex - 13.22MB -> 12.82MB (13.22MB file size)
Running time of dex2oat: 27.5s -> 37.1s

Photos
base.vdex - 12.98MB ->  9.77MB (15.10MB file size)
base.odex -  6.84MB ->  6.24MB ( 6.84MB file size)
Running time of dex2oat: 15.6s -> 19.9s

Plus
base.vdex - 14.09MB -> 13.29MB (16.72MB file size)
base.odex -  2.47MB ->  2.47MB ( 2.47MB file size)
Running time of dex2oat: 14.1s -> 18.5s

Performance and memory tracking bug: b/33017139

Test: mm test-art-host-gtest-dexlayout_test
Bug: 29921113
Change-Id: Ib500ed353d71a606e2db0dd80378750c5f7b8e33
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 2f34019..714a58c 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -552,8 +552,7 @@
   RunTest(CompilerFilter::kSpeed, true, { "--very-large-app-threshold=100" });
 }
 
-static const char kDexFileLayoutInputProfile[] =
-    "cHJvADAwMgABAAsAAAABAPUpbf5jbGFzc2VzLmRleAEA";
+static const char kDexFileLayoutInputProfile[] = "cHJvADAwMgABAAwAAQABAOqMEeFEZXhOb09hdC5qYXIBAAEA";
 
 static void WriteFileBase64(const char* base64, const char* location) {
   // Decode base64.
@@ -608,11 +607,26 @@
                                                      &error_msg));
     ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
 
+    const char* location = dex_location.c_str();
+    std::vector<std::unique_ptr<const DexFile>> dex_files;
+    ASSERT_TRUE(DexFile::Open(location, location, true, &error_msg, &dex_files));
+    EXPECT_EQ(dex_files.size(), 1U);
+    std::unique_ptr<const DexFile>& old_dex_file = dex_files[0];
+
     for (const OatDexFile* oat_dex_file : odex_file->GetOatDexFiles()) {
-      std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
-      ASSERT_TRUE(dex_file != nullptr);
-      uint32_t class_def_count = dex_file->NumClassDefs();
+      std::unique_ptr<const DexFile> new_dex_file = oat_dex_file->OpenDexFile(&error_msg);
+      ASSERT_TRUE(new_dex_file != nullptr);
+      uint32_t class_def_count = new_dex_file->NumClassDefs();
       ASSERT_LT(class_def_count, std::numeric_limits<uint16_t>::max());
+      ASSERT_GE(class_def_count, 2U);
+
+      // The new layout swaps the classes at indexes 0 and 1.
+      std::string old_class0 = old_dex_file->PrettyType(old_dex_file->GetClassDef(0).class_idx_);
+      std::string old_class1 = old_dex_file->PrettyType(old_dex_file->GetClassDef(1).class_idx_);
+      std::string new_class0 = new_dex_file->PrettyType(new_dex_file->GetClassDef(0).class_idx_);
+      std::string new_class1 = new_dex_file->PrettyType(new_dex_file->GetClassDef(1).class_idx_);
+      EXPECT_EQ(old_class0, new_class1);
+      EXPECT_EQ(old_class1, new_class0);
     }
 
     EXPECT_EQ(odex_file->GetCompilerFilter(), CompilerFilter::kLayoutProfile);