Disable compact dex code item deduping.

It conflicts with thread interpreter cache, where the interpreter
expects that once an entry is in the cache, it doesn't need to
perform access checks again.

Test: 536-checker-needs-access-check
Bug: 191252775
Change-Id: I65999abc8afe31e4f4bf2ca403432d6cd8be70ee
diff --git a/dexlayout/compact_dex_writer.cc b/dexlayout/compact_dex_writer.cc
index a7dad07..b8c6ebe 100644
--- a/dexlayout/compact_dex_writer.cc
+++ b/dexlayout/compact_dex_writer.cc
@@ -34,9 +34,8 @@
   return dex_layout_->GetOptions().compact_dex_level_;
 }
 
-CompactDexWriter::Container::Container(bool dedupe_code_items)
-    : code_item_dedupe_(dedupe_code_items, &data_section_),
-      data_item_dedupe_(/*enabled=*/ true, &data_section_) {}
+CompactDexWriter::Container::Container()
+    : data_item_dedupe_(&data_section_) {}
 
 uint32_t CompactDexWriter::WriteDebugInfoOffsetTable(Stream* stream) {
   const uint32_t start_offset = stream->Tell();
@@ -117,7 +116,10 @@
 }
 
 CompactDexWriter::ScopedDataSectionItem::~ScopedDataSectionItem() {
-  // After having written, maybe dedupe the whole code item (excluding padding).
+  if (deduper_ == nullptr) {
+    return;
+  }
+  // After having written, maybe dedupe the whole section (excluding padding).
   const uint32_t deduped_offset = deduper_->Dedupe(start_offset_,
                                                    stream_->Tell(),
                                                    item_->GetOffset());
@@ -145,7 +147,7 @@
   ScopedDataSectionItem data_item(stream,
                                   code_item,
                                   CompactDexFile::CodeItem::kAlignment,
-                                  code_item_dedupe_);
+                                  /* deduper= */ nullptr);
 
   CompactDexFile::CodeItem disk_code_item;
 
@@ -209,18 +211,14 @@
 }
 
 
-CompactDexWriter::Deduper::Deduper(bool enabled, DexContainer::Section* section)
-    : enabled_(enabled),
-      dedupe_map_(/*__n=*/ 32,
+CompactDexWriter::Deduper::Deduper(DexContainer::Section* section)
+    : dedupe_map_(/*__n=*/ 32,
                   HashedMemoryRange::HashEqual(section),
                   HashedMemoryRange::HashEqual(section)) {}
 
 uint32_t CompactDexWriter::Deduper::Dedupe(uint32_t data_start,
                                            uint32_t data_end,
                                            uint32_t item_offset) {
-  if (!enabled_) {
-    return kDidNotDedupe;
-  }
   HashedMemoryRange range {data_start, data_end - data_start};
   auto existing = dedupe_map_.emplace(range, item_offset);
   if (!existing.second) {
@@ -397,7 +395,6 @@
   data_stream->Seek(std::max(
       static_cast<uint32_t>(output->GetDataSection()->Size()),
       kDataSectionAlignment));
-  code_item_dedupe_ = &container->code_item_dedupe_;
   data_item_dedupe_ = &container->data_item_dedupe_;
 
   // Starting offset is right after the header.
@@ -521,17 +518,11 @@
     WriteHeader(main_stream);
   }
 
-  // Clear the dedupe to prevent interdex code item deduping. This does not currently work well with
-  // dex2oat's class unloading. The issue is that verification encounters quickened opcodes after
-  // the first dex gets unloaded.
-  code_item_dedupe_->Clear();
-
   return true;
 }
 
 std::unique_ptr<DexContainer> CompactDexWriter::CreateDexContainer() const {
-  return std::unique_ptr<DexContainer>(
-      new CompactDexWriter::Container(dex_layout_->GetOptions().dedupe_code_items_));
+  return std::unique_ptr<DexContainer>(new CompactDexWriter::Container());
 }
 
 }  // namespace art
