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_;