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 b04197e1..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;
 };