Merge "Check same dex file for finding class descriptor string id"
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index 8a0f4cf..a65e82b 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -16,6 +16,8 @@
#include "verifier_deps.h"
+#include <cstring>
+
#include "compiler_callbacks.h"
#include "leb128.h"
#include "mirror/class-inl.h"
@@ -56,17 +58,80 @@
}
}
-template <typename T>
-uint32_t VerifierDeps::GetDeclaringClassStringId(const DexFile& dex_file, T* element) {
+uint32_t VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
+ ObjPtr<mirror::Class> klass) {
+ DCHECK(klass != nullptr);
+ ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
+ // Array classes do not have a dex cache.
+ if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
+ DCHECK(dex_cache != nullptr) << klass->PrettyClass();
+ if (dex_cache->GetDexFile() == &dex_file) {
+ // FindStringId is slow, try to go through the class def if we have one.
+ const DexFile::ClassDef* class_def = klass->GetClassDef();
+ DCHECK(class_def != nullptr) << klass->PrettyClass();
+ std::string temp;
+ const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
+ DCHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
+ return type_id.descriptor_idx_;
+ }
+ }
+ std::string temp;
+ return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
+}
+
+// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
+static uint32_t TryGetClassDescriptorStringId(const DexFile& dex_file,
+ dex::TypeIndex type_idx,
+ ObjPtr<mirror::Class> klass)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (!klass->IsArrayClass()) {
+ const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
+ const DexFile& klass_dex = klass->GetDexFile();
+ const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
+ if (strcmp(dex_file.GetTypeDescriptor(type_id),
+ klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
+ return type_id.descriptor_idx_;
+ }
+ }
+ return DexFile::kDexNoIndex;
+}
+
+uint32_t VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_method_index,
+ ArtMethod* method) {
static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
- if (element == nullptr) {
+ if (method == nullptr) {
return VerifierDeps::kUnresolvedMarker;
- } else {
- std::string temp;
- uint32_t string_id = GetIdFromString(
- dex_file, element->GetDeclaringClass()->GetDescriptor(&temp));
+ }
+ const uint32_t string_id = TryGetClassDescriptorStringId(
+ dex_file,
+ dex_file.GetMethodId(dex_method_index).class_idx_,
+ method->GetDeclaringClass());
+ if (string_id != DexFile::kDexNoIndex) {
+ // Got lucky using the original dex file, return based on the input dex file.
+ DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
return string_id;
}
+ return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
+}
+
+uint32_t VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_field_idx,
+ ArtField* field) {
+ static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
+ if (field == nullptr) {
+ return VerifierDeps::kUnresolvedMarker;
+ }
+ const uint32_t string_id = TryGetClassDescriptorStringId(
+ dex_file,
+ dex_file.GetFieldId(dex_field_idx).class_idx_,
+ field->GetDeclaringClass());
+ if (string_id != DexFile::kDexNoIndex) {
+ // Got lucky using the original dex file, return based on the input dex file.
+ DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
+ return string_id;
+ }
+ return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
}
uint32_t VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
@@ -171,8 +236,11 @@
}
MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
- dex_deps->fields_.emplace(FieldResolution(
- field_idx, GetAccessFlags(field), GetDeclaringClassStringId(dex_file, field)));
+ dex_deps->fields_.emplace(FieldResolution(field_idx,
+ GetAccessFlags(field),
+ GetFieldDeclaringClassStringId(dex_file,
+ field_idx,
+ field)));
}
void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
@@ -194,7 +262,7 @@
MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
MethodResolution method_tuple(method_idx,
GetAccessFlags(method),
- GetDeclaringClassStringId(dex_file, method));
+ GetMethodDeclaringClassStringId(dex_file, method_idx, method));
if (resolution_kind == kDirectMethodResolution) {
dex_deps->direct_methods_.emplace(method_tuple);
} else if (resolution_kind == kVirtualMethodResolution) {
@@ -263,12 +331,8 @@
MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
// Get string IDs for both descriptors and store in the appropriate set.
-
- std::string temp1, temp2;
- std::string destination_desc(destination->GetDescriptor(&temp1));
- std::string source_desc(source->GetDescriptor(&temp2));
- uint32_t destination_id = GetIdFromString(dex_file, destination_desc);
- uint32_t source_id = GetIdFromString(dex_file, source_desc);
+ uint32_t destination_id = GetClassDescriptorStringId(dex_file, destination);
+ uint32_t source_id = GetClassDescriptorStringId(dex_file, source);
if (is_assignable) {
dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h
index 23e22d9..e35af41 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -232,8 +232,19 @@
// Returns a string ID of the descriptor of the declaring class of `element`,
// or `kUnresolvedMarker` if `element` is null.
- template <typename T>
- uint32_t GetDeclaringClassStringId(const DexFile& dex_file, T* element)
+ uint32_t GetMethodDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_method_idx,
+ ArtMethod* method)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(Locks::verifier_deps_lock_);
+ uint32_t GetFieldDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_field_idx,
+ ArtField* field)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(Locks::verifier_deps_lock_);
+
+ // Returns a string ID of the descriptor of the class.
+ uint32_t GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(Locks::verifier_deps_lock_);