Move code size from OatQuickMethodHeader to CodeInfo.
This saves 0.5% of oat file size.
(0.8% saving from this CL minus 0.3% due to go/aog/1614482)
Bug: 123510633
Test: m dump-oat
Test: m test-art-host-gtest
Test: ./art/test.py -b -r --host
Change-Id: I035b54a47b300a5808aa8c2992f87eae009fd245
diff --git a/runtime/oat_quick_method_header.h b/runtime/oat_quick_method_header.h
index 7e1fc9b..e0f942f 100644
--- a/runtime/oat_quick_method_header.h
+++ b/runtime/oat_quick_method_header.h
@@ -31,11 +31,8 @@
// OatQuickMethodHeader precedes the raw code chunk generated by the compiler.
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) {
+ OatQuickMethodHeader(uint32_t code_info_offset = 0) {
+ SetCodeInfoOffset(code_info_offset);
}
static OatQuickMethodHeader* NterpMethodHeader;
@@ -67,17 +64,22 @@
}
bool IsOptimized() const {
- return (code_size_ & kCodeSizeMask) != 0 && vmap_table_offset_ != 0;
+ 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 {
- DCHECK(IsOptimized());
- return code_ - vmap_table_offset_;
+ uint32_t offset = GetCodeInfoOffset();
+ DCHECK_NE(offset, 0u);
+ return code_ - offset;
}
uint8_t* GetOptimizedCodeInfoPtr() {
- DCHECK(IsOptimized());
- return code_ - vmap_table_offset_;
+ uint32_t offset = GetCodeInfoOffset();
+ DCHECK_NE(offset, 0u);
+ return code_ - offset;
}
const uint8_t* GetCode() const {
@@ -85,36 +87,17 @@
}
uint32_t GetCodeSize() const {
- // ART compiled method are prefixed with header, but we can also easily
- // accidentally use a function pointer to one of the stubs/trampolines.
- // We prefix those with 0xFF in the aseembly so that we can do DCHECKs.
- CHECK_NE(code_size_, 0xFFFFFFFF) << code_size_;
- if (IsOptimized()) {
- // Temporary code: Check that the code size in code info matches.
- CHECK_EQ(code_size_ & kCodeSizeMask, CodeInfo::DecodeCodeSize(this));
- }
- return code_size_ & kCodeSizeMask;
+ return IsOptimized() ? CodeInfo::DecodeCodeSize(this) : (data_ & kCodeSizeMask);
}
- const uint32_t* GetCodeSizeAddr() const {
- return &code_size_;
+ uint32_t GetCodeInfoOffset() const {
+ DCHECK(IsOptimized());
+ return data_ & kCodeInfoMask;
}
- uint32_t GetVmapTableOffset() const {
- return vmap_table_offset_;
- }
-
- void SetVmapTableOffset(uint32_t offset) {
- vmap_table_offset_ = offset;
- }
-
- const uint32_t* GetVmapTableOffsetAddr() const {
- return &vmap_table_offset_;
- }
-
- const uint8_t* GetVmapTable() const {
- CHECK(!IsOptimized()) << "Unimplemented vmap table for optimizing compiler";
- return (vmap_table_offset_ == 0) ? nullptr : code_ - vmap_table_offset_;
+ void SetCodeInfoOffset(uint32_t offset) {
+ data_ = kIsCodeInfoMask | offset;
+ DCHECK_EQ(GetCodeInfoOffset(), offset);
}
bool Contains(uintptr_t pc) const {
@@ -164,25 +147,22 @@
REQUIRES_SHARED(Locks::mutator_lock_);
void SetHasShouldDeoptimizeFlag() {
- DCHECK_EQ(code_size_ & kShouldDeoptimizeMask, 0u);
- code_size_ |= kShouldDeoptimizeMask;
+ DCHECK(!HasShouldDeoptimizeFlag());
+ data_ |= kShouldDeoptimizeMask;
}
bool HasShouldDeoptimizeFlag() const {
- return (code_size_ & kShouldDeoptimizeMask) != 0;
+ return (data_ & kShouldDeoptimizeMask) != 0;
}
private:
static constexpr uint32_t kShouldDeoptimizeMask = 0x80000000;
- static constexpr uint32_t kCodeSizeMask = ~kShouldDeoptimizeMask;
+ static constexpr uint32_t kIsCodeInfoMask = 0x40000000;
+ static constexpr uint32_t kCodeInfoMask = 0x3FFFFFFF; // If kIsCodeInfoMask is set.
+ static constexpr uint32_t kCodeSizeMask = 0x3FFFFFFF; // If kIsCodeInfoMask is clear.
- // 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 actual code.
- uint8_t code_[0];
+ uint32_t data_ = 0u; // Combination of fields using the above masks.
+ uint8_t code_[0]; // The actual method code.
};
} // namespace art