Run Java verification of mainline modules at boot time.
To avoid doing it at app startup time.
Memory impact after boot (walleye rvc-dev)
- zygote64 RSS: 116184K -> 116828K (+642K)
- zygote64 PSS: 20218K -> 20612K (+394K)
- zygote32 RSS: 103712K -> 104276K (+564K)
- zygote32 PSS: 34509K -> 34598K (+89K)
Boot time impact (walleye rvc-dev)
- TOTAL_BOOT_TIME: 16622.9 -> 15769ms (in the normal deviation)
- Verified 1345 classes from mainline modules in 162ms (finishes
before preloading classes finish)
Boot time impact (blueline rvc-dev)
- TOTAL_BOOT_TIME: 16984.1 -> 17213ms (looks like in the normal
deviation)
- Verified 1345 classes from mainline modules in 168.928ms (finishes
before preloading classes finish)
Bug: 152552491
Test: boot
Change-Id: Ifa4ffe9da1ef66bbd5b3e20f737c85e79b520538
Merged-In: Ifa4ffe9da1ef66bbd5b3e20f737c85e79b520538
(cherry picked from commit 405b0970a267ce08194a1537010250d21208f2f2)
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 5dce6c5..f94c51e 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -870,6 +870,54 @@
DISALLOW_COPY_AND_ASSIGN(JitDoneCompilingProfileTask);
};
+/**
+ * A JIT task to run Java verification of boot classpath classes that were not
+ * verified at compile-time.
+ */
+class ZygoteVerificationTask final : public Task {
+ public:
+ ZygoteVerificationTask() {}
+
+ void Run(Thread* self) override {
+ Runtime* runtime = Runtime::Current();
+ ClassLinker* linker = runtime->GetClassLinker();
+ const std::vector<const DexFile*>& boot_class_path =
+ runtime->GetClassLinker()->GetBootClassPath();
+ ScopedObjectAccess soa(self);
+ StackHandleScope<1> hs(self);
+ MutableHandle<mirror::Class> klass = hs.NewHandle<mirror::Class>(nullptr);
+ uint64_t start_ns = ThreadCpuNanoTime();
+ uint64_t number_of_classes = 0;
+ for (const DexFile* dex_file : boot_class_path) {
+ if (dex_file->GetOatDexFile() != nullptr &&
+ dex_file->GetOatDexFile()->GetOatFile() != nullptr) {
+ // If backed by an .oat file, we have already run verification at
+ // compile-time. Note that some classes may still have failed
+ // verification there if they reference updatable mainline module
+ // classes.
+ continue;
+ }
+ for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
+ const dex::ClassDef& class_def = dex_file->GetClassDef(i);
+ const char* descriptor = dex_file->GetClassDescriptor(class_def);
+ ScopedNullHandle<mirror::ClassLoader> null_loader;
+ klass.Assign(linker->FindClass(self, descriptor, null_loader));
+ if (klass == nullptr) {
+ self->ClearException();
+ LOG(WARNING) << "Could not find " << descriptor;
+ continue;
+ }
+ ++number_of_classes;
+ linker->VerifyClass(self, klass);
+ }
+ }
+ LOG(INFO) << "Verified "
+ << number_of_classes
+ << " classes from mainline modules in "
+ << PrettyDuration(ThreadCpuNanoTime() - start_ns);
+ }
+};
+
class ZygoteTask final : public Task {
public:
ZygoteTask() {}
@@ -1150,6 +1198,23 @@
Start();
Runtime* runtime = Runtime::Current();
+ if (runtime->IsZygote()) {
+ // To speed up class lookups, generate a type lookup table for
+ // dex files not backed by oat file.
+ for (const DexFile* dex_file : runtime->GetClassLinker()->GetBootClassPath()) {
+ if (dex_file->GetOatDexFile() == nullptr) {
+ TypeLookupTable type_lookup_table = TypeLookupTable::Create(*dex_file);
+ type_lookup_tables_.push_back(
+ std::make_unique<art::OatDexFile>(std::move(type_lookup_table)));
+ dex_file->SetOatDexFile(type_lookup_tables_.back().get());
+ }
+ }
+
+ // Add a task that will verify boot classpath jars that were not
+ // pre-compiled.
+ thread_pool_->AddTask(Thread::Current(), new ZygoteVerificationTask());
+ }
+
if (runtime->IsZygote() && HasImageWithProfile() && UseJitCompilation()) {
// If we have an image with a profile, request a JIT task to
// compile all methods in that profile.
@@ -1363,14 +1428,6 @@
// The ART module jars are already preopted.
continue;
}
- // To speed up class lookups, generate a type lookup table for
- // the dex file.
- if (dex_file->GetOatDexFile() == nullptr) {
- TypeLookupTable type_lookup_table = TypeLookupTable::Create(*dex_file);
- type_lookup_tables_.push_back(
- std::make_unique<art::OatDexFile>(std::move(type_lookup_table)));
- dex_file->SetOatDexFile(type_lookup_tables_.back().get());
- }
std::set<dex::TypeIndex> class_types;
std::set<uint16_t> all_methods;