Merge changes I6f281703,I1450fe2c

* changes:
  ART: Refactor code_item_accessors
  ART: Move Signature to its own header
diff --git a/dex2oat/linker/image_test.h b/dex2oat/linker/image_test.h
index 70a22b5..8c9dfb8 100644
--- a/dex2oat/linker/image_test.h
+++ b/dex2oat/linker/image_test.h
@@ -36,6 +36,7 @@
 #include "compiler_callbacks.h"
 #include "debug/method_debug_info.h"
 #include "dex/quick_compiler_callbacks.h"
+#include "dex/signature-inl.h"
 #include "driver/compiler_driver.h"
 #include "driver/compiler_options.h"
 #include "gc/space/image_space.h"
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index a4f7e25..9c48aa2 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -32,6 +32,7 @@
         "dex/dex_instruction.cc",
         "dex/modifiers.cc",
         "dex/primitive.cc",
+        "dex/signature.cc",
         "dex/standard_dex_file.cc",
         "dex/type_lookup_table.cc",
         "dex/utf.cc",
diff --git a/libdexfile/dex/code_item_accessors-inl.h b/libdexfile/dex/code_item_accessors-inl.h
index 15e34b7..632a787 100644
--- a/libdexfile/dex/code_item_accessors-inl.h
+++ b/libdexfile/dex/code_item_accessors-inl.h
@@ -19,6 +19,7 @@
 
 #include "code_item_accessors.h"
 
+#include "base/iteration_range.h"
 #include "compact_dex_file.h"
 #include "dex_file-inl.h"
 #include "standard_dex_file.h"
@@ -32,7 +33,9 @@
   insns_ = insns;
 }
 
-inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) {
+template <>
+inline void CodeItemInstructionAccessor::Init<CompactDexFile::CodeItem>(
+    const CompactDexFile::CodeItem& code_item) {
   uint32_t insns_size_in_code_units;
   code_item.DecodeFields</*kDecodeOnlyInstructionCount*/ true>(
       &insns_size_in_code_units,
@@ -43,7 +46,9 @@
   Init(insns_size_in_code_units, code_item.insns_);
 }
 
-inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) {
+template <>
+inline void CodeItemInstructionAccessor::Init<StandardDexFile::CodeItem>(
+    const StandardDexFile::CodeItem& code_item) {
   Init(code_item.insns_size_in_code_units_, code_item.insns_);
 }
 
@@ -82,7 +87,9 @@
       DexInstructionIterator(insns_, insns_size_in_code_units_) };
 }
 
-inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) {
+template <>
+inline void CodeItemDataAccessor::Init<CompactDexFile::CodeItem>(
+    const CompactDexFile::CodeItem& code_item) {
   uint32_t insns_size_in_code_units;
   code_item.DecodeFields</*kDecodeOnlyInstructionCount*/ false>(&insns_size_in_code_units,
                                                                 &registers_size_,
@@ -92,7 +99,9 @@
   CodeItemInstructionAccessor::Init(insns_size_in_code_units, code_item.insns_);
 }
 
-inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) {
+template <>
+inline void CodeItemDataAccessor::Init<StandardDexFile::CodeItem>(
+    const StandardDexFile::CodeItem& code_item) {
   CodeItemInstructionAccessor::Init(code_item);
   registers_size_ = code_item.registers_size_;
   ins_size_ = code_item.ins_size_;
@@ -104,10 +113,10 @@
                                        const dex::CodeItem* code_item) {
   if (code_item != nullptr) {
     if (dex_file.IsCompactDexFile()) {
-      CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
+      Init(down_cast<const CompactDexFile::CodeItem&>(*code_item));
     } else {
       DCHECK(dex_file.IsStandardDexFile());
-      CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
+      Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
     }
   }
 }
@@ -157,6 +166,23 @@
   return reinterpret_cast<const void*>(handler_data);
 }
 
+template <>
+inline void CodeItemDebugInfoAccessor::Init<CompactDexFile::CodeItem>(
+    const CompactDexFile::CodeItem& code_item,
+    uint32_t dex_method_index) {
+  debug_info_offset_ = down_cast<const CompactDexFile*>(dex_file_)->GetDebugInfoOffset(
+      dex_method_index);
+  CodeItemDataAccessor::Init(code_item);
+}
+
+template <>
+inline void CodeItemDebugInfoAccessor::Init<StandardDexFile::CodeItem>(
+    const StandardDexFile::CodeItem& code_item,
+    uint32_t dex_method_index ATTRIBUTE_UNUSED) {
+  debug_info_offset_ = code_item.debug_info_off_;
+  CodeItemDataAccessor::Init(code_item);
+}
+
 inline void CodeItemDebugInfoAccessor::Init(const DexFile& dex_file,
                                             const dex::CodeItem* code_item,
                                             uint32_t dex_method_index) {
@@ -168,22 +194,10 @@
     Init(down_cast<const CompactDexFile::CodeItem&>(*code_item), dex_method_index);
   } else {
     DCHECK(dex_file.IsStandardDexFile());
-    Init(down_cast<const StandardDexFile::CodeItem&>(*code_item));
+    Init(down_cast<const StandardDexFile::CodeItem&>(*code_item), dex_method_index);
   }
 }
 
-inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item,
-                                            uint32_t dex_method_index) {
-  debug_info_offset_ = down_cast<const CompactDexFile*>(dex_file_)->GetDebugInfoOffset(
-      dex_method_index);
-  CodeItemDataAccessor::Init(code_item);
-}
-
-inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) {
-  debug_info_offset_ = code_item.debug_info_off_;
-  CodeItemDataAccessor::Init(code_item);
-}
-
 template<typename NewLocalVisitor>
 inline bool CodeItemDebugInfoAccessor::DecodeDebugLocalInfo(
     bool is_static,
diff --git a/libdexfile/dex/code_item_accessors.h b/libdexfile/dex/code_item_accessors.h
index 0ae5905..794f234 100644
--- a/libdexfile/dex/code_item_accessors.h
+++ b/libdexfile/dex/code_item_accessors.h
@@ -21,9 +21,7 @@
 
 #include <android-base/logging.h>
 
-#include "compact_dex_file.h"
 #include "dex_instruction_iterator.h"
-#include "standard_dex_file.h"
 
 namespace art {
 
@@ -34,6 +32,8 @@
 
 class ArtMethod;
 class DexFile;
+template <typename Iter>
+class IterationRange;
 
 // Abstracts accesses to the instruction fields of code items for CompactDexFile and
 // StandardDexFile.
@@ -78,10 +78,11 @@
   CodeItemInstructionAccessor() = default;
 
   ALWAYS_INLINE void Init(uint32_t insns_size_in_code_units, const uint16_t* insns);
-  ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item);
-  ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
   ALWAYS_INLINE void Init(const DexFile& dex_file, const dex::CodeItem* code_item);
 
+  template <typename DexFileCodeItemType>
+  ALWAYS_INLINE void Init(const DexFileCodeItemType& code_item);
+
  private:
   // size of the insns array, in 2 byte code units. 0 if there is no code item.
   uint32_t insns_size_in_code_units_ = 0;
@@ -123,10 +124,11 @@
  protected:
   CodeItemDataAccessor() = default;
 
-  ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item);
-  ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
   ALWAYS_INLINE void Init(const DexFile& dex_file, const dex::CodeItem* code_item);
 
+  template <typename DexFileCodeItemType>
+  ALWAYS_INLINE void Init(const DexFileCodeItemType& code_item);
+
  private:
   // Fields mirrored from the dex/cdex code item.
   uint16_t registers_size_;
@@ -174,8 +176,8 @@
   bool GetLineNumForPc(const uint32_t pc, uint32_t* line_num) const;
 
  protected:
-  ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item, uint32_t dex_method_index);
-  ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
+  template <typename DexFileCodeItemType>
+  ALWAYS_INLINE void Init(const DexFileCodeItemType& code_item, uint32_t dex_method_index);
 
  private:
   const DexFile* dex_file_ = nullptr;
diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h
index 58fc893..9a720c2 100644
--- a/libdexfile/dex/dex_file-inl.h
+++ b/libdexfile/dex/dex_file-inl.h
@@ -163,60 +163,6 @@
   return (s1_len == s2_len) && (strcmp(s1_data, s2_data) == 0);
 }
 
