Re-generate dex IR to verify dex file

Instead of using the existing IR, re-generate it to catch possible
bugs writing the output dex.

Test: test-art-host
Bug: 63756964
Change-Id: Ib63f3137f5807ee5de1b05f8278137a3b3a3aee0
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 1c966c1..9a2ab66 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -2022,25 +2022,6 @@
   if (new_file != nullptr) {
     UNUSED(new_file->FlushCloseOrErase());
   }
-  // Verify the output dex file's structure for debug builds.
-  if (kIsDebugBuild) {
-    std::string location = "memory mapped file for " + dex_file_location;
-    std::unique_ptr<const DexFile> output_dex_file(DexFileLoader::Open(mem_map_->Begin(),
-                                                                       mem_map_->Size(),
-                                                                       location,
-                                                                       header_->Checksum(),
-                                                                       /*oat_dex_file*/ nullptr,
-                                                                       /*verify*/ true,
-                                                                       /*verify_checksum*/ false,
-                                                                       &error_msg));
-    DCHECK(output_dex_file != nullptr) << " Failed to re-open output file:" << error_msg;
-  }
-  // Do IR-level comparison between input and output. This check ignores potential differences
-  // due to layout, so offsets are not checked. Instead, it checks the data contents of each item.
-  if (kIsDebugBuild || options_.verify_output_) {
-    std::unique_ptr<dex_ir::Header> orig_header(dex_ir::DexIrBuilder(*dex_file));
-    CHECK(VerifyOutputDexFile(orig_header.get(), header_, &error_msg)) << error_msg;
-  }
 }
 
 /*
@@ -2072,12 +2053,38 @@
     DumpDexFile();
   }
 
-  // Output dex file as file or memmap.
+  // In case we are outputting to a file, keep it open so we can verify.
   if (options_.output_dex_directory_ != nullptr || options_.output_to_memmap_) {
     if (info_ != nullptr) {
       LayoutOutputFile(dex_file);
     }
     OutputDexFile(dex_file);
+
+    // Clear header before verifying to reduce peak RAM usage.
+    header.reset();
+
+    // Verify the output dex file's structure, only enabled by default for debug builds.
+    if (options_.verify_output_) {
+      std::string error_msg;
+      std::string location = "memory mapped file for " + std::string(file_name);
+      std::unique_ptr<const DexFile> output_dex_file(DexFileLoader::Open(mem_map_->Begin(),
+                                                                         mem_map_->Size(),
+                                                                         location,
+                                                                         /* checksum */ 0,
+                                                                         /*oat_dex_file*/ nullptr,
+                                                                         /*verify*/ true,
+                                                                         /*verify_checksum*/ false,
+                                                                         &error_msg));
+      CHECK(output_dex_file != nullptr) << "Failed to re-open output file:" << error_msg;
+
+      // Do IR-level comparison between input and output. This check ignores potential differences
+      // due to layout, so offsets are not checked. Instead, it checks the data contents of each item.
+      //
+      // Regenerate output IR to catch any bugs that might happen during writing.
+      std::unique_ptr<dex_ir::Header> output_header(dex_ir::DexIrBuilder(*output_dex_file));
+      std::unique_ptr<dex_ir::Header> orig_header(dex_ir::DexIrBuilder(*dex_file));
+      CHECK(VerifyOutputDexFile(output_header.get(), orig_header.get(), &error_msg)) << error_msg;
+    }
   }
 }
 
diff --git a/dexlayout/dexlayout.h b/dexlayout/dexlayout.h
index 57d273e..2e89773 100644
--- a/dexlayout/dexlayout.h
+++ b/dexlayout/dexlayout.h
@@ -60,7 +60,7 @@
   bool show_section_headers_ = false;
   bool show_section_statistics_ = false;
   bool verbose_ = false;
-  bool verify_output_ = false;
+  bool verify_output_ = kIsDebugBuild;
   bool visualize_pattern_ = false;
   CompactDexLevel compact_dex_level_ = CompactDexLevel::kCompactDexLevelNone;
   OutputFormat output_format_ = kOutputPlain;