Hash-based DexCache methods array.
Total boot*.art size for aosp_angler-userdebug:
- arm64:
- before: 11603968
- after: 10129408 (-1.4MiB, -12.7%)
- arm:
- before: 8626176
- after: 7888896 (-0.7MiB, -8.5%)
Test: m test-art-host-gtest
Test: testrunner.py --host
Test: Nexus 6P boots.
Test: testrunner.py --target
Test: Build aosp_mips64-eng
Bug: 30627598
Change-Id: I7f858605de5f074cbd7f0d9c4c072fbd44aee28f
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index f8bb417..4d258af 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -1116,6 +1116,7 @@
const std::vector<const DexFile*>* dex_files)
: OatDexMethodVisitor(writer, offset),
pointer_size_(GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet())),
+ class_loader_(writer->HasImage() ? writer->image_writer_->GetClassLoader() : nullptr),
dex_files_(dex_files),
class_linker_(Runtime::Current()->GetClassLinker()) {}
@@ -1131,10 +1132,7 @@
if (!IsImageClass()) {
return true;
}
- ScopedObjectAccessUnchecked soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- Handle<mirror::DexCache> dex_cache = hs.NewHandle(
- class_linker_->FindDexCache(Thread::Current(), *dex_file));
+ ObjPtr<mirror::DexCache> dex_cache = class_linker_->FindDexCache(Thread::Current(), *dex_file);
const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
mirror::Class* klass = dex_cache->GetResolvedType(class_def.class_idx_);
if (klass != nullptr) {
@@ -1182,36 +1180,36 @@
++method_offsets_index_;
}
- // Unchecked as we hold mutator_lock_ on entry.
- ScopedObjectAccessUnchecked soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker_->FindDexCache(
- Thread::Current(), *dex_file_)));
+ Thread* self = Thread::Current();
+ ObjPtr<mirror::DexCache> dex_cache = class_linker_->FindDexCache(self, *dex_file_);
ArtMethod* method;
if (writer_->HasBootImage()) {
const InvokeType invoke_type = it.GetMethodInvokeType(
dex_file_->GetClassDef(class_def_index_));
+ // Unchecked as we hold mutator_lock_ on entry.
+ ScopedObjectAccessUnchecked soa(self);
+ StackHandleScope<1> hs(self);
method = class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
*dex_file_,
it.GetMemberIndex(),
- dex_cache,
+ hs.NewHandle(dex_cache),
ScopedNullHandle<mirror::ClassLoader>(),
nullptr,
invoke_type);
if (method == nullptr) {
LOG(FATAL_WITHOUT_ABORT) << "Unexpected failure to resolve a method: "
<< dex_file_->PrettyMethod(it.GetMemberIndex(), true);
- soa.Self()->AssertPendingException();
- mirror::Throwable* exc = soa.Self()->GetException();
+ self->AssertPendingException();
+ mirror::Throwable* exc = self->GetException();
std::string dump = exc->Dump();
LOG(FATAL) << dump;
UNREACHABLE();
}
} else {
- // Should already have been resolved by the compiler, just peek into the dex cache.
+ // Should already have been resolved by the compiler.
// It may not be resolved if the class failed to verify, in this case, don't set the
- // entrypoint. This is not fatal since the dex cache will contain a resolution method.
- method = dex_cache->GetResolvedMethod(it.GetMemberIndex(), pointer_size_);
+ // entrypoint. This is not fatal since we shall use a resolution method.
+ method = class_linker_->LookupResolvedMethod(it.GetMemberIndex(), dex_cache, class_loader_);
}
if (method != nullptr &&
compiled_method != nullptr &&
@@ -1252,6 +1250,7 @@
private:
const PointerSize pointer_size_;
+ ObjPtr<mirror::ClassLoader> class_loader_;
const std::vector<const DexFile*>* dex_files_;
ClassLinker* const class_linker_;
std::vector<std::pair<ArtMethod*, ArtMethod*>> methods_to_process_;
@@ -1471,7 +1470,8 @@
ObjPtr<mirror::DexCache> dex_cache =
(dex_file_ == ref.dex_file) ? dex_cache_ : class_linker_->FindDexCache(
Thread::Current(), *ref.dex_file);
- ArtMethod* method = dex_cache->GetResolvedMethod(ref.dex_method_index, pointer_size_);
+ ArtMethod* method =
+ class_linker_->LookupResolvedMethod(ref.dex_method_index, dex_cache, class_loader_);
CHECK(method != nullptr);
return method;
}