Remove code size from OatQuickMethodHeader

This saves from 0.75% from oat file size.

Bug: 123510633
Change-Id: Ibf0d45d5d84057ee45a3584a4b69a7c0487443bf
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 07c73c9..2046f4f 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -66,7 +66,7 @@
     ArrayRef<const uint8_t> vmap_table = compiled_method->GetVmapTable();
     const uint32_t vmap_table_offset = vmap_table.empty() ? 0u
         : sizeof(OatQuickMethodHeader) + vmap_table.size();
-    OatQuickMethodHeader method_header(vmap_table_offset, code_size);
+    OatQuickMethodHeader method_header(vmap_table_offset);
 
     header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
     std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index f978cc6..48d1ed6 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -93,7 +93,7 @@
       AlignUp(&fake_header_code_and_maps_[stack_maps_size + header_size], code_alignment);
 
     memcpy(&fake_header_code_and_maps_[0], stack_map.data(), stack_maps_size);
-    OatQuickMethodHeader method_header(code_ptr - fake_header_code_and_maps_.data(), code_size);
+    OatQuickMethodHeader method_header(code_ptr - fake_header_code_and_maps_.data());
     static_assert(std::is_trivially_copyable<OatQuickMethodHeader>::value, "Cannot use memcpy");
     memcpy(code_ptr - header_size, &method_header, header_size);
     memcpy(code_ptr, fake_code_.data(), fake_code_.size());
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index be9a0cb..2f11f8e 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -1319,18 +1319,16 @@
     // Update quick method header.
     DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size());
     OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_];
-    uint32_t vmap_table_offset = method_header->GetVmapTableOffset();
-    // The code offset was 0 when the mapping/vmap table offset was set, so it's set
-    // to 0-offset and we need to adjust it by code_offset.
+    uint32_t code_info_offset = method_header->GetVmapTableOffset();
     uint32_t code_offset = quick_code_offset - thumb_offset;
     CHECK(!compiled_method->GetQuickCode().empty());
     // If the code is compiled, we write the offset of the stack map relative
-    // to the code.
-    if (vmap_table_offset != 0u) {
-      vmap_table_offset += code_offset;
-      DCHECK_LT(vmap_table_offset, code_offset);
+    // to the code. The offset was previously stored relative to start of file.
+    if (code_info_offset != 0u) {
+      DCHECK_LT(code_info_offset, code_offset);
+      code_info_offset = code_offset - code_info_offset;
     }
-    *method_header = OatQuickMethodHeader(vmap_table_offset, code_size);
+    *method_header = OatQuickMethodHeader(code_info_offset);
 
     if (!deduped) {
       // Update offsets. (Checksum is updated when writing.)
@@ -1462,9 +1460,9 @@
           // Deduplicate the inner BitTable<>s within the CodeInfo.
           return offset_ + dedupe_bit_table_.Dedupe(map.data());
         });
-        // Code offset is not initialized yet, so set the map offset to 0u-offset.
+        // Code offset is not initialized yet, so set file offset for now.
         DCHECK_EQ(oat_class->method_offsets_[method_offsets_index_].code_offset_, 0u);
-        oat_class->method_headers_[method_offsets_index_].SetVmapTableOffset(0u - offset);
+        oat_class->method_headers_[method_offsets_index_].SetVmapTableOffset(offset);
       }
       ++method_offsets_index_;
     }
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index ecf9db8..db0a1e5 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -468,7 +468,7 @@
   // it is time to update OatHeader::kOatVersion
   EXPECT_EQ(64U, sizeof(OatHeader));
   EXPECT_EQ(4U, sizeof(OatMethodOffsets));
