summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2016-11-17 13:08:35 -0800
committer Mathieu Chartier <mathieuc@google.com> 2016-11-21 13:28:23 -0800
commit32b50302d9826430013e008b45d5c71e6b7a2469 (patch)
tree210a7c575cc246787afdbbd988a45c8f38b8b169
parenta598b869b255b4daeaa34d1dd0939222a3a791b7 (diff)
Check same dex file for finding class descriptor string id
Use ClassDef for finding same dex file class descriptor string id for vdex. Removes some calls to FindStringId, the remaining calls to FindStringId are due to multidex or referring to types in the boot class path. Also check method index slot to see if we get lucky. Host perf: DexFile::FindStringId: 2.57% -> 0.94% Not done for fields since these do not seem to reach the FindStringId case accordingto perf. The remaining calls to FindStringId come from: 100.00% verifier::VerifierDeps::GetClassDescriptorStringId -> 66.62% verifier::VerifierDeps::AddAssignability -> 33.38% verifier::VerifierDeps::AddMethodResolution FB install time: 35.54s -> 34.41s (avg of 40 samples at 960MHZ N6P). Bug: 32641252 Test: test-art-host Change-Id: If50408cf1be5c2d2127140780b8d5af66306939c
-rw-r--r--runtime/verifier/verifier_deps.cc96
-rw-r--r--runtime/verifier/verifier_deps.h15
2 files changed, 93 insertions, 18 deletions
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index 8a0f4cfa31..a65e82b3df 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 @@ uint16_t VerifierDeps::GetAccessFlags(T* element) {
}
}
-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 @@ void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
}
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 @@ void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
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 @@ void VerifierDeps::AddAssignability(const DexFile& dex_file,
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 23e22d956d..e35af41e3f 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -232,8 +232,19 @@ class VerifierDeps {
// 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_);