-inline bool Signature::operator==(const Signature& rhs) const {
-  if (dex_file_ == nullptr) {
-    return rhs.dex_file_ == nullptr;
-  }
-  if (rhs.dex_file_ == nullptr) {
-    return false;
-  }
-  if (dex_file_ == rhs.dex_file_) {
-    return proto_id_ == rhs.proto_id_;
-  }
-  uint32_t lhs_shorty_len;  // For a shorty utf16 length == mutf8 length.
-  const char* lhs_shorty_data = dex_file_->StringDataAndUtf16LengthByIdx(proto_id_->shorty_idx_,
-                                                                         &lhs_shorty_len);
-  StringPiece lhs_shorty(lhs_shorty_data, lhs_shorty_len);
-  {
-    uint32_t rhs_shorty_len;
-    const char* rhs_shorty_data =
-        rhs.dex_file_->StringDataAndUtf16LengthByIdx(rhs.proto_id_->shorty_idx_,
-                                                     &rhs_shorty_len);
-    StringPiece rhs_shorty(rhs_shorty_data, rhs_shorty_len);
-    if (lhs_shorty != rhs_shorty) {
-      return false;  // Shorty mismatch.
-    }
-  }
-  if (lhs_shorty[0] == 'L') {
-    const dex::TypeId& return_type_id = dex_file_->GetTypeId(proto_id_->return_type_idx_);
-    const dex::TypeId& rhs_return_type_id =
-        rhs.dex_file_->GetTypeId(rhs.proto_id_->return_type_idx_);
-    if (!DexFile::StringEquals(dex_file_, return_type_id.descriptor_idx_,
-                               rhs.dex_file_, rhs_return_type_id.descriptor_idx_)) {
-      return false;  // Return type mismatch.
-    }
-  }
-  if (lhs_shorty.find('L', 1) != StringPiece::npos) {
-    const dex::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
-    const dex::TypeList* rhs_params = rhs.dex_file_->GetProtoParameters(*rhs.proto_id_);
-    // We found a reference parameter in the matching shorty, so both lists must be non-empty.
-    DCHECK(params != nullptr);
-    DCHECK(rhs_params != nullptr);
-    uint32_t params_size = params->Size();
-    DCHECK_EQ(params_size, rhs_params->Size());  // Parameter list size must match.
-    for (uint32_t i = 0; i < params_size; ++i) {
-      const dex::TypeId& param_id = dex_file_->GetTypeId(params->GetTypeItem(i).type_idx_);
-      const dex::TypeId& rhs_param_id =
-          rhs.dex_file_->GetTypeId(rhs_params->GetTypeItem(i).type_idx_);
-      if (!DexFile::StringEquals(dex_file_, param_id.descriptor_idx_,
-                                 rhs.dex_file_, rhs_param_id.descriptor_idx_)) {
-        return false;  // Parameter type mismatch.
-      }
-    }
-  }
-  return true;
-}
-
 template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
 bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream,
                                    const std::string& location,
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index ff51906..5c100e6 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -604,66 +604,6 @@
   return os;
 }
 
-std::string Signature::ToString() const {
-  if (dex_file_ == nullptr) {
-    CHECK(proto_id_ == nullptr);
-    return "<no signature>";
-  }
-  const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
-  std::string result;
-  if (params == nullptr) {
-    result += "()";
-  } else {
-    result += "(";
-    for (uint32_t i = 0; i < params->Size(); ++i) {
-      result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_);
-    }
-    result += ")";
-  }
-  result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
-  return result;
-}
-
-uint32_t Signature::GetNumberOfParameters() const {
-  const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
-  return (params != nullptr) ? params->Size() : 0;
-}
-
-bool Signature::IsVoid() const {
-  const char* return_type = dex_file_->GetReturnTypeDescriptor(*proto_id_);
-  return strcmp(return_type, "V") == 0;
-}
-
-bool Signature::operator==(const StringPiece& rhs) const {
-  if (dex_file_ == nullptr) {
-    return false;
-  }
-  StringPiece tail(rhs);
-  if (!tail.starts_with("(")) {
-    return false;  // Invalid signature
-  }
-  tail.remove_prefix(1);  // "(";
-  const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
-  if (params != nullptr) {
-    for (uint32_t i = 0; i < params->Size(); ++i) {
-      StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
-      if (!tail.starts_with(param)) {
-        return false;
-      }
-      tail.remove_prefix(param.length());
-    }
-  }
-  if (!tail.starts_with(")")) {
-    return false;
-  }
-  tail.remove_prefix(1);  // ")";
-  return tail == dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
-}
-
-std::ostream& operator<<(std::ostream& os, const Signature& sig) {
-  return os << sig.ToString();
-}
-
 EncodedArrayValueIterator::EncodedArrayValueIterator(const DexFile& dex_file,
                                                      const uint8_t* array_data)
     : dex_file_(dex_file),
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 05e4b61..cf32780 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -32,6 +32,7 @@
 #include "dex_file_types.h"
 #include "jni.h"
 #include "modifiers.h"
