Code cleanup around vdex.
1) Handle the vdex in dex2oat instead of compiler_driver
2) CHECK instead of DCHECK that we don't dexlayout with vdex.
Test: test.py
Change-Id: Idf7be59bb25708181e391d17128480659ac697e5
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index e486e2e..7eaba96 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -39,10 +39,7 @@
TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
compiler_options_->boot_image_ = false;
compiler_options_->SetCompilerFilter(CompilerFilter::kQuicken);
- compiler_driver_->CompileAll(class_loader,
- GetDexFiles(class_loader),
- /* verifier_deps */ nullptr,
- &timings);
+ compiler_driver_->CompileAll(class_loader, GetDexFiles(class_loader), &timings);
}
void RunTest(const char* dex_name) {
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 91b58e1..2330b9a 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -425,26 +425,6 @@
FreeThreadPools();
}
-void CompilerDriver::CompileAll(jobject class_loader,
- const std::vector<const DexFile*>& dex_files,
- VdexFile* vdex_file,
- TimingLogger* timings) {
- if (vdex_file != nullptr) {
- // TODO: we unquicken unconditionnally, as we don't know
- // if the boot image has changed. How exactly we'll know is under
- // experimentation.
- TimingLogger::ScopedTiming t("Unquicken", timings);
- // We do not decompile a RETURN_VOID_NO_BARRIER into a RETURN_VOID, as the quickening
- // optimization does not depend on the boot image (the optimization relies on not
- // having final fields in a class, which does not change for an app).
- VdexFile::Unquicken(dex_files, vdex_file->GetQuickeningInfo());
-
- Runtime::Current()->GetCompilerCallbacks()->SetVerifierDeps(
- new verifier::VerifierDeps(dex_files, vdex_file->GetVerifierDepsData()));
- }
- CompileAll(class_loader, dex_files, timings);
-}
-
static optimizer::DexToDexCompilationLevel GetDexToDexCompilationLevel(
Thread* self, const CompilerDriver& driver, Handle<mirror::ClassLoader> class_loader,
const DexFile& dex_file, const DexFile::ClassDef& class_def)
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 38e7d2c..69f7b1b 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -119,12 +119,6 @@
TimingLogger* timings)
REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_);
- void CompileAll(jobject class_loader,
- const std::vector<const DexFile*>& dex_files,
- VdexFile* vdex_file,
- TimingLogger* timings)
- REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_);
-
// Compile a single Method.
void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings)
REQUIRES_SHARED(Locks::mutator_lock_)
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 4b979d8..1329fdd 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -42,10 +42,7 @@
void CompileAll(jobject class_loader) REQUIRES(!Locks::mutator_lock_) {
TimingLogger timings("CompilerDriverTest::CompileAll", false, false);
TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
- compiler_driver_->CompileAll(class_loader,
- GetDexFiles(class_loader),
- /* verifier_deps */ nullptr,
- &timings);
+ compiler_driver_->CompileAll(class_loader, GetDexFiles(class_loader), &timings);
t.NewTiming("MakeAllExecutable");
MakeAllExecutable(class_loader);
}
diff --git a/compiler/image_test.h b/compiler/image_test.h
index 3d89757..fa714ad 100644
--- a/compiler/image_test.h
+++ b/compiler/image_test.h
@@ -220,7 +220,7 @@
TimingLogger timings("ImageTest::WriteRead", false, false);
TimingLogger::ScopedTiming t("CompileAll", &timings);
driver->SetDexFilesForOatFile(class_path);
- driver->CompileAll(class_loader, class_path, /* verifier_deps */ nullptr, &timings);
+ driver->CompileAll(class_loader, class_path, &timings);
t.NewTiming("WriteElf");
SafeMap<std::string, std::string> key_value_store;
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 55d0bd9..910d7a7 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -400,8 +400,7 @@
if (kCompile) {
TimingLogger timings2("OatTest::WriteRead", false, false);
compiler_driver_->SetDexFilesForOatFile(class_linker->GetBootClassPath());
- compiler_driver_->CompileAll(
- class_loader, class_linker->GetBootClassPath(), /* verifier_deps */ nullptr, &timings2);
+ compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings2);
}
ScratchFile tmp_oat, tmp_vdex(tmp_oat, ".vdex");
@@ -415,8 +414,7 @@
ASSERT_TRUE(success);
if (kCompile) { // OatWriter strips the code, regenerate to compare
- compiler_driver_->CompileAll(
- class_loader, class_linker->GetBootClassPath(), /* verifier_deps */ nullptr, &timings);
+ compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings);
}
std::unique_ptr<OatFile> oat_file(OatFile::Open(tmp_oat.GetFilename(),
tmp_oat.GetFilename(),
@@ -540,7 +538,7 @@
soa.Decode<mirror::ClassLoader>(class_loader).Ptr());
}
compiler_driver_->SetDexFilesForOatFile(dex_files);
- compiler_driver_->CompileAll(class_loader, dex_files, /* verifier_deps */ nullptr, &timings);
+ compiler_driver_->CompileAll(class_loader, dex_files, &timings);
ScratchFile tmp_oat, tmp_vdex(tmp_oat, ".vdex");
SafeMap<std::string, std::string> key_value_store;
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 59daf5a..1df9c48 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -2544,7 +2544,7 @@
return false;
}
if (profile_compilation_info_ != nullptr) {
- DCHECK(!update_input_vdex);
+ CHECK(!update_input_vdex) << "We should never update the input vdex when doing dexlayout";
if (!LayoutAndWriteDexFile(out, oat_dex_file)) {
return false;
}
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index b88fe09..d5d927c 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1292,8 +1292,6 @@
}
// OAT and VDEX file handling
- bool eagerly_unquicken_vdex = DoDexLayoutOptimizations();
-
if (oat_fd_ == -1) {
DCHECK(!oat_filenames_.empty());
for (const char* oat_filename : oat_filenames_) {
@@ -1314,7 +1312,7 @@
input_vdex_file_ = VdexFile::Open(input_vdex_,
/* writable */ false,
/* low_4gb */ false,
- eagerly_unquicken_vdex,
+ DoEagerUnquickeningOfVdex(),
&error_msg);
}
@@ -1364,7 +1362,7 @@
"vdex",
/* writable */ false,
/* low_4gb */ false,
- eagerly_unquicken_vdex,
+ DoEagerUnquickeningOfVdex(),
&error_msg);
// If there's any problem with the passed vdex, just warn and proceed
// without it.
@@ -1770,7 +1768,19 @@
swap_fd_,
profile_compilation_info_.get()));
driver_->SetDexFilesForOatFile(dex_files_);
- driver_->CompileAll(class_loader_, dex_files_, input_vdex_file_.get(), timings_);
+
+ // Setup vdex for compilation.
+ if (!DoEagerUnquickeningOfVdex() && input_vdex_file_ != nullptr) {
+ callbacks_->SetVerifierDeps(
+ new verifier::VerifierDeps(dex_files_, input_vdex_file_->GetVerifierDepsData()));
+
+ // TODO: we unquicken unconditionally, as we don't know
+ // if the boot image has changed. How exactly we'll know is under
+ // experimentation.
+ TimingLogger::ScopedTiming time_unquicken("Unquicken", timings_);
+ VdexFile::Unquicken(dex_files_, input_vdex_file_->GetQuickeningInfo());
+ }
+ driver_->CompileAll(class_loader_, dex_files_, timings_);
}
// Notes on the interleaving of creating the images and oat files to
@@ -2146,6 +2156,12 @@
return DoProfileGuidedOptimizations();
}
+ bool DoEagerUnquickeningOfVdex() const {
+ // DexLayout can invalidate the vdex metadata, so we need to unquicken
+ // the vdex file eagerly, before passing it to dexlayout.
+ return DoDexLayoutOptimizations();
+ }
+
bool LoadProfile() {
DCHECK(UseProfile());
// TODO(calin): We should be using the runtime arena pool (instead of the
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 842aa04..5e9a2fa 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -171,6 +171,10 @@
// least the size of quickening data for each method that has a code item.
return;
}
+ // We do not decompile a RETURN_VOID_NO_BARRIER into a RETURN_VOID, as the quickening
+ // optimization does not depend on the boot image (the optimization relies on not
+ // having final fields in a class, which does not change for an app).
+ constexpr bool kDecompileReturnInstruction = false;
const uint8_t* quickening_info_ptr = quickening_info.data();
const uint8_t* const quickening_info_end = quickening_info.data() + quickening_info.size();
for (const DexFile* dex_file : dex_files) {
@@ -196,7 +200,7 @@
quickening_info_ptr += sizeof(uint32_t);
optimizer::ArtDecompileDEX(*code_item,
ArrayRef<const uint8_t>(quickening_info_ptr, quickening_size),
- /* decompile_return_instruction */ false);
+ kDecompileReturnInstruction);
quickening_info_ptr += quickening_size;
}
it.Next();
@@ -209,7 +213,7 @@
quickening_info_ptr += sizeof(uint32_t);
optimizer::ArtDecompileDEX(*code_item,
ArrayRef<const uint8_t>(quickening_info_ptr, quickening_size),
- /* decompile_return_instruction */ false);
+ kDecompileReturnInstruction);
quickening_info_ptr += quickening_size;
}
it.Next();