diff options
author | 2017-02-16 02:03:30 +0000 | |
---|---|---|
committer | 2017-02-16 02:03:30 +0000 | |
commit | 9fb10fb39bcb3d9a4dc7e16f8c1d38dcc112639c (patch) | |
tree | 031b225f354460292f43210960ff200067123ab2 /runtime/stack_map.h | |
parent | 28de3b69db7f79852b93dc1c94c7402ba2e99e0b (diff) | |
parent | d776ff08e07494327716f0d2ea1a774b2ebfbca9 (diff) |
Merge "Add invoke infos to stack maps"
Diffstat (limited to 'runtime/stack_map.h')
-rw-r--r-- | runtime/stack_map.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/runtime/stack_map.h b/runtime/stack_map.h index f7a64026b7..67f0b5715d 100644 --- a/runtime/stack_map.h +++ b/runtime/stack_map.h @@ -1145,6 +1145,94 @@ struct ByteSizedTable { } }; +// Format is [native pc, invoke type, method index]. +class InvokeInfoEncoding { + public: + void SetFromSizes(size_t native_pc_max, + size_t invoke_type_max, + size_t method_index_max) { + total_bit_size_ = 0; + DCHECK_EQ(kNativePcBitOffset, total_bit_size_); + total_bit_size_ += MinimumBitsToStore(native_pc_max); + invoke_type_bit_offset_ = total_bit_size_; + total_bit_size_ += MinimumBitsToStore(invoke_type_max); + method_index_bit_offset_ = total_bit_size_; + total_bit_size_ += MinimumBitsToStore(method_index_max); + } + + ALWAYS_INLINE FieldEncoding GetNativePcEncoding() const { + return FieldEncoding(kNativePcBitOffset, invoke_type_bit_offset_); + } + + ALWAYS_INLINE FieldEncoding GetInvokeTypeEncoding() const { + return FieldEncoding(invoke_type_bit_offset_, method_index_bit_offset_); + } + + ALWAYS_INLINE FieldEncoding GetMethodIndexEncoding() const { + return FieldEncoding(method_index_bit_offset_, total_bit_size_); + } + + ALWAYS_INLINE size_t BitSize() const { + return total_bit_size_; + } + + template<typename Vector> + void Encode(Vector* dest) const { + static_assert(alignof(InvokeInfoEncoding) == 1, "Should not require alignment"); + const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this); + dest->insert(dest->end(), ptr, ptr + sizeof(*this)); + } + + void Decode(const uint8_t** ptr) { + *this = *reinterpret_cast<const InvokeInfoEncoding*>(*ptr); + *ptr += sizeof(*this); + } + + private: + static constexpr uint8_t kNativePcBitOffset = 0; + uint8_t invoke_type_bit_offset_; + uint8_t method_index_bit_offset_; + uint8_t total_bit_size_; +}; + +class InvokeInfo { + public: + explicit InvokeInfo(BitMemoryRegion region) : region_(region) {} + + ALWAYS_INLINE uint32_t GetNativePcOffset(const InvokeInfoEncoding& encoding, + InstructionSet instruction_set) const { + CodeOffset offset( + CodeOffset::FromCompressedOffset(encoding.GetNativePcEncoding().Load(region_))); + return offset.Uint32Value(instruction_set); + } + + ALWAYS_INLINE void SetNativePcCodeOffset(const InvokeInfoEncoding& encoding, + CodeOffset native_pc_offset) { + encoding.GetNativePcEncoding().Store(region_, native_pc_offset.CompressedValue()); + } + + ALWAYS_INLINE uint32_t GetInvokeType(const InvokeInfoEncoding& encoding) const { + return encoding.GetInvokeTypeEncoding().Load(region_); + } + + ALWAYS_INLINE void SetInvokeType(const InvokeInfoEncoding& encoding, uint32_t invoke_type) { + encoding.GetInvokeTypeEncoding().Store(region_, invoke_type); + } + + ALWAYS_INLINE uint32_t GetMethodIndex(const InvokeInfoEncoding& encoding) const { + return encoding.GetMethodIndexEncoding().Load(region_); + } + + ALWAYS_INLINE void SetMethodIndex(const InvokeInfoEncoding& encoding, uint32_t method_index) { + encoding.GetMethodIndexEncoding().Store(region_, method_index); + } + + bool IsValid() const { return region_.pointer() != nullptr; } + + private: + BitMemoryRegion region_; +}; + // Most of the fields are encoded as ULEB128 to save space. struct CodeInfoEncoding { static constexpr uint32_t kInvalidSize = static_cast<size_t>(-1); @@ -1154,6 +1242,7 @@ struct CodeInfoEncoding { BitEncodingTable<StackMapEncoding> stack_map; BitEncodingTable<BitRegionEncoding> register_mask; BitEncodingTable<BitRegionEncoding> stack_mask; + BitEncodingTable<InvokeInfoEncoding> invoke_info; BitEncodingTable<InlineInfoEncoding> inline_info; CodeInfoEncoding() {} @@ -1165,6 +1254,7 @@ struct CodeInfoEncoding { stack_map.Decode(&ptr); register_mask.Decode(&ptr); stack_mask.Decode(&ptr); + invoke_info.Decode(&ptr); if (stack_map.encoding.GetInlineInfoEncoding().BitSize() > 0) { inline_info.Decode(&ptr); } else { @@ -1183,6 +1273,7 @@ struct CodeInfoEncoding { stack_map.Encode(dest); register_mask.Encode(dest); stack_mask.Encode(dest); + invoke_info.Encode(dest); if (stack_map.encoding.GetInlineInfoEncoding().BitSize() > 0) { inline_info.Encode(dest); } @@ -1199,6 +1290,7 @@ struct CodeInfoEncoding { stack_map.UpdateBitOffset(&bit_offset); register_mask.UpdateBitOffset(&bit_offset); stack_mask.UpdateBitOffset(&bit_offset); + invoke_info.UpdateBitOffset(&bit_offset); inline_info.UpdateBitOffset(&bit_offset); cache_non_header_size = RoundUp(bit_offset, kBitsPerByte) / kBitsPerByte - HeaderSize(); } @@ -1303,6 +1395,10 @@ class CodeInfo { return encoding.stack_map.encoding.BitSize() * GetNumberOfStackMaps(encoding); } + InvokeInfo GetInvokeInfo(const CodeInfoEncoding& encoding, size_t index) const { + return InvokeInfo(encoding.invoke_info.BitRegion(region_, index)); + } + DexRegisterMap GetDexRegisterMapOf(StackMap stack_map, const CodeInfoEncoding& encoding, size_t number_of_dex_registers) const { @@ -1426,6 +1522,17 @@ class CodeInfo { return StackMap(); } + InvokeInfo GetInvokeInfoForNativePcOffset(uint32_t native_pc_offset, + const CodeInfoEncoding& encoding) { + for (size_t index = 0; index < encoding.invoke_info.num_entries; index++) { + InvokeInfo item = GetInvokeInfo(encoding, index); + if (item.GetNativePcOffset(encoding.invoke_info.encoding, kRuntimeISA) == native_pc_offset) { + return item; + } + } + return InvokeInfo(BitMemoryRegion()); + } + // Dump this CodeInfo object on `os`. `code_offset` is the (absolute) // native PC of the compiled method and `number_of_dex_registers` the // number of Dex virtual registers used in this method. If |