summaryrefslogtreecommitdiff
path: root/runtime/stack_map.h
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2017-02-16 02:03:30 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2017-02-16 02:03:30 +0000
commit9fb10fb39bcb3d9a4dc7e16f8c1d38dcc112639c (patch)
tree031b225f354460292f43210960ff200067123ab2 /runtime/stack_map.h
parent28de3b69db7f79852b93dc1c94c7402ba2e99e0b (diff)
parentd776ff08e07494327716f0d2ea1a774b2ebfbca9 (diff)
Merge "Add invoke infos to stack maps"
Diffstat (limited to 'runtime/stack_map.h')
-rw-r--r--runtime/stack_map.h107
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