Reduce code repetition in stack maps with macros.
Simplifies the code somewhat. It also makes it possible
to get column names as strings for the debugging code.
Test: test-art-host-gtest-stack_map_test
Change-Id: I1a2e146e7a4372c0752693313e1b881cb4a818bc
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index d80e2fc..3685ab2 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -129,7 +129,7 @@
CHECK_EQ(invoke_info.GetNativePcOffset(instruction_set_),
StackMap::UnpackNativePc(packed_native_pc, instruction_set_));
CHECK_EQ(invoke_info.GetInvokeType(), invoke_type);
- CHECK_EQ(method_infos_[invoke_info.GetMethodIndexIdx()], dex_method_index);
+ CHECK_EQ(method_infos_[invoke_info.GetMethodInfoIndex()], dex_method_index);
});
}
}
@@ -179,7 +179,7 @@
if (encode_art_method) {
CHECK_EQ(inline_info.GetArtMethod(), method);
} else {
- CHECK_EQ(method_infos_[inline_info.GetMethodIndexIdx()],
+ CHECK_EQ(method_infos_[inline_info.GetMethodInfoIndex()],
method->GetDexMethodIndexUnchecked());
}
CHECK_EQ(inline_info.HasDexRegisterMap(), (num_dex_registers != 0));
diff --git a/libartbase/base/bit_table.h b/libartbase/base/bit_table.h
index bf3d3b0..0ae60b9 100644
--- a/libartbase/base/bit_table.h
+++ b/libartbase/base/bit_table.h
@@ -68,8 +68,10 @@
public:
class Accessor {
public:
+ static constexpr uint32_t kCount = kNumColumns;
static constexpr uint32_t kNoValue = std::numeric_limits<uint32_t>::max();
+ Accessor() {}
Accessor(const BitTable* table, uint32_t row) : table_(table), row_(row) {}
ALWAYS_INLINE uint32_t Row() const { return row_; }
@@ -86,14 +88,27 @@
return this->table_ == other.table_ && this->row_ == other.row_;
}
- Accessor& operator++() {
- row_++;
- return *this;
- }
+// Helper macro to create constructors and per-table utilities in derived class.
+#define BIT_TABLE_HEADER() \
+ using BitTable<kCount>::Accessor::Accessor; /* inherit the constructors */ \
+ template<int COLUMN, int UNUSED /*needed to compile*/> struct ColumnName; \
+
+// Helper macro to create named column accessors in derived class.
+#define BIT_TABLE_COLUMN(COLUMN, NAME) \
+ static constexpr uint32_t k##NAME = COLUMN; \
+ ALWAYS_INLINE uint32_t Get##NAME() const { \
+ return table_->Get(row_, COLUMN); \
+ } \
+ ALWAYS_INLINE bool Has##NAME() const { \
+ return table_->Get(row_, COLUMN) != kNoValue; \
+ } \
+ template<int UNUSED> struct ColumnName<COLUMN, UNUSED> { \
+ static constexpr const char* Value = #NAME; \
+ }; \
protected:
- const BitTable* table_;
- uint32_t row_;
+ const BitTable* table_ = nullptr;
+ uint32_t row_ = -1;
};
static constexpr uint32_t kValueBias = -1;
@@ -152,11 +167,17 @@
uint16_t column_offset_[kNumColumns + 1] = {};
};
-template<uint32_t kNumColumns>
-constexpr uint32_t BitTable<kNumColumns>::Accessor::kNoValue;
+// Template meta-programming helper.
+template<typename Accessor, size_t... Columns>
+static const char** GetBitTableColumnNamesImpl(std::index_sequence<Columns...>) {
+ static const char* names[] = { Accessor::template ColumnName<Columns, 0>::Value... };
+ return names;
+}
-template<uint32_t kNumColumns>
-constexpr uint32_t BitTable<kNumColumns>::kValueBias;
+template<typename Accessor>
+static const char** GetBitTableColumnNames() {
+ return GetBitTableColumnNamesImpl<Accessor>(std::make_index_sequence<Accessor::kCount>());
+}
// Helper class for encoding BitTable. It can optionally de-duplicate the inputs.
// Type 'T' must be POD type consisting of uint32_t fields (one for each column).
@@ -209,18 +230,6 @@
return index;
}
- // Check if the table already contains given values starting at the given index.
- bool RangeEquals(uint32_t index, T* values, size_t count = 1) {
- DCHECK_LE(index, size());
- DCHECK_LE(count, size() - index);
- for (uint32_t i = 0; i < count; i++) {
- if (memcmp(&values[i], &rows_[index + i], sizeof(T)) != 0) {
- return false;
- }
- }
- return true;
- }
-
ALWAYS_INLINE uint32_t Get(uint32_t row, uint32_t column) const {
DCHECK_LT(row, size());
DCHECK_LT(column, kNumColumns);
@@ -290,9 +299,6 @@
ScopedArenaUnorderedMultimap<uint32_t, uint32_t> dedup_; // Hash -> row index.
};
-template<typename T>
-constexpr size_t BitTableBuilder<T>::kNumColumns;
-
// Helper class for encoding single-column BitTable of bitmaps (allows more than 32 bits).
class BitmapTableBuilder {
public:
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 7ac9e98..3188087 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1748,7 +1748,7 @@
if (num_inline_infos > 0u) {
stats_.AddBits(
Stats::kByteKindInlineInfoMethodIndexIdx,
- inline_infos.NumColumnBits(InlineInfo::kMethodIndexIdx) * num_inline_infos);
+ inline_infos.NumColumnBits(InlineInfo::kMethodInfoIndex) * num_inline_infos);
stats_.AddBits(
Stats::kByteKindInlineInfoDexPc,
inline_infos.NumColumnBits(InlineInfo::kDexPc) * num_inline_infos);
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index b04197e..6da0021 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -147,38 +147,26 @@
*/
class StackMap : public BitTable<7>::Accessor {
public:
- enum Field {
- kPackedNativePc,
- kDexPc,
- kRegisterMaskIndex,
- kStackMaskIndex,
- kInlineInfoIndex,
- kDexRegisterMaskIndex,
- kDexRegisterMapIndex,
- kCount,
- };
-
- StackMap() : BitTable<kCount>::Accessor(nullptr, -1) {}
- StackMap(const BitTable<kCount>* table, uint32_t row)
- : BitTable<kCount>::Accessor(table, row) {}
+ BIT_TABLE_HEADER()
+ BIT_TABLE_COLUMN(0, PackedNativePc)
+ BIT_TABLE_COLUMN(1, DexPc)
+ BIT_TABLE_COLUMN(2, RegisterMaskIndex)
+ BIT_TABLE_COLUMN(3, StackMaskIndex)
+ BIT_TABLE_COLUMN(4, InlineInfoIndex)
+ BIT_TABLE_COLUMN(5, DexRegisterMaskIndex)
+ BIT_TABLE_COLUMN(6, DexRegisterMapIndex)
ALWAYS_INLINE uint32_t GetNativePcOffset(InstructionSet instruction_set) const {
return UnpackNativePc(Get<kPackedNativePc>(), instruction_set);
}
- uint32_t GetDexPc() const { return Get<kDexPc>(); }
+ ALWAYS_INLINE bool HasInlineInfo() const {
+ return HasInlineInfoIndex();
+ }
- uint32_t GetDexRegisterMaskIndex() const { return Get<kDexRegisterMaskIndex>(); }
-
- uint32_t GetDexRegisterMapIndex() const { return Get<kDexRegisterMapIndex>(); }
- bool HasDexRegisterMap() const { return GetDexRegisterMapIndex() != kNoValue; }
-
- uint32_t GetInlineInfoIndex() const { return Get<kInlineInfoIndex>(); }
- bool HasInlineInfo() const { return GetInlineInfoIndex() != kNoValue; }
-
- uint32_t GetRegisterMaskIndex() const { return Get<kRegisterMaskIndex>(); }
-
- uint32_t GetStackMaskIndex() const { return Get<kStackMaskIndex>(); }
+ ALWAYS_INLINE bool HasDexRegisterMap() const {
+ return HasDexRegisterMapIndex();
+ }
static uint32_t PackNativePc(uint32_t native_pc, InstructionSet isa) {
DCHECK_ALIGNED_PARAM(native_pc, GetInstructionSetInstructionAlignment(isa));
@@ -206,56 +194,34 @@
*/
class InlineInfo : public BitTable<7>::Accessor {
public:
- enum Field {
- kIsLast, // Determines if there are further rows for further depths.
- kDexPc,
- kMethodIndexIdx,
- kArtMethodHi, // High bits of ArtMethod*.
- kArtMethodLo, // Low bits of ArtMethod*.
- kDexRegisterMaskIndex,
- kDexRegisterMapIndex,
- kCount,
- };
+ BIT_TABLE_HEADER()
+ BIT_TABLE_COLUMN(0, IsLast) // Determines if there are further rows for further depths.
+ BIT_TABLE_COLUMN(1, DexPc)
+ BIT_TABLE_COLUMN(2, MethodInfoIndex)
+ BIT_TABLE_COLUMN(3, ArtMethodHi) // High bits of ArtMethod*.
+ BIT_TABLE_COLUMN(4, ArtMethodLo) // Low bits of ArtMethod*.
+ BIT_TABLE_COLUMN(5, DexRegisterMaskIndex)
+ BIT_TABLE_COLUMN(6, DexRegisterMapIndex)
+
static constexpr uint32_t kLast = -1;
static constexpr uint32_t kMore = 0;
- InlineInfo(const BitTable<kCount>* table, uint32_t row)
- : BitTable<kCount>::Accessor(table, row) {}
-
- uint32_t GetIsLast() const { return Get<kIsLast>(); }
-
- uint32_t GetMethodIndexIdx() const {
- DCHECK(!EncodesArtMethod());
- return Get<kMethodIndexIdx>();
- }
-
uint32_t GetMethodIndex(const MethodInfo& method_info) const {
- return method_info.GetMethodIndex(GetMethodIndexIdx());
- }
-
- uint32_t GetDexPc() const {
- return Get<kDexPc>();
+ return method_info.GetMethodIndex(GetMethodInfoIndex());
}
bool EncodesArtMethod() const {
- return Get<kArtMethodLo>() != kNoValue;
+ return HasArtMethodLo();
}
ArtMethod* GetArtMethod() const {
- uint64_t lo = Get<kArtMethodLo>();
- uint64_t hi = Get<kArtMethodHi>();
+ uint64_t lo = GetArtMethodLo();
+ uint64_t hi = GetArtMethodHi();
return reinterpret_cast<ArtMethod*>((hi << 32) | lo);
}
- uint32_t GetDexRegisterMaskIndex() const {
- return Get<kDexRegisterMaskIndex>();
- }
-
- uint32_t GetDexRegisterMapIndex() const {
- return Get<kDexRegisterMapIndex>();
- }
- bool HasDexRegisterMap() const {
- return GetDexRegisterMapIndex() != kNoValue;
+ ALWAYS_INLINE bool HasDexRegisterMap() const {
+ return HasDexRegisterMapIndex();
}
void Dump(VariableIndentationOutputStream* vios,
@@ -267,43 +233,29 @@
class InvokeInfo : public BitTable<3>::Accessor {
public:
- enum Field {
- kPackedNativePc,
- kInvokeType,
- kMethodIndexIdx,
- kCount,
- };
-
- InvokeInfo(const BitTable<kCount>* table, uint32_t row)
- : BitTable<kCount>::Accessor(table, row) {}
+ BIT_TABLE_HEADER()
+ BIT_TABLE_COLUMN(0, PackedNativePc)
+ BIT_TABLE_COLUMN(1, InvokeType)
+ BIT_TABLE_COLUMN(2, MethodInfoIndex)
ALWAYS_INLINE uint32_t GetNativePcOffset(InstructionSet instruction_set) const {
return StackMap::UnpackNativePc(Get<kPackedNativePc>(), instruction_set);
}
- uint32_t GetInvokeType() const { return Get<kInvokeType>(); }
-
- uint32_t GetMethodIndexIdx() const { return Get<kMethodIndexIdx>(); }
-
uint32_t GetMethodIndex(MethodInfo method_info) const {
- return method_info.GetMethodIndex(GetMethodIndexIdx());
+ return method_info.GetMethodIndex(GetMethodInfoIndex());
}
};
class DexRegisterInfo : public BitTable<2>::Accessor {
public:
- enum Field {
- kKind,
- kPackedValue,
- kCount,
- };
-
- DexRegisterInfo(const BitTable<kCount>* table, uint32_t row)
- : BitTable<kCount>::Accessor(table, row) {}
+ BIT_TABLE_HEADER()
+ BIT_TABLE_COLUMN(0, Kind)
+ BIT_TABLE_COLUMN(1, PackedValue)
ALWAYS_INLINE DexRegisterLocation GetLocation() const {
- DexRegisterLocation::Kind kind = static_cast<DexRegisterLocation::Kind>(Get<kKind>());
- return DexRegisterLocation(kind, UnpackValue(kind, Get<kPackedValue>()));
+ DexRegisterLocation::Kind kind = static_cast<DexRegisterLocation::Kind>(GetKind());
+ return DexRegisterLocation(kind, UnpackValue(kind, GetPackedValue()));
}
static uint32_t PackValue(DexRegisterLocation::Kind kind, uint32_t value) {
@@ -328,17 +280,12 @@
// therefore it is worth encoding the mask as value+shift.
class RegisterMask : public BitTable<2>::Accessor {
public:
- enum Field {
- kValue,
- kShift,
- kCount,
- };
-
- RegisterMask(const BitTable<kCount>* table, uint32_t row)
- : BitTable<kCount>::Accessor(table, row) {}
+ BIT_TABLE_HEADER()
+ BIT_TABLE_COLUMN(0, Value)
+ BIT_TABLE_COLUMN(1, Shift)
ALWAYS_INLINE uint32_t GetMask() const {
- return Get<kValue>() << Get<kShift>();
+ return GetValue() << GetShift();
}
};
@@ -509,7 +456,7 @@
return item;
}
}
- return InvokeInfo(&invoke_infos_, -1);
+ return InvokeInfo();
}
// Dump this CodeInfo object on `vios`.
@@ -557,14 +504,14 @@
}
size_t size_;
- BitTable<StackMap::Field::kCount> stack_maps_;
- BitTable<RegisterMask::Field::kCount> register_masks_;
+ BitTable<StackMap::kCount> stack_maps_;
+ BitTable<RegisterMask::kCount> register_masks_;
BitTable<1> stack_masks_;
- BitTable<InvokeInfo::Field::kCount> invoke_infos_;
- BitTable<InlineInfo::Field::kCount> inline_infos_;
+ BitTable<InvokeInfo::kCount> invoke_infos_;
+ BitTable<InlineInfo::kCount> inline_infos_;
BitTable<1> dex_register_masks_;
BitTable<1> dex_register_maps_;
- BitTable<DexRegisterInfo::Field::kCount> dex_register_catalog_;
+ BitTable<DexRegisterInfo::kCount> dex_register_catalog_;
friend class OatDumper;
};