summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/linker/image_test.h1
-rw-r--r--libdexfile/Android.bp1
-rw-r--r--libdexfile/dex/code_item_accessors-inl.h52
-rw-r--r--libdexfile/dex/code_item_accessors.h18
-rw-r--r--libdexfile/dex/dex_file-inl.h54
-rw-r--r--libdexfile/dex/dex_file.cc60
-rw-r--r--libdexfile/dex/dex_file.h34
-rw-r--r--libdexfile/dex/signature-inl.h83
-rw-r--r--libdexfile/dex/signature.cc88
-rw-r--r--libdexfile/dex/signature.h69
-rw-r--r--openjdkjvmti/ti_redefine.cc1
-rw-r--r--runtime/art_method.cc1
-rw-r--r--runtime/art_method.h2
-rw-r--r--runtime/class_linker.cc1
-rw-r--r--runtime/class_linker_test.cc1
-rw-r--r--runtime/mirror/class.cc1
-rw-r--r--tools/dexanalyze/dexanalyze_bytecode.h1
-rw-r--r--tools/veridex/resolver.cc1
18 files changed, 295 insertions, 174 deletions
diff --git a/dex2oat/linker/image_test.h b/dex2oat/linker/image_test.h
index 70a22b5077..8c9dfb8969 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 a4f7e25128..9c48aa2c1b 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -32,6 +32,7 @@ cc_defaults {
"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 15e34b74be..632a787618 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 @@ inline void CodeItemInstructionAccessor::Init(uint32_t insns_size_in_code_units,
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 @@ inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& co
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 @@ inline IterationRange<DexInstructionIterator> CodeItemInstructionAccessor::Instr
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 @@ inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item
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 @@ inline void CodeItemDataAccessor::Init(const DexFile& dex_file,
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 @@ inline const void* CodeItemDataAccessor::CodeItemDataEnd() const {
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 @@ inline void CodeItemDebugInfoAccessor::Init(const DexFile& dex_file,
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 0ae5905860..794f2347d8 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 @@ struct TryItem;
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 @@ class CodeItemInstructionAccessor {
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 @@ class CodeItemDataAccessor : public CodeItemInstructionAccessor {
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 @@ class CodeItemDebugInfoAccessor : public CodeItemDataAccessor {
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 58fc893e90..9a720c2692 100644
--- a/libdexfile/dex/dex_file-inl.h
+++ b/libdexfile/dex/dex_file-inl.h
@@ -163,60 +163,6 @@ inline bool DexFile::StringEquals(const DexFile* df1, dex::StringIndex sidx1,
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 ff519064f1..5c100e6005 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -604,66 +604,6 @@ std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) {
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 05e4b61752..cf327804f2 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 @@ class DexInstructionIterator;
enum InvokeType : uint32_t;
class MemMap;
class OatDexFile;
-class Signature;
class StandardDexFile;
class StringPiece;
class ZipArchive;
@@ -911,38 +911,6 @@ class DexFileParameterIterator {
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 0000000000..ccc7ea9619
--- /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 0000000000..34b4b55f8c
--- /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 0000000000..235f37ca99
--- /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 365530072d..4bcb7b2642 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 dd628536c9..e273d94623 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 6b598da6b3..70bcbc9831 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 c22a5cbcd6..5d1f20c6cd 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 f3aefc2701..2f3712343c 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 515394ab18..53c9cc72e5 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 015801f516..da4249d28d 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 0d769cda31..df097b6263 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"