summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2018-05-04 11:28:03 +0100
committer David Brazdil <dbrazdil@google.com> 2018-05-14 13:40:47 +0100
commit1ab0fa89aed1100a3e6b631cb188db1d759b1efc (patch)
treeac0045dacc945b00e3d1eda30dabe27435f9d835 /runtime/class_linker.cc
parent6623bc389c43efc87668ce7465e19b195e765e22 (diff)
Refactor ClassLinker & ImageWriter to use a common resolution routine
ImageWriter prepopulates DexCaches of an app image, but does resolution directly on mirror::Class rather than going through the class linker where hidden API checks happen. This patch removes the duplicate code. Similarly, ClassLinker contains multiple methods for resolving methods and fields. Consolidate these into three common routines: - FindResolvedMethod - FindResolvedField - FindResolvedFieldJLS The CL also passes the correct class loader to ImageWriter::PruneAndPreloadDexCache because it would trip a DCHECK in class linker. Bug: 78548674 Test: art/test.py Change-Id: I12e383290945d2f44b209c32e8a7617533d86063
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc109
1 files changed, 62 insertions, 47 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 4141a37366..9c8b4383dc 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4850,6 +4850,9 @@ bool ClassLinker::InitializeClass(Thread* self, Handle<mirror::Class> klass,
const uint32_t field_idx = field->GetDexFieldIndex();
ArtField* resolved_field = dex_cache->GetResolvedField(field_idx, image_pointer_size_);
if (resolved_field == nullptr) {
+ // Populating cache of a dex file which defines `klass` should always be allowed.
+ DCHECK_EQ(hiddenapi::GetMemberAction(
+ field, class_loader.Get(), dex_cache.Get(), hiddenapi::kNone), hiddenapi::kAllow);
dex_cache->SetResolvedField(field_idx, field, image_pointer_size_);
} else {
DCHECK_EQ(field, resolved_field);
@@ -8053,26 +8056,8 @@ ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx,
return nullptr;
}
DCHECK(klass->IsResolved());
- Thread* self = is_static ? Thread::Current() : nullptr;
-
- // First try to find a field declared directly by `klass` by the field index.
- ArtField* resolved_field = is_static
- ? mirror::Class::FindStaticField(self, klass, dex_cache, field_idx)
- : klass->FindInstanceField(dex_cache, field_idx);
-
- if (resolved_field == nullptr) {
- // If not found in `klass` by field index, search the class hierarchy using the name and type.
- const char* name = dex_file.GetFieldName(field_id);
- const char* type = dex_file.GetFieldTypeDescriptor(field_id);
- resolved_field = is_static
- ? mirror::Class::FindStaticField(self, klass, name, type)
- : klass->FindInstanceField(name, type);
- }
- if (resolved_field != nullptr) {
- dex_cache->SetResolvedField(field_idx, resolved_field, image_pointer_size_);
- }
- return resolved_field;
+ return FindResolvedField(klass, dex_cache, class_loader, field_idx, is_static);
}
ArtField* ClassLinker::ResolveField(uint32_t field_idx,
@@ -8087,39 +8072,18 @@ ArtField* ClassLinker::ResolveField(uint32_t field_idx,
}
const DexFile& dex_file = *dex_cache->GetDexFile();
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
- Thread* const self = Thread::Current();
ObjPtr<mirror::Class> klass = ResolveType(field_id.class_idx_, dex_cache, class_loader);
if (klass == nullptr) {
DCHECK(Thread::Current()->IsExceptionPending());
return nullptr;
}
- if (is_static) {
- resolved = mirror::Class::FindStaticField(self, klass, dex_cache.Get(), field_idx);
- } else {
- resolved = klass->FindInstanceField(dex_cache.Get(), field_idx);
- }
-
+ resolved = FindResolvedField(klass, dex_cache.Get(), class_loader.Get(), field_idx, is_static);
if (resolved == nullptr) {
const char* name = dex_file.GetFieldName(field_id);
const char* type = dex_file.GetFieldTypeDescriptor(field_id);
- if (is_static) {
- resolved = mirror::Class::FindStaticField(self, klass, name, type);
- } else {
- resolved = klass->FindInstanceField(name, type);
- }
- }
-
- if (resolved == nullptr ||
- hiddenapi::GetMemberAction(
- resolved, class_loader.Get(), dex_cache.Get(), hiddenapi::kLinking) == hiddenapi::kDeny) {
- const char* name = dex_file.GetFieldName(field_id);
- const char* type = dex_file.GetFieldTypeDescriptor(field_id);
ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass, type, name);
- return nullptr;
}
-
- dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
return resolved;
}
@@ -8134,26 +8098,77 @@ ArtField* ClassLinker::ResolveFieldJLS(uint32_t field_idx,
}
const DexFile& dex_file = *dex_cache->GetDexFile();
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
- Thread* self = Thread::Current();
ObjPtr<mirror::Class> klass = ResolveType(field_id.class_idx_, dex_cache, class_loader);
if (klass == nullptr) {
DCHECK(Thread::Current()->IsExceptionPending());
return nullptr;
}
- StringPiece name(dex_file.GetFieldName(field_id));
- StringPiece type(dex_file.GetFieldTypeDescriptor(field_id));
+ resolved = FindResolvedFieldJLS(klass, dex_cache.Get(), class_loader.Get(), field_idx);
+ if (resolved == nullptr) {
+ const char* name = dex_file.GetFieldName(field_id);
+ const char* type = dex_file.GetFieldTypeDescriptor(field_id);
+ ThrowNoSuchFieldError("", klass, type, name);
+ }
+ return resolved;
+}
+
+ArtField* ClassLinker::FindResolvedField(ObjPtr<mirror::Class> klass,
+ ObjPtr<mirror::DexCache> dex_cache,
+ ObjPtr<mirror::ClassLoader> class_loader,
+ uint32_t field_idx,
+ bool is_static) {
+ ArtField* resolved = nullptr;
+ Thread* self = is_static ? Thread::Current() : nullptr;
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+
+ resolved = is_static ? mirror::Class::FindStaticField(self, klass, dex_cache, field_idx)
+ : klass->FindInstanceField(dex_cache, field_idx);
+
+ if (resolved == nullptr) {
+ const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
+ const char* name = dex_file.GetFieldName(field_id);
+ const char* type = dex_file.GetFieldTypeDescriptor(field_id);
+ resolved = is_static ? mirror::Class::FindStaticField(self, klass, name, type)
+ : klass->FindInstanceField(name, type);
+ }
+
+ if (resolved != nullptr &&
+ hiddenapi::GetMemberAction(
+ resolved, class_loader, dex_cache, hiddenapi::kLinking) == hiddenapi::kDeny) {
+ resolved = nullptr;
+ }
+
+ if (resolved != nullptr) {
+ dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
+ }
+
+ return resolved;
+}
+
+ArtField* ClassLinker::FindResolvedFieldJLS(ObjPtr<mirror::Class> klass,
+ ObjPtr<mirror::DexCache> dex_cache,
+ ObjPtr<mirror::ClassLoader> class_loader,
+ uint32_t field_idx) {
+ ArtField* resolved = nullptr;
+ Thread* self = Thread::Current();
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+ const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
+
+ const char* name = dex_file.GetFieldName(field_id);
+ const char* type = dex_file.GetFieldTypeDescriptor(field_id);
resolved = mirror::Class::FindField(self, klass, name, type);
+
if (resolved != nullptr &&
hiddenapi::GetMemberAction(
- resolved, class_loader.Get(), dex_cache.Get(), hiddenapi::kLinking) == hiddenapi::kDeny) {
+ resolved, class_loader, dex_cache, hiddenapi::kLinking) == hiddenapi::kDeny) {
resolved = nullptr;
}
+
if (resolved != nullptr) {
dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
- } else {
- ThrowNoSuchFieldError("", klass, type, name);
}
+
return resolved;
}