-  EXPECT_EQ(8U, sizeof(OatQuickMethodHeader));
+  EXPECT_EQ(4U, sizeof(OatQuickMethodHeader));
   EXPECT_EQ(166 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)),
             sizeof(QuickEntryPoints));
 }
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index c3abe6c..14ff1ae 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1247,65 +1247,45 @@
     }
     {
       vios->Stream() << "CODE: ";
-      uint32_t code_size_offset = oat_method.GetQuickCodeSizeOffset();
-      if (code_size_offset > oat_file_.Size()) {
-        ScopedIndentation indent2(vios);
+      const void* code = oat_method.GetQuickCode();
+      uint32_t aligned_code_begin = AlignCodeOffset(code_offset);
+      uint64_t aligned_code_end = aligned_code_begin + code_size;
+      if (AddStatsObject(code)) {
+        stats_.Child("Code")->AddBytes(code_size);
+      }
+
+      if (options_.absolute_addresses_) {
+        vios->Stream() << StringPrintf("%p ", code);
+      }
+      vios->Stream() << StringPrintf("(code_offset=0x%08x size=%u)%s\n",
+                                     code_offset,
+                                     code_size,
+                                     code != nullptr ? "..." : "");
+
+      ScopedIndentation indent2(vios);
+      if (aligned_code_begin > oat_file_.Size()) {
         vios->Stream() << StringPrintf("WARNING: "
-                                       "code size offset 0x%08x is past end of file 0x%08zx.",
-                                       code_size_offset, oat_file_.Size());
+                                       "start of code at 0x%08x is past end of file 0x%08zx.",
+                                       aligned_code_begin, oat_file_.Size());
         success = false;
-      } else {
-        const void* code = oat_method.GetQuickCode();
-        uint32_t aligned_code_begin = AlignCodeOffset(code_offset);
-        uint64_t aligned_code_end = aligned_code_begin + code_size;
-        if (AddStatsObject(code)) {
-          stats_.Child("Code")->AddBytes(code_size);
-        }
-
-        if (options_.absolute_addresses_) {
-          vios->Stream() << StringPrintf("%p ", code);
-        }
-        vios->Stream() << StringPrintf("(code_offset=0x%08x size_offset=0x%08x size=%u)%s\n",
-                                       code_offset,
-                                       code_size_offset,
-                                       code_size,
-                                       code != nullptr ? "..." : "");
-
-        ScopedIndentation indent2(vios);
-        if (aligned_code_begin > oat_file_.Size()) {
-          vios->Stream() << StringPrintf("WARNING: "
-                                         "start of code at 0x%08x is past end of file 0x%08zx.",
-                                         aligned_code_begin, oat_file_.Size());
-          success = false;
-        } else if (aligned_code_end > oat_file_.Size()) {
-          vios->Stream() << StringPrintf(
-              "WARNING: "
-              "end of code at 0x%08" PRIx64 " is past end of file 0x%08zx. "
-              "code size is 0x%08x loaded from offset 0x%08x.\n",
-              aligned_code_end, oat_file_.Size(),
-              code_size, code_size_offset);
-          success = false;
-          if (options_.disassemble_code_) {
-            if (code_size_offset + kPrologueBytes <= oat_file_.Size()) {
-              DumpCode(vios, oat_method, code_item_accessor, true, kPrologueBytes);
-            }
-          }
-        } else if (code_size > kMaxCodeSize) {
-          vios->Stream() << StringPrintf(
-              "WARNING: "
-              "code size %d is bigger than max expected threshold of %d. "
-              "code size is 0x%08x loaded from offset 0x%08x.\n",
-              code_size, kMaxCodeSize,
-              code_size, code_size_offset);
-          success = false;
-          if (options_.disassemble_code_) {
-            if (code_size_offset + kPrologueBytes <= oat_file_.Size()) {
-              DumpCode(vios, oat_method, code_item_accessor, true, kPrologueBytes);
-            }
-          }
-        } else if (options_.disassemble_code_) {
-          DumpCode(vios, oat_method, code_item_accessor, !success, 0);
-        }
+      } else if (aligned_code_end > oat_file_.Size()) {
+        vios->Stream() << StringPrintf(
+            "WARNING: "
+            "end of code at 0x%08" PRIx64 " is past end of file 0x%08zx. "
+            "code size is 0x%08x.\n",
+            aligned_code_end, oat_file_.Size(),
+            code_size);
+        success = false;
+      } else if (code_size > kMaxCodeSize) {
+        vios->Stream() << StringPrintf(
+            "WARNING: "
+            "code size %d is bigger than max expected threshold of %d. "
+            "code size is 0x%08x.\n",
+            code_size, kMaxCodeSize,
+            code_size);
+        success = false;
+      } else if (options_.disassemble_code_) {
+        DumpCode(vios, oat_method, code_item_accessor, !success, 0);
       }
     }
     vios->Stream() << std::flush;
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index c1b9a1a..a9823e5 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -990,8 +990,7 @@
     }
 
     new (method_header) OatQuickMethodHeader(
-        (stack_map != nullptr) ? code_ptr - stack_map : 0u,
-        code_size);
+        (stack_map != nullptr) ? code_ptr - stack_map : 0u);
 
     DCHECK(!Runtime::Current()->IsAotCompiler());
     if (has_should_deoptimize_flag) {
diff --git a/runtime/oat.h b/runtime/oat.h
index b824729..bd4a6e3 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -31,8 +31,8 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
-  // Last oat version changed reason: Add code size to CodeInfo.
-  static constexpr uint8_t kOatVersion[] = { '1', '6', '7', '\0' };
+  // Last oat version changed reason: Remove code size from OatQuickMethodHeader.
+  static constexpr uint8_t kOatVersion[] = { '1', '6', '8', '\0' };
 
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
   static constexpr const char* kDebuggableKey = "debuggable";
diff --git a/runtime/oat_file-inl.h b/runtime/oat_file-inl.h
index b71c4e8..6ff86b8 100644
--- a/runtime/oat_file-inl.h
+++ b/runtime/oat_file-inl.h
@@ -41,14 +41,6 @@
   return reinterpret_cast<const uint8_t*>(method_header) - begin_;
 }
 
