Inline CodeInfo::DecodeCodeSize

Micro-optimization. This is not expected to make any difference
(but it also certainly should not cause any harm to performance).

Bug: 183547619
Change-Id: If1d493822f1bb49f9cf332a88b373f1d01195ca6
diff --git a/runtime/oat_quick_method_header.h b/runtime/oat_quick_method_header.h
index e0f942f..c2f1c4c 100644
--- a/runtime/oat_quick_method_header.h
+++ b/runtime/oat_quick_method_header.h
@@ -63,34 +63,36 @@
     return pc - reinterpret_cast<uintptr_t>(GetEntryPoint());
   }
 
-  bool IsOptimized() const {
+  ALWAYS_INLINE bool IsOptimized() const {
     uintptr_t code = reinterpret_cast<uintptr_t>(code_);
     DCHECK_NE(data_, 0u) << std::hex << code;          // Probably a padding of native code.
     DCHECK_NE(data_, 0xFFFFFFFF) << std::hex << code;  // Probably a stub or trampoline.
     return (data_ & kIsCodeInfoMask) != 0;
   }
 
-  const uint8_t* GetOptimizedCodeInfoPtr() const {
+  ALWAYS_INLINE const uint8_t* GetOptimizedCodeInfoPtr() const {
     uint32_t offset = GetCodeInfoOffset();
     DCHECK_NE(offset, 0u);
     return code_ - offset;
   }
 
-  uint8_t* GetOptimizedCodeInfoPtr() {
+  ALWAYS_INLINE uint8_t* GetOptimizedCodeInfoPtr() {
     uint32_t offset = GetCodeInfoOffset();
     DCHECK_NE(offset, 0u);
     return code_ - offset;
   }
 
-  const uint8_t* GetCode() const {
+  ALWAYS_INLINE const uint8_t* GetCode() const {
     return code_;
   }
 
-  uint32_t GetCodeSize() const {
-    return IsOptimized() ? CodeInfo::DecodeCodeSize(this) : (data_ & kCodeSizeMask);
+  ALWAYS_INLINE uint32_t GetCodeSize() const {
+    return LIKELY(IsOptimized())
+        ? CodeInfo::DecodeCodeSize(GetOptimizedCodeInfoPtr())
+        : (data_ & kCodeSizeMask);
   }
 
-  uint32_t GetCodeInfoOffset() const {
+  ALWAYS_INLINE uint32_t GetCodeInfoOffset() const {
     DCHECK(IsOptimized());
     return data_ & kCodeInfoMask;
   }
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index c154ad5..c160e2b 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -61,13 +61,6 @@
 CodeInfo::CodeInfo(const OatQuickMethodHeader* header)
     : CodeInfo(header->GetOptimizedCodeInfoPtr()) {}
 
-QuickMethodFrameInfo CodeInfo::DecodeFrameInfo(const uint8_t* data) {
-  CodeInfo code_info(data);
-  return QuickMethodFrameInfo(code_info.packed_frame_size_ * kStackAlignment,
-                              code_info.core_spill_mask_,
-                              code_info.fp_spill_mask_);
-}
-
 CodeInfo CodeInfo::DecodeGcMasksOnly(const OatQuickMethodHeader* header) {
   CodeInfo code_info(header->GetOptimizedCodeInfoPtr());
   CodeInfo copy;  // Copy to dead-code-eliminate all fields that we do not need.
@@ -87,10 +80,6 @@
   return copy;
 }
 
-uint32_t CodeInfo::DecodeCodeSize(const OatQuickMethodHeader* header) {
-  return CodeInfo(header->GetOptimizedCodeInfoPtr()).code_size_;
-}
-
 size_t CodeInfo::Deduper::Dedupe(const uint8_t* code_info_data) {
   writer_.ByteAlign();
   size_t deduped_offset = writer_.NumberOfWrittenBits() / kBitsPerByte;
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index ce577c0..103402b 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -296,10 +296,29 @@
   ALWAYS_INLINE explicit CodeInfo(const OatQuickMethodHeader* header);
 
   // The following methods decode only part of the data.
-  static QuickMethodFrameInfo DecodeFrameInfo(const uint8_t* data);
   static CodeInfo DecodeGcMasksOnly(const OatQuickMethodHeader* header);
   static CodeInfo DecodeInlineInfoOnly(const OatQuickMethodHeader* header);
-  static uint32_t DecodeCodeSize(const OatQuickMethodHeader* header);
+
+  ALWAYS_INLINE static uint32_t DecodeCodeSize(const uint8_t* code_info_data) {
+    return DecodeHeaderOnly(code_info_data).code_size_;
+  }
+
+  ALWAYS_INLINE static QuickMethodFrameInfo DecodeFrameInfo(const uint8_t* code_info_data) {
+    CodeInfo code_info = DecodeHeaderOnly(code_info_data);
+    return QuickMethodFrameInfo(code_info.packed_frame_size_ * kStackAlignment,
+                                code_info.core_spill_mask_,
+                                code_info.fp_spill_mask_);
+  }
+
+  ALWAYS_INLINE static CodeInfo DecodeHeaderOnly(const uint8_t* code_info_data) {
+    CodeInfo code_info;
+    BitMemoryReader reader(code_info_data);
+    std::array<uint32_t, kNumHeaders> header = reader.ReadInterleavedVarints<kNumHeaders>();
+    ForEachHeaderField([&code_info, &header](size_t i, auto member_pointer) {
+      code_info.*member_pointer = header[i];
+    });
+    return code_info;
+  }
 
   ALWAYS_INLINE const BitTable<StackMap>& GetStackMaps() const {
     return stack_maps_;