diff options
author | 2017-07-19 20:50:23 +0000 | |
---|---|---|
committer | 2017-07-19 20:50:23 +0000 | |
commit | 187ff4576847ab54db7e2eea6e6a55ccf7d1c40a (patch) | |
tree | 7fecc1f7d9c662d32233a2399516072c23ec0392 /compiler/driver/compiler_driver.cc | |
parent | 6c13ce8b4ccdb6127c4428cf8b2c8261dccced20 (diff) | |
parent | 1a088d440a3fac4e477a11af68adae9dcd3afd00 (diff) |
Merge "Use AtomicDexRefMap for compiled classes"
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
-rw-r--r-- | compiler/driver/compiler_driver.cc | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index b3160dd900..f3718c467b 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -291,7 +291,6 @@ CompilerDriver::CompilerDriver( instruction_set_(instruction_set == kArm ? kThumb2 : instruction_set), instruction_set_features_(instruction_set_features), requires_constructor_barrier_lock_("constructor barrier lock"), - compiled_classes_lock_("compiled classes lock"), non_relative_linker_patch_count_(0u), image_classes_(image_classes), classes_to_compile_(compiled_classes), @@ -1947,7 +1946,12 @@ bool CompilerDriver::FastVerify(jobject jclass_loader, if (compiler_only_verifies) { // Just update the compiled_classes_ map. The compiler doesn't need to resolve // the type. - compiled_classes_.Overwrite(ClassReference(dex_file, i), mirror::Class::kStatusVerified); + DexFileReference ref(dex_file, i); + mirror::Class::Status existing = mirror::Class::kStatusNotReady; + DCHECK(compiled_classes_.Get(ref, &existing)) << ref.dex_file->GetLocation(); + ClassStateTable::InsertResult result = + compiled_classes_.Insert(ref, existing, mirror::Class::kStatusVerified); + CHECK_EQ(result, ClassStateTable::kInsertResultSuccess); } else { // Update the class status, so later compilation stages know they don't need to verify // the class. @@ -1978,6 +1982,13 @@ bool CompilerDriver::FastVerify(jobject jclass_loader, void CompilerDriver::Verify(jobject jclass_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings) { + // Always add the dex files to compiled_classes_. This happens for all compiler filters. + for (const DexFile* dex_file : dex_files) { + if (!compiled_classes_.HaveDexFile(dex_file)) { + compiled_classes_.AddDexFile(dex_file, dex_file->NumClassDefs()); + } + } + if (FastVerify(jclass_loader, dex_files, timings)) { return; } @@ -2202,6 +2213,9 @@ void CompilerDriver::SetVerifiedDexFile(jobject class_loader, size_t thread_count, TimingLogger* timings) { TimingLogger::ScopedTiming t("Verify Dex File", timings); + if (!compiled_classes_.HaveDexFile(&dex_file)) { + compiled_classes_.AddDexFile(&dex_file, dex_file.NumClassDefs()); + } ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files, thread_pool); @@ -2248,12 +2262,13 @@ class InitializeClassVisitor : public CompilationVisitor { const bool is_app_image = manager_->GetCompiler()->GetCompilerOptions().IsAppImage(); mirror::Class::Status old_status = klass->GetStatus(); + // Don't initialize classes in boot space when compiling app image + if (is_app_image && klass->IsBootStrapClassLoaded()) { + // Also return early and don't store the class status in the recorded class status. + return; + } // Only try to initialize classes that were successfully verified. if (klass->IsVerified()) { - // Don't initialize classes in boot space when compiling app image - if (is_app_image && klass->IsBootStrapClassLoaded()) { - return; - } // Attempt to initialize the class but bail if we either need to initialize the super-class // or static fields. manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, false); @@ -2860,12 +2875,12 @@ void CompilerDriver::AddCompiledMethod(const MethodReference& method_ref, bool CompilerDriver::GetCompiledClass(ClassReference ref, mirror::Class::Status* status) const { DCHECK(status != nullptr); - MutexLock mu(Thread::Current(), compiled_classes_lock_); - ClassStateTable::const_iterator it = compiled_classes_.find(ref); - if (it == compiled_classes_.end()) { + // The table doesn't know if something wasn't inserted. For this case it will return + // kStatusNotReady. To handle this, just assume anything not verified is not compiled. + if (!compiled_classes_.Get(DexFileReference(ref.first, ref.second), status) || + *status < mirror::Class::kStatusVerified) { return false; } - *status = it->second; return true; } @@ -2886,15 +2901,20 @@ void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status << " of " << status; } - MutexLock mu(Thread::Current(), compiled_classes_lock_); - auto it = compiled_classes_.find(ref); - if (it == compiled_classes_.end()) { - compiled_classes_.Overwrite(ref, status); - } else if (status > it->second) { + ClassStateTable::InsertResult result; + do { + DexFileReference dex_ref(ref.first, ref.second); + mirror::Class::Status existing = mirror::Class::kStatusNotReady; + CHECK(compiled_classes_.Get(dex_ref, &existing)) << dex_ref.dex_file->GetLocation(); + if (existing >= status) { + // Existing status is already better than we expect, break. + break; + } // Update the status if we now have a greater one. This happens with vdex, // which records a class is verified, but does not resolve it. - it->second = status; - } + result = compiled_classes_.Insert(dex_ref, existing, status); + CHECK(result != ClassStateTable::kInsertResultInvalidDexFile); + } while (result != ClassStateTable::kInsertResultSuccess); } CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const { |