-inline uint32_t OatFile::OatMethod::GetQuickCodeSizeOffset() const {
-  const OatQuickMethodHeader* method_header = GetOatQuickMethodHeader();
-  if (method_header == nullptr) {
-    return 0u;
-  }
-  return reinterpret_cast<const uint8_t*>(method_header->GetCodeSizeAddr()) - begin_;
-}
-
 inline size_t OatFile::OatMethod::GetFrameSizeInBytes() const {
   const void* code = EntryPointToCodePointer(GetQuickCode());
   if (code == nullptr) {
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 04b666c..e2c6633 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -155,7 +155,6 @@
 
     // Returns size of quick code.
     uint32_t GetQuickCodeSize() const;
-    uint32_t GetQuickCodeSizeOffset() const;
 
     // Returns OatQuickMethodHeader for debugging. Most callers should
     // use more specific methods such as GetQuickCodeSize.
diff --git a/runtime/oat_quick_method_header.h b/runtime/oat_quick_method_header.h
index 6c123c4..745be40 100644
--- a/runtime/oat_quick_method_header.h
+++ b/runtime/oat_quick_method_header.h
@@ -31,12 +31,8 @@
 class PACKED(4) OatQuickMethodHeader {
  public:
   OatQuickMethodHeader() = default;
-  OatQuickMethodHeader(uint32_t vmap_table_offset,
-                       uint32_t code_size)
-      : vmap_table_offset_(vmap_table_offset),
-        code_size_(code_size) {
-    DCHECK_NE(vmap_table_offset, 0u);
-    DCHECK_NE(code_size, 0u);
+  OatQuickMethodHeader(uint32_t code_info_offset) : code_info_offset_(code_info_offset) {
+    DCHECK_NE(code_info_offset, 0u);
   }
 
   static OatQuickMethodHeader* FromCodePointer(const void* code_ptr) {
@@ -60,17 +56,17 @@
   }
 
   bool IsOptimized() const {
-    return (code_size_ & kCodeSizeMask) != 0 && vmap_table_offset_ != 0;
+    return true;
   }
 
   const uint8_t* GetOptimizedCodeInfoPtr() const {
-    DCHECK(IsOptimized());
-    return code_ - vmap_table_offset_;
+    DCHECK_NE(code_info_offset_, 0u);
+    return code_ - GetVmapTableOffset();
   }
 
   uint8_t* GetOptimizedCodeInfoPtr() {
-    DCHECK(IsOptimized());
-    return code_ - vmap_table_offset_;
+    DCHECK_NE(code_info_offset_, 0u);
+    return code_ - GetVmapTableOffset();
   }
 
   const uint8_t* GetCode() const {
@@ -78,32 +74,26 @@
   }
 
   uint32_t GetCodeSize() const {
-    DCHECK(IsOptimized());
-    size_t code_size1 = code_size_ & kCodeSizeMask;
-    size_t code_size2 = CodeInfo::DecodeCodeSize(GetOptimizedCodeInfoPtr());
-    DCHECK_EQ(code_size1, code_size2);
-    return code_size2;
-  }
-
-  const uint32_t* GetCodeSizeAddr() const {
-    return &code_size_;
+    return CodeInfo::DecodeCodeSize(GetOptimizedCodeInfoPtr());
   }
 
   uint32_t GetVmapTableOffset() const {
-    return vmap_table_offset_;
+    return code_info_offset_ & kCodeInfoMask;
   }
 
   void SetVmapTableOffset(uint32_t offset) {
-    vmap_table_offset_ = offset;
+    DCHECK(!HasShouldDeoptimizeFlag());
+    code_info_offset_ = offset;
+    DCHECK_EQ(GetVmapTableOffset(), offset);
   }
 
   const uint32_t* GetVmapTableOffsetAddr() const {
-    return &vmap_table_offset_;
+    return &code_info_offset_;
   }
 
   const uint8_t* GetVmapTable() const {
     CHECK(!IsOptimized()) << "Unimplemented vmap table for optimizing compiler";
-    return (vmap_table_offset_ == 0) ? nullptr : code_ - vmap_table_offset_;
+    return (code_info_offset_ == 0) ? nullptr : code_ - code_info_offset_;
   }
 
   bool Contains(uintptr_t pc) const {
@@ -149,23 +139,21 @@
   uint32_t ToDexPc(ArtMethod* method, const uintptr_t pc, bool abort_on_failure = true) const;
 
   void SetHasShouldDeoptimizeFlag() {
-    DCHECK_EQ(code_size_ & kShouldDeoptimizeMask, 0u);
-    code_size_ |= kShouldDeoptimizeMask;
+    DCHECK_EQ(code_info_offset_ & kShouldDeoptimizeMask, 0u);
+    code_info_offset_ |= kShouldDeoptimizeMask;
   }
 
   bool HasShouldDeoptimizeFlag() const {
-    return (code_size_ & kShouldDeoptimizeMask) != 0;
+    return (code_info_offset_ & kShouldDeoptimizeMask) != 0;
   }
 
  private:
   static constexpr uint32_t kShouldDeoptimizeMask = 0x80000000;
-  static constexpr uint32_t kCodeSizeMask = ~kShouldDeoptimizeMask;
+  static constexpr uint32_t kCodeInfoMask = ~kShouldDeoptimizeMask;
 
-  // The offset in bytes from the start of the vmap table to the end of the header.
-  uint32_t vmap_table_offset_ = 0u;
-  // The code size in bytes. The highest bit is used to signify if the compiled
-  // code with the method header has should_deoptimize flag.
-  uint32_t code_size_ = 0u;
+  // The offset in bytes from the start of the code_info to the end of the header.
+  // The highest bit is used to store the should_deoptimize flag.
+  uint32_t code_info_offset_ = 0u;
   // The actual code.
   uint8_t code_[0];
 };