+#include "signature.h"
 
 namespace art {
 
@@ -41,7 +42,6 @@
 enum InvokeType : uint32_t;
 class MemMap;
 class OatDexFile;
-class Signature;
 class StandardDexFile;
 class StringPiece;
 class ZipArchive;
@@ -911,38 +911,6 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
 };
 
-// Abstract the signature of a method.
-class Signature : public ValueObject {
- public:
-  std::string ToString() const;
-
-  static Signature NoSignature() {
-    return Signature();
-  }
-
-  bool IsVoid() const;
-  uint32_t GetNumberOfParameters() const;
-
-  bool operator==(const Signature& rhs) const;
-  bool operator!=(const Signature& rhs) const {
-    return !(*this == rhs);
-  }
-
-  bool operator==(const StringPiece& rhs) const;
-
- private:
-  Signature(const DexFile* dex, const dex::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
-  }
-
-  Signature() = default;
-
-  friend class DexFile;
-
-  const DexFile* const dex_file_ = nullptr;
-  const dex::ProtoId* const proto_id_ = nullptr;
-};
-std::ostream& operator<<(std::ostream& os, const Signature& sig);
-
 class EncodedArrayValueIterator {
  public:
   EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
diff --git a/libdexfile/dex/signature-inl.h b/libdexfile/dex/signature-inl.h
new file mode 100644
index 0000000..ccc7ea9
--- /dev/null
+++ b/libdexfile/dex/signature-inl.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_LIBDEXFILE_DEX_SIGNATURE_INL_H_
+#define ART_LIBDEXFILE_DEX_SIGNATURE_INL_H_
+
+#include "signature.h"
+
+#include "base/stringpiece.h"
+#include "dex_file-inl.h"
+
+namespace art {
+
+inline bool Signature::operator==(const Signature& rhs) const {
+  if (dex_file_ == nullptr) {
+    return rhs.dex_file_ == nullptr;
+  }
+  if (rhs.dex_file_ == nullptr) {
+    return false;
+  }
+  if (dex_file_ == rhs.dex_file_) {
+    return proto_id_ == rhs.proto_id_;
+  }
+  uint32_t lhs_shorty_len;  // For a shorty utf16 length == mutf8 length.
+  const char* lhs_shorty_data = dex_file_->StringDataAndUtf16LengthByIdx(proto_id_->shorty_idx_,
+                                                                         &lhs_shorty_len);
+  StringPiece lhs_shorty(lhs_shorty_data, lhs_shorty_len);
+  {
+    uint32_t rhs_shorty_len;
+    const char* rhs_shorty_data =
+        rhs.dex_file_->StringDataAndUtf16LengthByIdx(rhs.proto_id_->shorty_idx_,
+                                                     &rhs_shorty_len);
+    StringPiece rhs_shorty(rhs_shorty_data, rhs_shorty_len);
+    if (lhs_shorty != rhs_shorty) {
+      return false;  // Shorty mismatch.
+    }
+  }
+  if (lhs_shorty[0] == 'L') {
+    const dex::TypeId& return_type_id = dex_file_->GetTypeId(proto_id_->return_type_idx_);
+    const dex::TypeId& rhs_return_type_id =
+        rhs.dex_file_->GetTypeId(rhs.proto_id_->return_type_idx_);
+    if (!DexFile::StringEquals(dex_file_, return_type_id.descriptor_idx_,
+                               rhs.dex_file_, rhs_return_type_id.descriptor_idx_)) {
+      return false;  // Return type mismatch.
+    }
+  }
+  if (lhs_shorty.find('L', 1) != StringPiece::npos) {
+    const dex::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
+    const dex::TypeList* rhs_params = rhs.dex_file_->GetProtoParameters(*rhs.proto_id_);
+    // We found a reference parameter in the matching shorty, so both lists must be non-empty.
+    DCHECK(params != nullptr);
+    DCHECK(rhs_params != nullptr);
+    uint32_t params_size = params->Size();
+    DCHECK_EQ(params_size, rhs_params->Size());  // Parameter list size must match.
+    for (uint32_t i = 0; i < params_size; ++i) {
+      const dex::TypeId& param_id = dex_file_->GetTypeId(params->GetTypeItem(i).type_idx_);
+      const dex::TypeId& rhs_param_id =
+          rhs.dex_file_->GetTypeId(rhs_params->GetTypeItem(i).type_idx_);
+      if (!DexFile::StringEquals(dex_file_, param_id.descriptor_idx_,
+                                 rhs.dex_file_, rhs_param_id.descriptor_idx_)) {
+        return false;  // Parameter type mismatch.
+      }
+    }
+  }
+  return true;
+}
+
+}  // namespace art
+
+#endif  // ART_LIBDEXFILE_DEX_SIGNATURE_INL_H_
diff --git a/libdexfile/dex/signature.cc b/libdexfile/dex/signature.cc
new file mode 100644
index 0000000..34b4b55
--- /dev/null
+++ b/libdexfile/dex/signature.cc
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "signature-inl.h"
+
+#include <string.h>
+
+#include <ostream>
+#include <type_traits>
+
+namespace art {
+
+using dex::TypeList;
+
+std::string Signature::ToString() const {
+  if (dex_file_ == nullptr) {
+    CHECK(proto_id_ == nullptr);
+    return "<no signature>";
+  }
+  const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
+  std::string result;
+  if (params == nullptr) {
+    result += "()";
+  } else {
+    result += "(";
+    for (uint32_t i = 0; i < params->Size(); ++i) {
+      result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_);
+    }
+    result += ")";
+  }
+  result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
+  return result;
+}
+
+uint32_t Signature::GetNumberOfParameters() const {
+  const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
+  return (params != nullptr) ? params->Size() : 0;
+}
+
+bool Signature::IsVoid() const {
+  const char* return_type = dex_file_->GetReturnTypeDescriptor(*proto_id_);
+  return strcmp(return_type, "V") == 0;
+}
+
+bool Signature::operator==(const StringPiece& rhs) const {
+  if (dex_file_ == nullptr) {
+    return false;
+  }
+  StringPiece tail(rhs);
+  if (!tail.starts_with("(")) {
+    return false;  // Invalid signature
+  }
+  tail.remove_prefix(1);  // "(";
+  const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
+  if (params != nullptr) {
+    for (uint32_t i = 0; i < params->Size(); ++i) {
+      StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
+      if (!tail.starts_with(param)) {
+        return false;
+      }
+      tail.remove_prefix(param.length());
+    }
+  }
+  if (!tail.starts_with(")")) {
+    return false;
+  }
+  tail.remove_prefix(1);  // ")";
+  return tail == dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
+}
+
+std::ostream& operator<<(std::ostream& os, const Signature& sig) {
+  return os << sig.ToString();
+}
+
+}  // namespace art
diff --git a/libdexfile/dex/signature.h b/libdexfile/dex/signature.h
new file mode 100644
index 0000000..235f37c
--- /dev/null
+++ b/libdexfile/dex/signature.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_LIBDEXFILE_DEX_SIGNATURE_H_
+#define ART_LIBDEXFILE_DEX_SIGNATURE_H_
+
+#include <iosfwd>
+#include <string>
+
+#include <android-base/logging.h>
+
+#include "base/value_object.h"
+
+namespace art {
+
+namespace dex {
+struct ProtoId;
+}  // namespace dex
+class DexFile;
+class StringPiece;
+
+// Abstract the signature of a method.
+class Signature : public ValueObject {
+ public:
+  std::string ToString() const;
+
+  static Signature NoSignature() {
+    return Signature();
+  }
+
+  bool IsVoid() const;
+  uint32_t GetNumberOfParameters() const;
+
+  bool operator==(const Signature& rhs) const;
+  bool operator!=(const Signature& rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator==(const StringPiece& rhs) const;
+
+ private:
+  Signature(const DexFile* dex, const dex::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
+  }
+
+  Signature() = default;
+
+  friend class DexFile;
+
+  const DexFile* const dex_file_ = nullptr;
+  const dex::ProtoId* const proto_id_ = nullptr;
+};
+std::ostream& operator<<(std::ostream& os, const Signature& sig);
+
+}  // namespace art
+
+#endif  // ART_LIBDEXFILE_DEX_SIGNATURE_H_
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index 3655300..4bcb7b2 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -49,6 +49,7 @@
 #include "dex/dex_file.h"
 #include "dex/dex_file_loader.h"
 #include "dex/dex_file_types.h"
+#include "dex/signature-inl.h"
 #include "events-inl.h"
 #include "gc/allocation_listener.h"
 #include "gc/heap.h"
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index dd62853..e273d94 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -31,6 +31,7 @@
 #include "dex/dex_file-inl.h"
 #include "dex/dex_file_exception_helpers.h"
 #include "dex/dex_instruction.h"
+#include "dex/signature-inl.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc/accounting/card_table-inl.h"
 #include "hidden_api.h"
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 6b598da..70bcbc9 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -20,6 +20,7 @@
 #include <cstddef>
 
 #include <android-base/logging.h>
+#include <jni.h>
 
 #include "base/array_ref.h"
 #include "base/bit_utils.h"
@@ -33,6 +34,7 @@
 #include "dex/dex_instruction_iterator.h"
 #include "dex/modifiers.h"
 #include "dex/primitive.h"
+#include "dex/signature.h"
 #include "gc_root.h"
 #include "obj_ptr.h"
 #include "offsets.h"
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c22a5cb..5d1f20c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -61,6 +61,7 @@
 #include "dex/dex_file-inl.h"
 #include "dex/dex_file_exception_helpers.h"
 #include "dex/dex_file_loader.h"
+#include "dex/signature-inl.h"
 #include "dex/utf.h"
 #include "entrypoints/entrypoint_utils.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index f3aefc2..2f37123 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -28,6 +28,7 @@
 #include "class_root.h"
 #include "common_runtime_test.h"
 #include "dex/dex_file_types.h"
+#include "dex/signature-inl.h"
 #include "dex/standard_dex_file.h"
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "experimental_flags.h"
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 515394a..53c9cc7 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -30,6 +30,7 @@
 #include "dex/descriptors_names.h"
 #include "dex/dex_file-inl.h"
 #include "dex/dex_file_annotations.h"
+#include "dex/signature-inl.h"
 #include "dex_cache.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/heap-inl.h"
diff --git a/tools/dexanalyze/dexanalyze_bytecode.h b/tools/dexanalyze/dexanalyze_bytecode.h
index 015801f..da4249d 100644
--- a/tools/dexanalyze/dexanalyze_bytecode.h
+++ b/tools/dexanalyze/dexanalyze_bytecode.h
@@ -24,6 +24,7 @@
 #include "base/safe_map.h"
 #include "dexanalyze_experiments.h"
 #include "dex/code_item_accessors.h"
+#include "dex/dex_file_types.h"
 
 namespace art {
 namespace dexanalyze {
diff --git a/tools/veridex/resolver.cc b/tools/veridex/resolver.cc
index 0d769cd..df097b6 100644
--- a/tools/veridex/resolver.cc
+++ b/tools/veridex/resolver.cc
@@ -19,6 +19,7 @@
 #include "dex/class_accessor-inl.h"
 #include "dex/dex_file-inl.h"
 #include "dex/primitive.h"
+#include "dex/signature-inl.h"
 #include "hidden_api.h"
 #include "veridex.h"