Revert "Make 'quicken' an alias to 'verify'."
This reverts commit 4f0e8daf7ed79c0712c0fd927c8ad2c903c15773.
Reason for revert: Droidcop-triggered revert due to breakage https://android-build.googleplex.com/builds/tests/view?invocationId=I69100006175866595&testResultId=TR93113908724113263, bug 170588354, bug 170589481, bug 170589988.
Change-Id: If8f4396aa0db024ed5817a4fed61c13caf32f785
diff --git a/dex2oat/dex/dex_to_dex_decompiler_test.cc b/dex2oat/dex/dex_to_dex_decompiler_test.cc
index e754d5d..9d65436 100644
--- a/dex2oat/dex/dex_to_dex_decompiler_test.cc
+++ b/dex2oat/dex/dex_to_dex_decompiler_test.cc
@@ -40,7 +40,7 @@
void CompileAll(jobject class_loader) REQUIRES(!Locks::mutator_lock_) {
TimingLogger timings("DexToDexDecompilerTest::CompileAll", false, false);
compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
- compiler_options_->SetCompilerFilter(CompilerFilter::kVerify);
+ compiler_options_->SetCompilerFilter(CompilerFilter::kQuicken);
// Create the main VerifierDeps, here instead of in the compiler since we want to aggregate
// the results for all the dex files, not just the results for the current dex file.
down_cast<QuickCompilerCallbacks*>(Runtime::Current()->GetCompilerCallbacks())->SetVerifierDeps(
@@ -77,6 +77,9 @@
updated_dex_file->EnableWrite();
CompileAll(class_loader);
+ // The dex files should be different after quickening.
+ cmp = memcmp(original_dex_file->Begin(), updated_dex_file->Begin(), updated_dex_file->Size());
+ ASSERT_NE(0, cmp);
// Unquicken the dex file.
for (ClassAccessor accessor : updated_dex_file->GetClasses()) {
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index f425fc9..e131e06 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -54,6 +54,7 @@
namespace art {
static constexpr bool kDebugArgs = false;
+static const char* kDisableCompactDex = "--compact-dex-level=none";
using android::base::StringPrintf;
@@ -613,16 +614,19 @@
TEST_F(Dex2oatVeryLargeTest, DontUseVeryLarge) {
RunTest(CompilerFilter::kAssumeVerified, false, false);
RunTest(CompilerFilter::kExtract, false, false);
+ RunTest(CompilerFilter::kQuicken, false, false);
RunTest(CompilerFilter::kSpeed, false, false);
RunTest(CompilerFilter::kAssumeVerified, false, false, { "--very-large-app-threshold=10000000" });
RunTest(CompilerFilter::kExtract, false, false, { "--very-large-app-threshold=10000000" });
+ RunTest(CompilerFilter::kQuicken, false, false, { "--very-large-app-threshold=10000000" });
RunTest(CompilerFilter::kSpeed, false, false, { "--very-large-app-threshold=10000000" });
}
TEST_F(Dex2oatVeryLargeTest, UseVeryLarge) {
RunTest(CompilerFilter::kAssumeVerified, true, false, { "--very-large-app-threshold=100" });
RunTest(CompilerFilter::kExtract, true, false, { "--very-large-app-threshold=100" });
+ RunTest(CompilerFilter::kQuicken, true, true, { "--very-large-app-threshold=100" });
RunTest(CompilerFilter::kSpeed, true, true, { "--very-large-app-threshold=100" });
}
@@ -869,6 +873,148 @@
RunTestVDex();
}
+class Dex2oatUnquickenTest : public Dex2oatTest {
+ protected:
+ void RunUnquickenMultiDex() {
+ std::string dex_location = GetScratchDir() + "/UnquickenMultiDex.jar";
+ std::string odex_location = GetOdexDir() + "/UnquickenMultiDex.odex";
+ std::string vdex_location = GetOdexDir() + "/UnquickenMultiDex.vdex";
+ Copy(GetTestDexFileName("MultiDex"), dex_location);
+
+ std::unique_ptr<File> vdex_file1(OS::CreateEmptyFile(vdex_location.c_str()));
+ CHECK(vdex_file1 != nullptr) << vdex_location;
+ // Quicken the dex file into a vdex file.
+ {
+ std::string input_vdex = "--input-vdex-fd=-1";
+ std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_file1->Fd());
+ ASSERT_TRUE(GenerateOdexForTest(dex_location,
+ odex_location,
+ CompilerFilter::kQuicken,
+ { input_vdex, output_vdex },
+ /* expect_success= */ true,
+ /* use_fd= */ true));
+ EXPECT_GT(vdex_file1->GetLength(), 0u);
+ }
+ // Get the dex file checksums.
+ std::vector<uint32_t> checksums1;
+ GetDexFileChecksums(dex_location, odex_location, &checksums1);
+ // Unquicken by running the verify compiler filter on the vdex file.
+ {
+ std::string input_vdex = StringPrintf("--input-vdex-fd=%d", vdex_file1->Fd());
+ std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_file1->Fd());
+ ASSERT_TRUE(GenerateOdexForTest(dex_location,
+ odex_location,
+ CompilerFilter::kVerify,
+ { input_vdex, output_vdex, kDisableCompactDex },
+ /* expect_success= */ true,
+ /* use_fd= */ true));
+ }
+ ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file";
+ CheckResult(dex_location, odex_location);
+ // Verify that the checksums did not change.
+ std::vector<uint32_t> checksums2;
+ GetDexFileChecksums(dex_location, odex_location, &checksums2);
+ ASSERT_EQ(checksums1.size(), checksums2.size());
+ for (size_t i = 0; i != checksums1.size(); ++i) {
+ EXPECT_EQ(checksums1[i], checksums2[i]) << i;
+ }
+ ASSERT_TRUE(success_);
+ }
+
+ void RunUnquickenMultiDexCDex() {
+ std::string dex_location = GetScratchDir() + "/UnquickenMultiDex.jar";
+ std::string odex_location = GetOdexDir() + "/UnquickenMultiDex.odex";
+ std::string odex_location2 = GetOdexDir() + "/UnquickenMultiDex2.odex";
+ std::string vdex_location = GetOdexDir() + "/UnquickenMultiDex.vdex";
+ std::string vdex_location2 = GetOdexDir() + "/UnquickenMultiDex2.vdex";
+ Copy(GetTestDexFileName("MultiDex"), dex_location);
+
+ std::unique_ptr<File> vdex_file1(OS::CreateEmptyFile(vdex_location.c_str()));
+ std::unique_ptr<File> vdex_file2(OS::CreateEmptyFile(vdex_location2.c_str()));
+ CHECK(vdex_file1 != nullptr) << vdex_location;
+ CHECK(vdex_file2 != nullptr) << vdex_location2;
+
+ // Quicken the dex file into a vdex file.
+ {
+ std::string input_vdex = "--input-vdex-fd=-1";
+ std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_file1->Fd());
+ ASSERT_TRUE(GenerateOdexForTest(dex_location,
+ odex_location,
+ CompilerFilter::kQuicken,
+ { input_vdex, output_vdex, "--compact-dex-level=fast"},
+ /* expect_success= */ true,
+ /* use_fd= */ true));
+ EXPECT_GT(vdex_file1->GetLength(), 0u);
+ }
+ // Unquicken by running the verify compiler filter on the vdex file.
+ {
+ std::string input_vdex = StringPrintf("--input-vdex-fd=%d", vdex_file1->Fd());
+ std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_file2->Fd());
+ ASSERT_TRUE(GenerateOdexForTest(dex_location,
+ odex_location2,
+ CompilerFilter::kVerify,
+ { input_vdex, output_vdex, "--compact-dex-level=none"},
+ /* expect_success= */ true,
+ /* use_fd= */ true));
+ }
+ ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file";
+ ASSERT_EQ(vdex_file2->FlushCloseOrErase(), 0) << "Could not flush and close vdex file";
+ CheckResult(dex_location, odex_location2);
+ ASSERT_TRUE(success_);
+ }
+
+ void CheckResult(const std::string& dex_location, const std::string& odex_location) {
+ std::string error_msg;
+ std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1,
+ odex_location.c_str(),
+ odex_location.c_str(),
+ /*executable=*/ false,
+ /*low_4gb=*/ false,
+ dex_location,
+ &error_msg));
+ ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
+ ASSERT_GE(odex_file->GetOatDexFiles().size(), 1u);
+
+ // Iterate over the dex files and ensure there is no quickened instruction.
+ for (const OatDexFile* oat_dex_file : odex_file->GetOatDexFiles()) {
+ std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
+ for (ClassAccessor accessor : dex_file->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ for (const DexInstructionPcPair& inst : method.GetInstructions()) {
+ ASSERT_FALSE(inst->IsQuickened()) << inst->Opcode() << " " << output_;
+ }
+ }
+ }
+ }
+ }
+
+ void GetDexFileChecksums(const std::string& dex_location,
+ const std::string& odex_location,
+ /*out*/std::vector<uint32_t>* checksums) {
+ std::string error_msg;
+ std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1,
+ odex_location.c_str(),
+ odex_location.c_str(),
+ /*executable=*/ false,
+ /*low_4gb=*/ false,
+ dex_location,
+ &error_msg));
+ ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
+ ASSERT_GE(odex_file->GetOatDexFiles().size(), 1u);
+ for (const OatDexFile* oat_dex_file : odex_file->GetOatDexFiles()) {
+ checksums->push_back(oat_dex_file->GetDexFileLocationChecksum());
+ }
+ }
+};
+
+TEST_F(Dex2oatUnquickenTest, UnquickenMultiDex) {
+ RunUnquickenMultiDex();
+}
+
+TEST_F(Dex2oatUnquickenTest, UnquickenMultiDexCDex) {
+ RunUnquickenMultiDexCDex();
+}
+
class Dex2oatWatchdogTest : public Dex2oatTest {
protected:
void RunTest(bool expect_success, const std::vector<std::string>& extra_args = {}) {
@@ -966,7 +1112,7 @@
ASSERT_TRUE(GenerateOdexForTest(dex_location,
odex_location,
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
extra_args,
expected_success,
/*use_fd=*/ false,
@@ -1034,7 +1180,7 @@
ASSERT_TRUE(GenerateOdexForTest(stripped_classpath,
odex_for_classpath,
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
{},
true));
@@ -1163,7 +1309,7 @@
const int res = GenerateOdexForTestWithStatus(
GetLibCoreDexFileNames(),
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--force-determinism", "--avoid-storing-invocation"});
ASSERT_EQ(res, 0);
@@ -1180,7 +1326,7 @@
const int res2 = GenerateOdexForTestWithStatus(
GetLibCoreDexFileNames(),
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--force-determinism", "--avoid-storing-invocation", "--compile-individually"});
ASSERT_EQ(res2, 0);
@@ -1265,7 +1411,7 @@
const int res = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
oat_filename,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--profile-file=" + profile_file.GetFilename()});
EXPECT_EQ(res, 0);
@@ -1374,7 +1520,7 @@
const int res = GenerateOdexForTestWithStatus(
{ dex_location },
oat_filename,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--compact-dex-level=fast"});
EXPECT_EQ(res, 0);
@@ -1434,7 +1580,7 @@
const int res_fail = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--abort-on-hard-verifier-error"});
EXPECT_NE(0, res_fail);
@@ -1442,7 +1588,7 @@
const int res_no_fail = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--no-abort-on-hard-verifier-error"});
EXPECT_EQ(0, res_no_fail);
@@ -1457,7 +1603,7 @@
const int res_fail = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--abort-on-soft-verifier-error"});
EXPECT_NE(0, res_fail);
@@ -1465,7 +1611,7 @@
const int res_no_fail = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--no-abort-on-soft-verifier-error"});
EXPECT_EQ(0, res_no_fail);
@@ -1511,7 +1657,7 @@
const std::string base_oat_name = out_dir + "/base.oat";
ASSERT_TRUE(GenerateOdexForTest(dex->GetLocation(),
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
{ },
/*expect_success=*/ true,
/*use_fd=*/ false,
@@ -1528,7 +1674,7 @@
int status = GenerateOdexForTestWithStatus(
{ GetTestDexFileName("MainEmptyUncompressed") },
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{ },
/*use_fd*/ false);
@@ -1544,7 +1690,7 @@
int status = GenerateOdexForTestWithStatus(
{ GetTestDexFileName("MainEmptyUncompressedAligned") },
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{ },
/*use_fd*/ false);
@@ -1683,7 +1829,7 @@
const std::string odex_location = GetOdexDir() + "/output.odex";
ASSERT_TRUE(GenerateOdexForTest(dex_location,
odex_location,
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
{ "--compact-dex-level=fast" },
true));
}
@@ -1697,7 +1843,7 @@
ASSERT_TRUE(GenerateOdexForTest(dex_location,
odex_location,
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
{ "--runtime-arg", "-Xuse-stderr-logger" },
true));
// Look for some random part of dex2oat logging. With the stderr logger this should be captured,
@@ -1843,10 +1989,89 @@
EXPECT_TRUE(found_fast_verify) << "Expected to find " << kFastVerifyString << "\n" << output_;
};
+ // Generate a quickened dex by using the input dm file to verify.
+ generate_and_check(CompilerFilter::Filter::kQuicken);
// Use verify compiler filter to check that FastVerify works for that filter too.
generate_and_check(CompilerFilter::Filter::kVerify);
}
+// Test that dex files with quickened opcodes aren't dequickened.
+TEST_F(Dex2oatTest, QuickenedInput) {
+ std::string error_msg;
+ ScratchFile temp_dex;
+ MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
+ bool mutated_successfully = false;
+ // Change the dex instructions to make an opcode that spans past the end of the code item.
+ for (ClassAccessor accessor : dex->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ CodeItemInstructionAccessor instructions = method.GetInstructions();
+ // Make a quickened instruction that doesn't run past the end of the code item.
+ if (instructions.InsnsSizeInCodeUnits() > 2) {
+ const_cast<Instruction&>(instructions.InstructionAt(0)).SetOpcode(
+ Instruction::IGET_BYTE_QUICK);
+ mutated_successfully = true;
+ }
+ }
+ }
+ CHECK(mutated_successfully)
+ << "Failed to find candidate code item with only one code unit in last instruction.";
+ });
+
+ const std::string& dex_location = temp_dex.GetFilename();
+ std::string odex_location = GetOdexDir() + "/quickened.odex";
+ std::string vdex_location = GetOdexDir() + "/quickened.vdex";
+ std::unique_ptr<File> vdex_output(OS::CreateEmptyFile(vdex_location.c_str()));
+ // Quicken the dex
+ {
+ std::string input_vdex = "--input-vdex-fd=-1";
+ std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_output->Fd());
+ ASSERT_TRUE(GenerateOdexForTest(dex_location,
+ odex_location,
+ CompilerFilter::kQuicken,
+ // Disable cdex since we want to compare against the original
+ // dex file after unquickening.
+ { input_vdex, output_vdex, kDisableCompactDex },
+ /* expect_success= */ true,
+ /* use_fd= */ true));
+ }
+ // Unquicken by running the verify compiler filter on the vdex file and verify it matches.
+ std::string odex_location2 = GetOdexDir() + "/unquickened.odex";
+ std::string vdex_location2 = GetOdexDir() + "/unquickened.vdex";
+ std::unique_ptr<File> vdex_unquickened(OS::CreateEmptyFile(vdex_location2.c_str()));
+ {
+ std::string input_vdex = StringPrintf("--input-vdex-fd=%d", vdex_output->Fd());
+ std::string output_vdex = StringPrintf("--output-vdex-fd=%d", vdex_unquickened->Fd());
+ ASSERT_TRUE(GenerateOdexForTest(dex_location,
+ odex_location2,
+ CompilerFilter::kVerify,
+ // Disable cdex to avoid needing to write out the shared
+ // section.
+ { input_vdex, output_vdex, kDisableCompactDex },
+ /* expect_success= */ true,
+ /* use_fd= */ true));
+ }
+ ASSERT_EQ(vdex_unquickened->Flush(), 0) << "Could not flush and close vdex file";
+ ASSERT_TRUE(success_);
+ {
+ // Check that hte vdex has one dex and compare it to the original one.
+ std::unique_ptr<VdexFile> vdex(VdexFile::Open(vdex_location2.c_str(),
+ /*writable*/ false,
+ /*low_4gb*/ false,
+ /*unquicken*/ false,
+ &error_msg));
+ std::vector<std::unique_ptr<const DexFile>> dex_files;
+ bool result = vdex->OpenAllDexFiles(&dex_files, &error_msg);
+ ASSERT_TRUE(result) << error_msg;
+ ASSERT_EQ(dex_files.size(), 1u) << error_msg;
+ ScratchFile temp;
+ ASSERT_TRUE(temp.GetFile()->WriteFully(dex_files[0]->Begin(), dex_files[0]->Size()));
+ ASSERT_EQ(temp.GetFile()->Flush(), 0) << "Could not flush extracted dex";
+ EXPECT_EQ(temp.GetFile()->Compare(temp_dex.GetFile()), 0);
+ }
+ ASSERT_EQ(vdex_output->FlushCloseOrErase(), 0) << "Could not flush and close";
+ ASSERT_EQ(vdex_unquickened->FlushCloseOrErase(), 0) << "Could not flush and close";
+}
+
// Test that compact dex generation with invalid dex files doesn't crash dex2oat. b/75970654
TEST_F(Dex2oatTest, CompactDexInvalidSource) {
ScratchFile invalid_dex;
@@ -1874,7 +2099,7 @@
int status = GenerateOdexForTestWithStatus(
{dex_location},
odex_location,
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
&error_msg,
{ "--compact-dex-level=fast" });
ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_;
@@ -1913,7 +2138,7 @@
status = GenerateOdexForTestWithStatus(
{ invalid_dex_zip.GetFilename() },
GetOdexDir() + "/output_apk.odex",
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
&error_msg,
{ "--compact-dex-level=fast" });
ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_;
@@ -1921,7 +2146,7 @@
status = GenerateOdexForTestWithStatus(
{ invalid_dex.GetFilename() },
GetOdexDir() + "/output.odex",
- CompilerFilter::kVerify,
+ CompilerFilter::kQuicken,
&error_msg,
{ "--compact-dex-level=fast" });
ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_;
@@ -1969,7 +2194,7 @@
const std::string base_oat_name = out_dir + "/base.oat";
ASSERT_TRUE(GenerateOdexForTest(zip_location,
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
extra_args,
/*expect_success=*/ true,
/*use_fd=*/ false,
@@ -2068,7 +2293,7 @@
};
ASSERT_TRUE(GenerateOdexForTest(dex_location,
base_oat_name,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
extra_args,
/*expect_success=*/ true,
/*use_fd=*/ false,
@@ -2255,7 +2480,7 @@
// The class path should not be valid and should fail being stored.
EXPECT_TRUE(GenerateOdexForTest(GetTestDexFileName("ManyMethods"),
odex_location,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
{ "--class-loader-context=" + stored_context },
/*expect_success=*/ true,
/*use_fd=*/ false,
@@ -2267,7 +2492,7 @@
// The stored context should match what we expect even though it's invalid.
EXPECT_TRUE(GenerateOdexForTest(GetTestDexFileName("ManyMethods"),
odex_location,
- CompilerFilter::Filter::kVerify,
+ CompilerFilter::Filter::kQuicken,
{ "--class-loader-context=" + valid_context,
"--stored-class-loader-context=" + stored_context },
/*expect_success=*/ true,
@@ -2323,7 +2548,7 @@
const int res_fail = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
base_oat_name,
- CompilerFilter::Filter::kSpeed,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--check-linkage-conditions", "--crash-on-linkage-violation"});
EXPECT_NE(0, res_fail);
@@ -2331,7 +2556,7 @@
const int res_no_fail = GenerateOdexForTestWithStatus(
{dex->GetLocation()},
base_oat_name,
- CompilerFilter::Filter::kSpeed,
+ CompilerFilter::Filter::kQuicken,
&error_msg,
{"--check-linkage-conditions"});
EXPECT_EQ(0, res_no_fail);
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index c9f99a4..c08227a 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -355,11 +355,8 @@
if (dex_file.GetContainer() != nullptr && dex_file.GetContainer()->IsReadOnly()) {
return optimizer::DexToDexCompiler::CompilationLevel::kDontDexToDexCompile;
}
- if (!driver.GetCompilerOptions().IsQuickeningCompilationEnabled()) {
- // b/170086509 Quickening compilation is being deprecated.
- return optimizer::DexToDexCompiler::CompilationLevel::kDontDexToDexCompile;
- }
auto* const runtime = Runtime::Current();
+ DCHECK(driver.GetCompilerOptions().IsQuickeningCompilationEnabled());
const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = runtime->GetClassLinker();
ObjPtr<mirror::Class> klass = class_linker->FindClass(self, descriptor, class_loader);
diff --git a/dexoptanalyzer/dexoptanalyzer_test.cc b/dexoptanalyzer/dexoptanalyzer_test.cc
index d8321d6..651fa4a 100644
--- a/dexoptanalyzer/dexoptanalyzer_test.cc
+++ b/dexoptanalyzer/dexoptanalyzer_test.cc
@@ -104,7 +104,7 @@
Verify(dex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kVerify);
+ Verify(dex_location, CompilerFilter::kQuicken);
Verify(dex_location, CompilerFilter::kSpeedProfile);
Verify(dex_location, CompilerFilter::kSpeed, false, false, nullptr);
}
@@ -116,7 +116,7 @@
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kVerify);
+ Verify(dex_location, CompilerFilter::kQuicken);
Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kEverything);
Verify(dex_location, CompilerFilter::kSpeed, false, false, nullptr);
@@ -129,19 +129,19 @@
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
Verify(dex_location, CompilerFilter::kSpeedProfile, false);
- Verify(dex_location, CompilerFilter::kVerify, false);
+ Verify(dex_location, CompilerFilter::kQuicken, false);
Verify(dex_location, CompilerFilter::kSpeedProfile, true);
- Verify(dex_location, CompilerFilter::kVerify, true);
+ Verify(dex_location, CompilerFilter::kQuicken, true);
}
TEST_F(DexoptAnalyzerTest, Downgrade) {
std::string dex_location = GetScratchDir() + "/Downgrade.jar";
Copy(GetDexSrc1(), dex_location);
- GenerateOatForTest(dex_location.c_str(), CompilerFilter::kVerify);
+ GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
Verify(dex_location, CompilerFilter::kSpeedProfile, false, true);
+ Verify(dex_location, CompilerFilter::kQuicken, false, true);
Verify(dex_location, CompilerFilter::kVerify, false, true);
- Verify(dex_location, CompilerFilter::kExtract, false, true);
}
// Case: We have a MultiDEX file and up-to-date OAT file for it.
@@ -195,7 +195,7 @@
/*with_alternate_image=*/true);
Verify(dex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kVerify);
+ Verify(dex_location, CompilerFilter::kQuicken);
Verify(dex_location, CompilerFilter::kSpeed);
}
@@ -212,7 +212,7 @@
/*with_alternate_image=*/true);
Verify(dex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kVerify);
+ Verify(dex_location, CompilerFilter::kQuicken);
}
// Case: We have a DEX file and an ODEX file, but no OAT file.
@@ -272,7 +272,7 @@
Verify(dex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kVerify);
+ Verify(dex_location, CompilerFilter::kQuicken);
}
// Case: We have a DEX file, an ODEX file and an OAT file.
diff --git a/runtime/compiler_filter.cc b/runtime/compiler_filter.cc
index 6291329..9ce2533 100644
--- a/runtime/compiler_filter.cc
+++ b/runtime/compiler_filter.cc
@@ -26,7 +26,8 @@
switch (filter) {
case CompilerFilter::kAssumeVerified:
case CompilerFilter::kExtract:
- case CompilerFilter::kVerify: return false;
+ case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken: return false;
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
@@ -44,6 +45,7 @@
case CompilerFilter::kExtract:
case CompilerFilter::kVerify: return false;
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
case CompilerFilter::kSpeedProfile:
@@ -54,8 +56,21 @@
UNREACHABLE();
}
-bool CompilerFilter::IsQuickeningCompilationEnabled(Filter filter ATTRIBUTE_UNUSED) {
- return false;
+bool CompilerFilter::IsQuickeningCompilationEnabled(Filter filter) {
+ switch (filter) {
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract:
+ case CompilerFilter::kVerify: return false;
+
+ case CompilerFilter::kQuicken:
+ case CompilerFilter::kSpaceProfile:
+ case CompilerFilter::kSpace:
+ case CompilerFilter::kSpeedProfile:
+ case CompilerFilter::kSpeed:
+ case CompilerFilter::kEverythingProfile:
+ case CompilerFilter::kEverything: return true;
+ }
+ UNREACHABLE();
}
bool CompilerFilter::IsAnyCompilationEnabled(Filter filter) {
@@ -70,6 +85,7 @@
case CompilerFilter::kExtract: return false;
case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
case CompilerFilter::kSpeedProfile:
@@ -91,6 +107,7 @@
case CompilerFilter::kAssumeVerified:
case CompilerFilter::kExtract:
case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpace:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverything: return false;
@@ -107,6 +124,7 @@
case CompilerFilter::kAssumeVerified:
case CompilerFilter::kExtract:
case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpace:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverything:
@@ -131,6 +149,7 @@
case CompilerFilter::kAssumeVerified:
case CompilerFilter::kExtract:
case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
return filter;
case CompilerFilter::kSpace:
@@ -139,7 +158,7 @@
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpeedProfile:
case CompilerFilter::kEverythingProfile:
- return CompilerFilter::kVerify;
+ return CompilerFilter::kQuicken;
}
UNREACHABLE();
}
@@ -157,6 +176,7 @@
case CompilerFilter::kAssumeVerified: return "assume-verified";
case CompilerFilter::kExtract: return "extract";
case CompilerFilter::kVerify: return "verify";
+ case CompilerFilter::kQuicken: return "quicken";
case CompilerFilter::kSpaceProfile: return "space-profile";
case CompilerFilter::kSpace: return "space";
case CompilerFilter::kSpeedProfile: return "speed-profile";
@@ -177,7 +197,7 @@
} else if (strcmp(option, "interpret-only") == 0) {
LOG(WARNING) << "'interpret-only' is an obsolete compiler filter name that will be "
<< "removed in future releases, please use 'quicken' instead.";
- *filter = kVerify;
+ *filter = kQuicken;
} else if (strcmp(option, "verify-profile") == 0) {
LOG(WARNING) << "'verify-profile' is an obsolete compiler filter name that will be "
<< "removed in future releases, please use 'verify' instead.";
@@ -201,8 +221,7 @@
} else if (strcmp(option, "verify") == 0) {
*filter = kVerify;
} else if (strcmp(option, "quicken") == 0) {
- // b/170086509 'quicken' becomes an alias to 'verify.
- *filter = kVerify;
+ *filter = kQuicken;
} else if (strcmp(option, "space") == 0) {
*filter = kSpace;
} else if (strcmp(option, "space-profile") == 0) {
diff --git a/runtime/compiler_filter.h b/runtime/compiler_filter.h
index 0b930a4..a016683 100644
--- a/runtime/compiler_filter.h
+++ b/runtime/compiler_filter.h
@@ -33,6 +33,7 @@
kAssumeVerified, // Skip verification but mark all classes as verified anyway.
kExtract, // Delay verication to runtime, do not compile anything.
kVerify, // Only verify classes.
+ kQuicken, // Verify, quicken, and compile JNI stubs.
kSpaceProfile, // Maximize space savings based on profile.
kSpace, // Maximize space savings.
kSpeedProfile, // Maximize runtime performance based on profile.
diff --git a/runtime/compiler_filter_test.cc b/runtime/compiler_filter_test.cc
index df7c8e7..9b4f845 100644
--- a/runtime/compiler_filter_test.cc
+++ b/runtime/compiler_filter_test.cc
@@ -43,6 +43,7 @@
TestCompilerFilterName(CompilerFilter::kAssumeVerified, "assume-verified");
TestCompilerFilterName(CompilerFilter::kExtract, "extract");
TestCompilerFilterName(CompilerFilter::kVerify, "verify");
+ TestCompilerFilterName(CompilerFilter::kQuicken, "quicken");
TestCompilerFilterName(CompilerFilter::kSpaceProfile, "space-profile");
TestCompilerFilterName(CompilerFilter::kSpace, "space");
TestCompilerFilterName(CompilerFilter::kSpeedProfile, "speed-profile");
@@ -57,12 +58,13 @@
TestSafeModeFilter(CompilerFilter::kAssumeVerified, "assume-verified");
TestSafeModeFilter(CompilerFilter::kExtract, "extract");
TestSafeModeFilter(CompilerFilter::kVerify, "verify");
- TestSafeModeFilter(CompilerFilter::kVerify, "space-profile");
- TestSafeModeFilter(CompilerFilter::kVerify, "space");
- TestSafeModeFilter(CompilerFilter::kVerify, "speed-profile");
- TestSafeModeFilter(CompilerFilter::kVerify, "speed");
- TestSafeModeFilter(CompilerFilter::kVerify, "everything-profile");
- TestSafeModeFilter(CompilerFilter::kVerify, "everything");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "quicken");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "space-profile");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "space");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "speed-profile");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "speed");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "everything-profile");
+ TestSafeModeFilter(CompilerFilter::kQuicken, "everything");
}
} // namespace art
diff --git a/runtime/oat.h b/runtime/oat.h
index f43aa11..0fbb09a 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,8 +32,8 @@
class PACKED(4) OatHeader {
public:
static constexpr std::array<uint8_t, 4> kOatMagic { { 'o', 'a', 't', '\n' } };
- // Last oat version changed reason: Deprecation of 'quicken'.
- static constexpr std::array<uint8_t, 4> kOatVersion { { '1', '8', '8', '\0' } };
+ // Last oat version changed reason: Changes of ABI for conflict trampoline.
+ static constexpr std::array<uint8_t, 4> kOatVersion { { '1', '8', '7', '\0' } };
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
static constexpr const char* kDebuggableKey = "debuggable";
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 223b6f4..92347b1 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -233,7 +233,7 @@
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeedProfile));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
@@ -278,7 +278,7 @@
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
@@ -310,7 +310,7 @@
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
@@ -345,7 +345,7 @@
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
@@ -379,7 +379,7 @@
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
@@ -420,7 +420,7 @@
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
@@ -617,11 +617,11 @@
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeedProfile, false));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify, false));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken, false));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeedProfile, true));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify, true));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken, true));
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -776,7 +776,7 @@
EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -811,7 +811,7 @@
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -861,7 +861,7 @@
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
+ GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kQuicken));
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -972,7 +972,7 @@
std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
Copy(GetDexSrc1(), dex_location);
- GenerateOatForTest(dex_location.c_str(), CompilerFilter::kVerify);
+ GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
diff --git a/runtime/oat_file_test.cc b/runtime/oat_file_test.cc
index f332357..8222a8aa 100644
--- a/runtime/oat_file_test.cc
+++ b/runtime/oat_file_test.cc
@@ -57,7 +57,7 @@
std::string dex_location = GetScratchDir() + "/MultiDexUncompressedAligned.jar";
Copy(GetTestDexFileName("MultiDexUncompressedAligned"), dex_location);
- GenerateOatForTest(dex_location.c_str(), CompilerFilter::kVerify);
+ GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
std::string oat_location;
std::string error_msg;