diff --git a/dexlayout/compact_dex_writer.h b/dexlayout/compact_dex_writer.h
index c81d0c7..d78f8be 100644
--- a/dexlayout/compact_dex_writer.h
+++ b/dexlayout/compact_dex_writer.h
@@ -37,8 +37,7 @@
    public:
     static const uint32_t kDidNotDedupe = 0;
 
-    // if not enabled, Dedupe will always return kDidNotDedupe.
-    explicit Deduper(bool enabled, DexContainer::Section* section);
+    explicit Deduper(DexContainer::Section* section);
 
     // Deduplicate a blob of data that has been written to mem_map.
     // Returns the offset of the deduplicated data or kDidNotDedupe did deduplication did not occur.
@@ -85,8 +84,6 @@
       };
     };
 
-    const bool enabled_;
-
     // Dedupe map.
     std::unordered_map<HashedMemoryRange,
                        uint32_t,
@@ -125,11 +122,10 @@
     }
 
    private:
-    explicit Container(bool dedupe_code_items);
+    Container();
 
     VectorSection main_section_;
     VectorSection data_section_;
-    Deduper code_item_dedupe_;
     Deduper data_item_dedupe_;
 
     friend class CompactDexWriter;
@@ -173,8 +169,6 @@
   uint32_t owned_data_begin_ = 0u;
   uint32_t owned_data_end_ = 0u;
 
-  // State for where we are deduping.
-  Deduper* code_item_dedupe_ = nullptr;
   Deduper* data_item_dedupe_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(CompactDexWriter);
diff --git a/dexlayout/dexlayout.h b/dexlayout/dexlayout.h
index 60076bf..9bb7b8b 100644
--- a/dexlayout/dexlayout.h
+++ b/dexlayout/dexlayout.h
@@ -67,7 +67,6 @@
   bool visualize_pattern_ = false;
   bool update_checksum_ = false;
   CompactDexLevel compact_dex_level_ = CompactDexLevel::kCompactDexLevelNone;
-  bool dedupe_code_items_ = true;
   OutputFormat output_format_ = kOutputPlain;
   const char* output_dex_directory_ = nullptr;
   const char* output_file_name_ = nullptr;
diff --git a/libdexfile/dex/compact_dex_file.h b/libdexfile/dex/compact_dex_file.h
index f5cd924..9a12f4a 100644
--- a/libdexfile/dex/compact_dex_file.h
+++ b/libdexfile/dex/compact_dex_file.h
@@ -27,7 +27,8 @@
 class CompactDexFile : public DexFile {
  public:
   static constexpr uint8_t kDexMagic[kDexMagicSize] = { 'c', 'd', 'e', 'x' };
-  static constexpr uint8_t kDexMagicVersion[] = {'0', '0', '1', '\0'};
+  // Last change: remove code item deduping.
+  static constexpr uint8_t kDexMagicVersion[] = {'0', '0', '2', '\0'};
 
   enum class FeatureFlags : uint32_t {
     kDefaultMethods = 0x1,
diff --git a/test/536-checker-needs-access-check/src/Main.java b/test/536-checker-needs-access-check/src/Main.java
index 0dc2ab1..bb402e5 100644
--- a/test/536-checker-needs-access-check/src/Main.java
+++ b/test/536-checker-needs-access-check/src/Main.java
@@ -51,6 +51,11 @@
 
         InaccessibleClassProxy.testGetReferrersClass();
         InaccessibleClassProxy.testGetReferrersClassViaAnotherClass();
+
+        // Execute again now that classes have been initialized, and entrypoints may have been
+        // updated.
+        InaccessibleClassProxy.testGetReferrersClass();
+        InaccessibleClassProxy.testGetReferrersClassViaAnotherClass();
     }
 
     /// CHECK-START: boolean Main.testInstanceOf() register (after)