summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.oat.mk8
-rw-r--r--compiler/Android.bp1
-rw-r--r--compiler/dex/dex_to_dex_decompiler_test.cc4
-rw-r--r--compiler/dex/verification_results.cc7
-rw-r--r--compiler/driver/compiler_driver.cc82
-rw-r--r--compiler/driver/compiler_driver_test.cc2
-rw-r--r--compiler/driver/compiler_options.h22
-rw-r--r--compiler/oat_test.cc2
-rw-r--r--compiler/oat_writer.cc31
-rw-r--r--compiler/optimizing/graph_checker.cc3
-rw-r--r--dex2oat/dex2oat.cc56
-rw-r--r--dex2oat/dex2oat_test.cc32
-rw-r--r--dexlayout/dexdiag.cc1
-rw-r--r--dexoptanalyzer/dexoptanalyzer_test.cc36
-rw-r--r--runtime/Android.bp1
-rw-r--r--runtime/arch/context-inl.h55
-rw-r--r--runtime/arch/context.cc35
-rw-r--r--runtime/base/stl_util.h11
-rw-r--r--runtime/compiler_filter.cc123
-rw-r--r--runtime/compiler_filter.h18
-rw-r--r--runtime/compiler_filter_test.cc10
-rw-r--r--runtime/debugger.cc17
-rw-r--r--runtime/debugger.h3
-rw-r--r--runtime/dex_file_annotations.cc34
-rw-r--r--runtime/dex_file_annotations.h2
-rw-r--r--runtime/dex_to_dex_decompiler.cc (renamed from compiler/dex/dex_to_dex_decompiler.cc)0
-rw-r--r--runtime/dex_to_dex_decompiler.h (renamed from compiler/dex/dex_to_dex_decompiler.h)6
-rw-r--r--runtime/dexopt_test.cc2
-rw-r--r--runtime/jdwp/jdwp_handler.cc15
-rw-r--r--runtime/native/dalvik_system_ZygoteHooks.cc4
-rw-r--r--runtime/oat_file.cc2
-rw-r--r--runtime/oat_file_assistant.cc5
-rw-r--r--runtime/oat_file_assistant_test.cc48
-rw-r--r--runtime/openjdkjvmti/fixed_up_dex_file.cc4
-rw-r--r--runtime/runtime.cc3
-rw-r--r--runtime/thread.cc6
-rw-r--r--runtime/vdex_file.cc91
-rw-r--r--runtime/vdex_file.h12
-rw-r--r--runtime/vdex_file_test.cc4
-rw-r--r--runtime/verifier/method_verifier.cc2
-rw-r--r--test/117-nopatchoat/nopatchoat.cc2
-rwxr-xr-xtest/157-void-class/run4
-rw-r--r--test/595-profile-saving/run6
-rw-r--r--test/628-vdex/run2
-rw-r--r--test/634-vdex-duplicate/run2
-rwxr-xr-xtest/648-many-direct-methods/build25
-rw-r--r--test/648-many-direct-methods/expected.txt1
-rw-r--r--test/648-many-direct-methods/info.txt2
-rwxr-xr-xtest/648-many-direct-methods/util-src/generate_java.py137
-rwxr-xr-xtest/etc/run-test-jar22
-rw-r--r--test/knownfailures.json14
-rw-r--r--tools/art18
-rw-r--r--tools/dexfuzz/src/dexfuzz/executors/Executor.java2
-rwxr-xr-xtools/run-jdwp-tests.sh4
-rwxr-xr-xtools/run-libcore-tests.sh2
55 files changed, 508 insertions, 535 deletions
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index c733febd06..3f9ea15fb3 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -56,11 +56,11 @@ define create-core-oat-host-rules
core_dex2oat_dependency := $(DEX2OAT)
endif
ifeq ($(1),interpreter)
- core_compile_options += --compiler-filter=interpret-only
+ core_compile_options += --compiler-filter=quicken
core_infix := -interpreter
endif
ifeq ($(1),interp-ac)
- core_compile_options += --compiler-filter=verify-at-runtime --runtime-arg -Xverify:softfail
+ core_compile_options += --compiler-filter=extract --runtime-arg -Xverify:softfail
core_infix := -interp-ac
endif
ifneq ($(filter-out interpreter interp-ac optimizing,$(1)),)
@@ -166,11 +166,11 @@ define create-core-oat-target-rules
core_dex2oat_dependency := $(DEX2OAT)
endif
ifeq ($(1),interpreter)
- core_compile_options += --compiler-filter=interpret-only
+ core_compile_options += --compiler-filter=quicken
core_infix := -interpreter
endif
ifeq ($(1),interp-ac)
- core_compile_options += --compiler-filter=verify-at-runtime --runtime-arg -Xverify:softfail
+ core_compile_options += --compiler-filter=extract --runtime-arg -Xverify:softfail
core_infix := -interp-ac
endif
ifneq ($(filter-out interpreter interp-ac optimizing,$(1)),)
diff --git a/compiler/Android.bp b/compiler/Android.bp
index dec8b577d8..6ef866a3c6 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -28,7 +28,6 @@ art_cc_defaults {
"compiled_method.cc",
"debug/elf_debug_writer.cc",
"dex/dex_to_dex_compiler.cc",
- "dex/dex_to_dex_decompiler.cc",
"dex/inline_method_analyser.cc",
"dex/verified_method.cc",
"dex/verification_results.cc",
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index 9a8d27cd03..e486e2e6ec 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "dex/dex_to_dex_decompiler.h"
+#include "dex_to_dex_decompiler.h"
#include "class_linker.h"
#include "compiler/common_compiler_test.h"
@@ -38,7 +38,7 @@ class DexToDexDecompilerTest : public CommonCompilerTest {
TimingLogger timings("CompilerDriverTest::CompileAll", false, false);
TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
compiler_options_->boot_image_ = false;
- compiler_options_->SetCompilerFilter(CompilerFilter::kInterpretOnly);
+ compiler_options_->SetCompilerFilter(CompilerFilter::kQuicken);
compiler_driver_->CompileAll(class_loader,
GetDexFiles(class_loader),
/* verifier_deps */ nullptr,
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc
index 00a7d44bac..3f0df3b2c8 100644
--- a/compiler/dex/verification_results.cc
+++ b/compiler/dex/verification_results.cc
@@ -104,11 +104,12 @@ void VerificationResults::CreateVerifiedMethodFor(MethodReference ref) {
// This method should only be called for classes verified at compile time,
// which have no verifier error, nor has methods that we know will throw
// at runtime.
- AtomicMap::InsertResult result = atomic_verified_methods_.Insert(
+ atomic_verified_methods_.Insert(
ref,
/*expected*/ nullptr,
new VerifiedMethod(/* encountered_error_types */ 0, /* has_runtime_throw */ false));
- DCHECK_EQ(result, AtomicMap::kInsertResultSuccess);
+ // We don't check the result of `Insert` as we could insert twice for the same
+ // MethodReference in the presence of duplicate methods.
}
void VerificationResults::AddRejectedClass(ClassReference ref) {
@@ -126,7 +127,7 @@ bool VerificationResults::IsClassRejected(ClassReference ref) {
bool VerificationResults::IsCandidateForCompilation(MethodReference&,
const uint32_t access_flags) {
- if (!compiler_options_->IsBytecodeCompilationEnabled()) {
+ if (!compiler_options_->IsAotCompilationEnabled()) {
return false;
}
// Don't compile class initializers unless kEverything.
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index f77b3ddfe0..fbfa087cfd 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -45,7 +45,6 @@
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
#include "dex/dex_to_dex_compiler.h"
-#include "dex/dex_to_dex_decompiler.h"
#include "dex/verification_results.h"
#include "dex/verified_method.h"
#include "driver/compiler_options.h"
@@ -421,7 +420,7 @@ INTRINSICS_LIST(SETUP_INTRINSICS)
// Compile:
// 1) Compile all classes and methods enabled for compilation. May fall back to dex-to-dex
// compilation.
- if (GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ if (GetCompilerOptions().IsAnyCompilationEnabled()) {
Compile(class_loader, dex_files, timings);
}
if (dump_stats_) {
@@ -431,61 +430,6 @@ INTRINSICS_LIST(SETUP_INTRINSICS)
FreeThreadPools();
}
-// In-place unquicken the given `dex_files` based on `quickening_info`.
-static void Unquicken(const std::vector<const DexFile*>& dex_files,
- const ArrayRef<const uint8_t>& quickening_info,
- bool decompile_return_instruction) {
- 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) {
- for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
- const uint8_t* class_data = dex_file->GetClassData(class_def);
- if (class_data == nullptr) {
- continue;
- }
- ClassDataItemIterator it(*dex_file, class_data);
- // Skip fields
- while (it.HasNextStaticField()) {
- it.Next();
- }
- while (it.HasNextInstanceField()) {
- it.Next();
- }
-
- while (it.HasNextDirectMethod()) {
- const DexFile::CodeItem* code_item = it.GetMethodCodeItem();
- if (code_item != nullptr) {
- uint32_t quickening_size = *reinterpret_cast<const uint32_t*>(quickening_info_ptr);
- quickening_info_ptr += sizeof(uint32_t);
- optimizer::ArtDecompileDEX(*code_item,
- ArrayRef<const uint8_t>(quickening_info_ptr, quickening_size),
- decompile_return_instruction);
- quickening_info_ptr += quickening_size;
- }
- it.Next();
- }
-
- while (it.HasNextVirtualMethod()) {
- const DexFile::CodeItem* code_item = it.GetMethodCodeItem();
- if (code_item != nullptr) {
- uint32_t quickening_size = *reinterpret_cast<const uint32_t*>(quickening_info_ptr);
- quickening_info_ptr += sizeof(uint32_t);
- optimizer::ArtDecompileDEX(*code_item,
- ArrayRef<const uint8_t>(quickening_info_ptr, quickening_size),
- decompile_return_instruction);
- quickening_info_ptr += quickening_size;
- }
- it.Next();
- }
- DCHECK(!it.HasNext());
- }
- }
- if (quickening_info_ptr != quickening_info_end) {
- LOG(FATAL) << "Failed to use all quickening info";
- }
-}
-
void CompilerDriver::CompileAll(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
VdexFile* vdex_file,
@@ -494,15 +438,12 @@ void CompilerDriver::CompileAll(jobject class_loader,
// TODO: we unquicken unconditionnally, as we don't know
// if the boot image has changed. How exactly we'll know is under
// experimentation.
- if (vdex_file->GetQuickeningInfo().size() != 0) {
- 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).
- Unquicken(dex_files,
- vdex_file->GetQuickeningInfo(),
- /* decompile_return_instruction */ false);
- }
+ 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()));
}
@@ -514,7 +455,7 @@ static optimizer::DexToDexCompilationLevel GetDexToDexCompilationLevel(
const DexFile& dex_file, const DexFile::ClassDef& class_def)
REQUIRES_SHARED(Locks::mutator_lock_) {
auto* const runtime = Runtime::Current();
- DCHECK(driver.GetCompilerOptions().IsAnyMethodCompilationEnabled());
+ DCHECK(driver.GetCompilerOptions().IsQuickeningCompilationEnabled());
const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = runtime->GetClassLinker();
mirror::Class* klass = class_linker->FindClass(self, descriptor, class_loader);
@@ -986,7 +927,8 @@ void CompilerDriver::PreCompile(jobject class_loader,
LoadImageClasses(timings);
VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString(false);
- if (compiler_options_->IsAnyMethodCompilationEnabled()) {
+ if (compiler_options_->IsAnyCompilationEnabled()) {
+ // Resolve eagerly to prepare for compilation.
Resolve(class_loader, dex_files, timings);
VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
}
@@ -1014,7 +956,7 @@ void CompilerDriver::PreCompile(jobject class_loader,
<< "situations. Please check the log.";
}
- if (compiler_options_->IsAnyMethodCompilationEnabled()) {
+ if (compiler_options_->IsAnyCompilationEnabled()) {
if (kIsDebugBuild) {
EnsureVerifiedOrVerifyAtRuntime(class_loader, dex_files);
}
@@ -2017,7 +1959,7 @@ bool CompilerDriver::FastVerify(jobject jclass_loader,
return false;
}
- bool compiler_only_verifies = !GetCompilerOptions().IsAnyMethodCompilationEnabled();
+ bool compiler_only_verifies = !GetCompilerOptions().IsAnyCompilationEnabled();
// We successfully validated the dependencies, now update class status
// of verified classes. Note that the dependencies also record which classes
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 42ff1e748a..17854fd61a 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -325,7 +325,7 @@ TEST_F(CompilerDriverProfileTest, ProfileGuidedCompilation) {
class CompilerDriverVerifyTest : public CompilerDriverTest {
protected:
CompilerFilter::Filter GetCompilerFilter() const OVERRIDE {
- return CompilerFilter::kVerifyProfile;
+ return CompilerFilter::kVerify;
}
void CheckVerifiedClass(jobject class_loader, const std::string& clazz) const {
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 2376fbf5f5..957ea99c49 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -84,32 +84,32 @@ class CompilerOptions FINAL {
compiler_filter_ = compiler_filter;
}
- bool VerifyAtRuntime() const {
- return compiler_filter_ == CompilerFilter::kVerifyAtRuntime;
- }
-
- bool IsBytecodeCompilationEnabled() const {
- return CompilerFilter::IsBytecodeCompilationEnabled(compiler_filter_);
+ bool IsAotCompilationEnabled() const {
+ return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
}
bool IsJniCompilationEnabled() const {
return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
}
+ bool IsQuickeningCompilationEnabled() const {
+ return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
+ }
+
bool IsVerificationEnabled() const {
return CompilerFilter::IsVerificationEnabled(compiler_filter_);
}
bool AssumeClassesAreVerified() const {
- return compiler_filter_ == CompilerFilter::kVerifyNone;
+ return compiler_filter_ == CompilerFilter::kAssumeVerified;
}
- bool VerifyOnlyProfile() const {
- return compiler_filter_ == CompilerFilter::kVerifyProfile;
+ bool VerifyAtRuntime() const {
+ return compiler_filter_ == CompilerFilter::kExtract;
}
- bool IsAnyMethodCompilationEnabled() const {
- return CompilerFilter::IsAnyMethodCompilationEnabled(compiler_filter_);
+ bool IsAnyCompilationEnabled() const {
+ return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
}
size_t GetHugeMethodThreshold() const {
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index ead41240c2..1578c0cd3e 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -519,7 +519,7 @@ TEST_F(OatTest, EmptyTextSection) {
if (insn_set == kArm) insn_set = kThumb2;
std::string error_msg;
std::vector<std::string> compiler_options;
- compiler_options.push_back("--compiler-filter=verify-at-runtime");
+ compiler_options.push_back("--compiler-filter=extract");
SetupCompiler(compiler_kind, insn_set, compiler_options, /*out*/ &error_msg);
jobject class_loader;
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index af60def11e..6b5387ae19 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -1675,7 +1675,7 @@ bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) {
if (UNLIKELY(!visitor->StartClass(dex_file, class_def_index))) {
return false;
}
- if (compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ if (compiler_driver_->GetCompilerOptions().IsAnyCompilationEnabled()) {
const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
const uint8_t* class_data = dex_file->GetClassData(class_def);
if (class_data != nullptr) { // ie not an empty class, such as a marker interface
@@ -1757,7 +1757,7 @@ size_t OatWriter::InitOatClasses(size_t offset) {
}
size_t OatWriter::InitOatMaps(size_t offset) {
- if (!compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ if (!compiler_driver_->GetCompilerOptions().IsAnyCompilationEnabled()) {
return offset;
}
{
@@ -1813,7 +1813,7 @@ size_t OatWriter::InitOatCode(size_t offset) {
}
size_t OatWriter::InitOatCodeDexFiles(size_t offset) {
- if (!compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ if (!compiler_driver_->GetCompilerOptions().IsAnyCompilationEnabled()) {
return offset;
}
InitCodeMethodVisitor code_visitor(this, offset, vdex_quickening_info_offset_);
@@ -1982,7 +1982,7 @@ bool OatWriter::WriteQuickeningInfo(OutputStream* vdex_out) {
return false;
}
- if (compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ if (compiler_driver_->GetCompilerOptions().IsAnyCompilationEnabled()) {
WriteQuickeningInfoMethodVisitor visitor(this, vdex_out, start_offset);
if (!VisitDexMethods(&visitor)) {
PLOG(ERROR) << "Failed to write the vdex quickening info. File: " << vdex_out->GetLocation();
@@ -2474,11 +2474,28 @@ bool OatWriter::LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_fil
/* verify */ true,
/* verify_checksum */ true,
&error_msg);
- } else {
- CHECK(oat_dex_file->source_.IsRawFile())
- << static_cast<size_t>(oat_dex_file->source_.GetType());
+ } else if (oat_dex_file->source_.IsRawFile()) {
File* raw_file = oat_dex_file->source_.GetRawFile();
dex_file = DexFile::OpenDex(raw_file->Fd(), location, /* verify_checksum */ true, &error_msg);
+ } else {
+ // The source data is a vdex file.
+ CHECK(oat_dex_file->source_.IsRawData())
+ << static_cast<size_t>(oat_dex_file->source_.GetType());
+ const uint8_t* raw_dex_file = oat_dex_file->source_.GetRawData();
+ // Note: The raw data has already been checked to contain the header
+ // and all the data that the header specifies as the file size.
+ DCHECK(raw_dex_file != nullptr);
+ DCHECK(ValidateDexFileHeader(raw_dex_file, oat_dex_file->GetLocation()));
+ const UnalignedDexFileHeader* header = AsUnalignedDexFileHeader(raw_dex_file);
+ // Since the source may have had its layout changed, or may be quickened, don't verify it.
+ dex_file = DexFile::Open(raw_dex_file,
+ header->file_size_,
+ location,
+ oat_dex_file->dex_file_location_checksum_,
+ nullptr,
+ /* verify */ false,
+ /* verify_checksum */ false,
+ &error_msg);
}
if (dex_file == nullptr) {
LOG(ERROR) << "Failed to open dex file for layout: " << error_msg;
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 34b52a87b5..12340b416d 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -497,8 +497,7 @@ void GraphChecker::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
"has a null pointer as last input.",
invoke->DebugName(),
invoke->GetId()));
- }
- if (!last_input->IsClinitCheck() && !last_input->IsLoadClass()) {
+ } else if (!last_input->IsClinitCheck() && !last_input->IsLoadClass()) {
AddError(StringPrintf("Static invoke %s:%d marked as having an explicit clinit check "
"has a last instruction (%s:%d) which is neither a clinit check "
"nor a load class instruction.",
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 5090c1192a..4cba36aef6 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -268,20 +268,17 @@ NO_RETURN static void Usage(const char* fmt, ...) {
UsageError(" Default: Optimizing");
UsageError("");
UsageError(" --compiler-filter="
- "(verify-none"
- "|verify-at-runtime"
- "|verify-profile"
- "|interpret-only"
- "|time"
+ "(assume-verified"
+ "|extract"
+ "|verify"
+ "|quicken"
"|space-profile"
"|space"
- "|balanced"
"|speed-profile"
"|speed"
"|everything-profile"
"|everything):");
UsageError(" select compiler filter.");
- UsageError(" verify-profile requires a --profile(-fd) to also be passed in.");
UsageError(" Example: --compiler-filter=everything");
UsageError(" Default: speed");
UsageError("");
@@ -721,6 +718,10 @@ class Dex2Oat FINAL {
Usage("Can't have both --input-vdex-fd and --input-vdex");
}
+ if (output_vdex_fd_ != -1 && !output_vdex_.empty()) {
+ Usage("Can't have both --output-vdex-fd and --output-vdex");
+ }
+
if (!oat_filenames_.empty() && oat_fd_ != -1) {
Usage("--oat-file should not be used with --oat-fd");
}
@@ -1125,6 +1126,8 @@ class Dex2Oat FINAL {
ParseInputVdexFd(option);
} else if (option.starts_with("--input-vdex=")) {
input_vdex_ = option.substr(strlen("--input-vdex=")).data();
+ } else if (option.starts_with("--output-vdex=")) {
+ output_vdex_ = option.substr(strlen("--output-vdex=")).data();
} else if (option.starts_with("--output-vdex-fd=")) {
ParseOutputVdexFd(option);
} else if (option.starts_with("--oat-file=")) {
@@ -1260,6 +1263,7 @@ class Dex2Oat FINAL {
}
// OAT and VDEX file handling
+ bool eagerly_unquicken_vdex = DoDexLayoutOptimizations();
if (oat_fd_ == -1) {
DCHECK(!oat_filenames_.empty());
@@ -1281,12 +1285,15 @@ class Dex2Oat FINAL {
input_vdex_file_ = VdexFile::Open(input_vdex_,
/* writable */ false,
/* low_4gb */ false,
+ eagerly_unquicken_vdex,
&error_msg);
}
DCHECK_EQ(output_vdex_fd_, -1);
- std::string vdex_filename = ReplaceFileExtension(oat_filename, "vdex");
- if (vdex_filename == input_vdex_) {
+ std::string vdex_filename = output_vdex_.empty()
+ ? ReplaceFileExtension(oat_filename, "vdex")
+ : output_vdex_;
+ if (vdex_filename == input_vdex_ && output_vdex_.empty()) {
update_input_vdex_ = true;
std::unique_ptr<File> vdex_file(OS::OpenFileReadWrite(vdex_filename.c_str()));
vdex_files_.push_back(std::move(vdex_file));
@@ -1328,6 +1335,7 @@ class Dex2Oat FINAL {
"vdex",
/* writable */ false,
/* low_4gb */ false,
+ eagerly_unquicken_vdex,
&error_msg);
// If there's any problem with the passed vdex, just warn and proceed
// without it.
@@ -1570,14 +1578,14 @@ class Dex2Oat FINAL {
// If we need to downgrade the compiler-filter for size reasons, do that check now.
if (!IsBootImage() && IsVeryLarge(dex_files_)) {
- if (!CompilerFilter::IsAsGoodAs(CompilerFilter::kVerifyAtRuntime,
+ if (!CompilerFilter::IsAsGoodAs(CompilerFilter::kExtract,
compiler_options_->GetCompilerFilter())) {
- LOG(INFO) << "Very large app, downgrading to verify-at-runtime.";
+ LOG(INFO) << "Very large app, downgrading to extract.";
// Note: this change won't be reflected in the key-value store, as that had to be
// finalized before loading the dex files. This setup is currently required
// to get the size from the DexFile objects.
// TODO: refactor. b/29790079
- compiler_options_->SetCompilerFilter(CompilerFilter::kVerifyAtRuntime);
+ compiler_options_->SetCompilerFilter(CompilerFilter::kExtract);
}
}
@@ -2085,17 +2093,13 @@ class Dex2Oat FINAL {
}
bool DoProfileGuidedOptimizations() const {
- return UseProfile() && compiler_options_->GetCompilerFilter() != CompilerFilter::kVerifyProfile;
+ return UseProfile();
}
bool DoDexLayoutOptimizations() const {
return DoProfileGuidedOptimizations();
}
- bool HasInputVdexFile() const {
- return input_vdex_file_ != nullptr || input_vdex_fd_ != -1 || !input_vdex_.empty();
- }
-
bool LoadProfile() {
DCHECK(UseProfile());
@@ -2151,16 +2155,6 @@ class Dex2Oat FINAL {
return dex_files_size >= very_large_threshold_;
}
- template <typename T>
- static std::vector<T*> MakeNonOwningPointerVector(const std::vector<std::unique_ptr<T>>& src) {
- std::vector<T*> result;
- result.reserve(src.size());
- for (const std::unique_ptr<T>& t : src) {
- result.push_back(t.get());
- }
- return result;
- }
-
std::vector<std::string> GetClassPathLocations(const std::string& class_path) {
// This function is used only for apps and for an app we have exactly one oat file.
DCHECK(!IsBootImage());
@@ -2693,6 +2687,7 @@ class Dex2Oat FINAL {
int input_vdex_fd_;
int output_vdex_fd_;
std::string input_vdex_;
+ std::string output_vdex_;
std::unique_ptr<VdexFile> input_vdex_file_;
std::vector<const char*> dex_filenames_;
std::vector<const char*> dex_locations_;
@@ -2899,13 +2894,6 @@ static dex2oat::ReturnCode Dex2oat(int argc, char** argv) {
}
}
- if (dex2oat->DoDexLayoutOptimizations()) {
- if (dex2oat->HasInputVdexFile()) {
- LOG(ERROR) << "Dexlayout is incompatible with an input VDEX";
- return dex2oat::ReturnCode::kOther;
- }
- }
-
art::MemMap::Init(); // For ZipEntry::ExtractToMemMap, and vdex.
// Check early that the result of compilation can be written
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 8c14b50094..a267766456 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -161,7 +161,7 @@ class Dex2oatTest : public Dex2oatEnvironmentTest {
runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
if (!runtime->IsVerificationEnabled()) {
- argv.push_back("--compiler-filter=verify-none");
+ argv.push_back("--compiler-filter=assume-verified");
}
if (runtime->MustRelocateIfPossible()) {
@@ -514,7 +514,7 @@ class Dex2oatVeryLargeTest : public Dex2oatTest {
}
// If the input filter was "below," it should have been used.
- if (!CompilerFilter::IsAsGoodAs(CompilerFilter::kVerifyAtRuntime, filter)) {
+ if (!CompilerFilter::IsAsGoodAs(CompilerFilter::kExtract, filter)) {
EXPECT_EQ(odex_file->GetCompilerFilter(), filter);
}
} else {
@@ -536,11 +536,11 @@ class Dex2oatVeryLargeTest : public Dex2oatTest {
void CheckHostResult(bool expect_large) {
if (!kIsTargetBuild) {
if (expect_large) {
- EXPECT_NE(output_.find("Very large app, downgrading to verify-at-runtime."),
+ EXPECT_NE(output_.find("Very large app, downgrading to extract."),
std::string::npos)
<< output_;
} else {
- EXPECT_EQ(output_.find("Very large app, downgrading to verify-at-runtime."),
+ EXPECT_EQ(output_.find("Very large app, downgrading to extract."),
std::string::npos)
<< output_;
}
@@ -567,21 +567,21 @@ class Dex2oatVeryLargeTest : public Dex2oatTest {
};
TEST_F(Dex2oatVeryLargeTest, DontUseVeryLarge) {
- RunTest(CompilerFilter::kVerifyNone, false);
- RunTest(CompilerFilter::kVerifyAtRuntime, false);
- RunTest(CompilerFilter::kInterpretOnly, false);
+ RunTest(CompilerFilter::kAssumeVerified, false);
+ RunTest(CompilerFilter::kExtract, false);
+ RunTest(CompilerFilter::kQuicken, false);
RunTest(CompilerFilter::kSpeed, false);
- RunTest(CompilerFilter::kVerifyNone, false, { "--very-large-app-threshold=1000000" });
- RunTest(CompilerFilter::kVerifyAtRuntime, false, { "--very-large-app-threshold=1000000" });
- RunTest(CompilerFilter::kInterpretOnly, false, { "--very-large-app-threshold=1000000" });
+ RunTest(CompilerFilter::kAssumeVerified, false, { "--very-large-app-threshold=1000000" });
+ RunTest(CompilerFilter::kExtract, false, { "--very-large-app-threshold=1000000" });
+ RunTest(CompilerFilter::kQuicken, false, { "--very-large-app-threshold=1000000" });
RunTest(CompilerFilter::kSpeed, false, { "--very-large-app-threshold=1000000" });
}
TEST_F(Dex2oatVeryLargeTest, UseVeryLarge) {
- RunTest(CompilerFilter::kVerifyNone, false, { "--very-large-app-threshold=100" });
- RunTest(CompilerFilter::kVerifyAtRuntime, false, { "--very-large-app-threshold=100" });
- RunTest(CompilerFilter::kInterpretOnly, true, { "--very-large-app-threshold=100" });
+ RunTest(CompilerFilter::kAssumeVerified, false, { "--very-large-app-threshold=100" });
+ RunTest(CompilerFilter::kExtract, false, { "--very-large-app-threshold=100" });
+ RunTest(CompilerFilter::kQuicken, true, { "--very-large-app-threshold=100" });
RunTest(CompilerFilter::kSpeed, true, { "--very-large-app-threshold=100" });
}
@@ -736,12 +736,12 @@ class Dex2oatLayoutTest : public Dex2oatTest {
/* use_fd */ true,
/* num_profile_classes */ 1,
{ input_vdex, output_vdex },
- /* expect_success */ false);
- EXPECT_EQ(vdex_file2.GetFile()->GetLength(), 0u);
+ /* expect_success */ true);
+ EXPECT_GT(vdex_file2.GetFile()->GetLength(), 0u);
}
ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file";
CheckValidity();
- ASSERT_FALSE(success_);
+ ASSERT_TRUE(success_);
}
void CheckResult(const std::string& dex_location,
diff --git a/dexlayout/dexdiag.cc b/dexlayout/dexdiag.cc
index 688201b6b8..ea2679a1e3 100644
--- a/dexlayout/dexdiag.cc
+++ b/dexlayout/dexdiag.cc
@@ -313,6 +313,7 @@ static bool DisplayMappingIfFromVdexFile(pm_map_t* map, Printer* printer) {
std::unique_ptr<VdexFile> vdex(VdexFile::Open(vdex_name,
false /*writeable*/,
false /*low_4gb*/,
+ false /*unquicken */,
&error_msg /*out*/));
if (vdex == nullptr) {
std::cerr << "Could not open vdex file "
diff --git a/dexoptanalyzer/dexoptanalyzer_test.cc b/dexoptanalyzer/dexoptanalyzer_test.cc
index 57d3f1f68b..1703ff4cbc 100644
--- a/dexoptanalyzer/dexoptanalyzer_test.cc
+++ b/dexoptanalyzer/dexoptanalyzer_test.cc
@@ -89,8 +89,8 @@ TEST_F(DexoptAnalyzerTest, DexNoOat) {
Copy(GetDexSrc1(), dex_location);
Verify(dex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
- Verify(dex_location, CompilerFilter::kInterpretOnly);
+ Verify(dex_location, CompilerFilter::kExtract);
+ Verify(dex_location, CompilerFilter::kQuicken);
Verify(dex_location, CompilerFilter::kSpeedProfile);
}
@@ -101,8 +101,8 @@ TEST_F(DexoptAnalyzerTest, OatUpToDate) {
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kInterpretOnly);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
+ Verify(dex_location, CompilerFilter::kQuicken);
+ Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kEverything);
}
@@ -113,9 +113,9 @@ TEST_F(DexoptAnalyzerTest, ProfileOatUpToDate) {
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
Verify(dex_location, CompilerFilter::kSpeedProfile, false);
- Verify(dex_location, CompilerFilter::kInterpretOnly, false);
+ Verify(dex_location, CompilerFilter::kQuicken, false);
Verify(dex_location, CompilerFilter::kSpeedProfile, true);
- Verify(dex_location, CompilerFilter::kInterpretOnly, true);
+ Verify(dex_location, CompilerFilter::kQuicken, true);
}
// Case: We have a MultiDEX file and up-to-date OAT file for it.
@@ -154,7 +154,7 @@ TEST_F(DexoptAnalyzerTest, OatDexOutOfDate) {
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Copy(GetDexSrc2(), dex_location);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
+ Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kSpeed);
}
@@ -170,8 +170,8 @@ TEST_F(DexoptAnalyzerTest, OatImageOutOfDate) {
/*pic*/false,
/*with_alternate_image*/true);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
- Verify(dex_location, CompilerFilter::kInterpretOnly);
+ Verify(dex_location, CompilerFilter::kExtract);
+ Verify(dex_location, CompilerFilter::kQuicken);
Verify(dex_location, CompilerFilter::kSpeed);
}
@@ -184,13 +184,13 @@ TEST_F(DexoptAnalyzerTest, OatVerifyAtRuntimeImageOutOfDate) {
Copy(GetDexSrc1(), dex_location);
GenerateOatForTest(dex_location.c_str(),
- CompilerFilter::kVerifyAtRuntime,
+ CompilerFilter::kExtract,
/*relocate*/true,
/*pic*/false,
/*with_alternate_image*/true);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
- Verify(dex_location, CompilerFilter::kInterpretOnly);
+ Verify(dex_location, CompilerFilter::kExtract);
+ Verify(dex_location, CompilerFilter::kQuicken);
}
// Case: We have a DEX file and an ODEX file, but no OAT file.
@@ -201,7 +201,7 @@ TEST_F(DexoptAnalyzerTest, DexOdexNoOat) {
Copy(GetDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
+ Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kSpeed);
}
@@ -235,7 +235,7 @@ TEST_F(DexoptAnalyzerTest, StrippedDexOdexOat) {
// Strip the dex file.
Copy(GetStrippedDexSrc1(), dex_location);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
+ Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kEverything);
}
@@ -248,8 +248,8 @@ TEST_F(DexoptAnalyzerTest, ResourceOnlyDex) {
Copy(GetStrippedDexSrc1(), dex_location);
Verify(dex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
- Verify(dex_location, CompilerFilter::kInterpretOnly);
+ Verify(dex_location, CompilerFilter::kExtract);
+ Verify(dex_location, CompilerFilter::kQuicken);
}
// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
@@ -287,9 +287,9 @@ TEST_F(DexoptAnalyzerTest, DexVerifyAtRuntimeOdexNoOat) {
std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kVerifyAtRuntime);
+ Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kSpeed);
}
diff --git a/runtime/Android.bp b/runtime/Android.bp
index cff2cbccdb..186996894e 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -57,6 +57,7 @@ cc_defaults {
"dex_file_annotations.cc",
"dex_file_verifier.cc",
"dex_instruction.cc",
+ "dex_to_dex_decompiler.cc",
"elf_file.cc",
"exec_utils.cc",
"fault_handler.cc",
diff --git a/runtime/arch/context-inl.h b/runtime/arch/context-inl.h
new file mode 100644
index 0000000000..ddcbbb18e5
--- /dev/null
+++ b/runtime/arch/context-inl.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This file is special-purpose for cases where you want a stack context. Most users should use
+// Context::Create().
+
+#include "context.h"
+
+#ifndef ART_RUNTIME_ARCH_CONTEXT_INL_H_
+#define ART_RUNTIME_ARCH_CONTEXT_INL_H_
+
+#if defined(__arm__)
+#include "arm/context_arm.h"
+#define RUNTIME_CONTEXT_TYPE arm::ArmContext
+#elif defined(__aarch64__)
+#include "arm64/context_arm64.h"
+#define RUNTIME_CONTEXT_TYPE arm64::Arm64Context
+#elif defined(__mips__) && !defined(__LP64__)
+#include "mips/context_mips.h"
+#define RUNTIME_CONTEXT_TYPE mips::MipsContext
+#elif defined(__mips__) && defined(__LP64__)
+#include "mips64/context_mips64.h"
+#define RUNTIME_CONTEXT_TYPE mips64::Mips64Context
+#elif defined(__i386__)
+#include "x86/context_x86.h"
+#define RUNTIME_CONTEXT_TYPE x86::X86Context
+#elif defined(__x86_64__)
+#include "x86_64/context_x86_64.h"
+#define RUNTIME_CONTEXT_TYPE x86_64::X86_64Context
+#else
+#error unimplemented
+#endif
+
+namespace art {
+
+using RuntimeContextType = RUNTIME_CONTEXT_TYPE;
+
+} // namespace art
+
+#undef RUNTIME_CONTEXT_TYPE
+
+#endif // ART_RUNTIME_ARCH_CONTEXT_INL_H_
diff --git a/runtime/arch/context.cc b/runtime/arch/context.cc
index bf40a3f8ce..82d8b6ca00 100644
--- a/runtime/arch/context.cc
+++ b/runtime/arch/context.cc
@@ -14,43 +14,12 @@
* limitations under the License.
*/
-#include "context.h"
-
-#if defined(__arm__)
-#include "arm/context_arm.h"
-#elif defined(__aarch64__)
-#include "arm64/context_arm64.h"
-#elif defined(__mips__) && !defined(__LP64__)
-#include "mips/context_mips.h"
-#elif defined(__mips__) && defined(__LP64__)
-#include "mips64/context_mips64.h"
-#elif defined(__i386__)
-#include "x86/context_x86.h"
-#elif defined(__x86_64__)
-#include "x86_64/context_x86_64.h"
-#else
-#include "base/logging.h"
-#endif
+#include "context-inl.h"
namespace art {
Context* Context::Create() {
-#if defined(__arm__)
- return new arm::ArmContext();
-#elif defined(__aarch64__)
- return new arm64::Arm64Context();
-#elif defined(__mips__) && !defined(__LP64__)
- return new mips::MipsContext();
-#elif defined(__mips__) && defined(__LP64__)
- return new mips64::Mips64Context();
-#elif defined(__i386__)
- return new x86::X86Context();
-#elif defined(__x86_64__)
- return new x86_64::X86_64Context();
-#else
- UNIMPLEMENTED(FATAL);
- return nullptr;
-#endif
+ return new RuntimeContextType;
}
} // namespace art
diff --git a/runtime/base/stl_util.h b/runtime/base/stl_util.h
index d5f375a5d9..cfe27f3811 100644
--- a/runtime/base/stl_util.h
+++ b/runtime/base/stl_util.h
@@ -194,6 +194,17 @@ static inline void MergeSets(std::set<T>& to_update, const std::set<T>& other) {
to_update.insert(other.begin(), other.end());
}
+// Returns a copy of the passed vector that doesn't memory-own its entries.
+template <typename T>
+static inline std::vector<T*> MakeNonOwningPointerVector(const std::vector<std::unique_ptr<T>>& src) {
+ std::vector<T*> result;
+ result.reserve(src.size());
+ for (const std::unique_ptr<T>& t : src) {
+ result.push_back(t.get());
+ }
+ return result;
+}
+
} // namespace art
#endif // ART_RUNTIME_BASE_STL_UTIL_H_
diff --git a/runtime/compiler_filter.cc b/runtime/compiler_filter.cc
index dc55ab8931..dbfcdfe874 100644
--- a/runtime/compiler_filter.cc
+++ b/runtime/compiler_filter.cc
@@ -20,17 +20,15 @@
namespace art {
-bool CompilerFilter::IsBytecodeCompilationEnabled(Filter filter) {
+bool CompilerFilter::IsAotCompilationEnabled(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone:
- case CompilerFilter::kVerifyAtRuntime:
- case CompilerFilter::kVerifyProfile:
- case CompilerFilter::kInterpretOnly: return false;
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract:
+ case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken: return false;
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
- case CompilerFilter::kBalanced:
- case CompilerFilter::kTime:
case CompilerFilter::kSpeedProfile:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverythingProfile:
@@ -41,15 +39,13 @@ bool CompilerFilter::IsBytecodeCompilationEnabled(Filter filter) {
bool CompilerFilter::IsJniCompilationEnabled(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone:
- case CompilerFilter::kVerifyAtRuntime: return false;
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract:
+ case CompilerFilter::kVerify: return false;
- case CompilerFilter::kVerifyProfile:
- case CompilerFilter::kInterpretOnly:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
- case CompilerFilter::kBalanced:
- case CompilerFilter::kTime:
case CompilerFilter::kSpeedProfile:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverythingProfile:
@@ -58,17 +54,15 @@ bool CompilerFilter::IsJniCompilationEnabled(Filter filter) {
UNREACHABLE();
}
-bool CompilerFilter::IsAnyMethodCompilationEnabled(Filter filter) {
+bool CompilerFilter::IsQuickeningCompilationEnabled(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone:
- case CompilerFilter::kVerifyAtRuntime:
- case CompilerFilter::kVerifyProfile: return false;
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract:
+ case CompilerFilter::kVerify: return false;
- case CompilerFilter::kInterpretOnly:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
- case CompilerFilter::kBalanced:
- case CompilerFilter::kTime:
case CompilerFilter::kSpeedProfile:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverythingProfile:
@@ -77,17 +71,21 @@ bool CompilerFilter::IsAnyMethodCompilationEnabled(Filter filter) {
UNREACHABLE();
}
+bool CompilerFilter::IsAnyCompilationEnabled(Filter filter) {
+ return IsJniCompilationEnabled(filter) ||
+ IsQuickeningCompilationEnabled(filter) ||
+ IsAotCompilationEnabled(filter);
+}
+
bool CompilerFilter::IsVerificationEnabled(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone:
- case CompilerFilter::kVerifyAtRuntime: return false;
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract: return false;
- case CompilerFilter::kVerifyProfile:
- case CompilerFilter::kInterpretOnly:
+ case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpace:
- case CompilerFilter::kBalanced:
- case CompilerFilter::kTime:
case CompilerFilter::kSpeedProfile:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverythingProfile:
@@ -104,19 +102,14 @@ bool CompilerFilter::DependsOnImageChecksum(Filter filter) {
bool CompilerFilter::DependsOnProfile(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone:
- case CompilerFilter::kVerifyAtRuntime:
- case CompilerFilter::kInterpretOnly:
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract:
+ case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpace:
- case CompilerFilter::kBalanced:
- case CompilerFilter::kTime:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverything: return false;
- // verify-profile doesn't look at profiles anymore.
- // TODO(ngeoffray): this will be cleaned up with b/34715556.
- case CompilerFilter::kVerifyProfile: return false;
-
case CompilerFilter::kSpaceProfile:
case CompilerFilter::kSpeedProfile:
case CompilerFilter::kEverythingProfile: return true;
@@ -126,21 +119,15 @@ bool CompilerFilter::DependsOnProfile(Filter filter) {
CompilerFilter::Filter CompilerFilter::GetNonProfileDependentFilterFrom(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone:
- case CompilerFilter::kVerifyAtRuntime:
- case CompilerFilter::kInterpretOnly:
+ case CompilerFilter::kAssumeVerified:
+ case CompilerFilter::kExtract:
+ case CompilerFilter::kVerify:
+ case CompilerFilter::kQuicken:
case CompilerFilter::kSpace:
- case CompilerFilter::kBalanced:
- case CompilerFilter::kTime:
case CompilerFilter::kSpeed:
case CompilerFilter::kEverything:
return filter;
- case CompilerFilter::kVerifyProfile:
- // verify-profile doesn't look at profiles anymore.
- // TODO(ngeoffray): this will be cleaned up with b/34715556.
- return filter;
-
case CompilerFilter::kSpaceProfile:
return CompilerFilter::kSpace;
@@ -160,14 +147,12 @@ bool CompilerFilter::IsAsGoodAs(Filter current, Filter target) {
std::string CompilerFilter::NameOfFilter(Filter filter) {
switch (filter) {
- case CompilerFilter::kVerifyNone: return "verify-none";
- case CompilerFilter::kVerifyAtRuntime: return "verify-at-runtime";
- case CompilerFilter::kVerifyProfile: return "verify-profile";
- case CompilerFilter::kInterpretOnly: return "interpret-only";
+ 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::kBalanced: return "balanced";
- case CompilerFilter::kTime: return "time";
case CompilerFilter::kSpeedProfile: return "speed-profile";
case CompilerFilter::kSpeed: return "speed";
case CompilerFilter::kEverythingProfile: return "everything-profile";
@@ -180,19 +165,41 @@ bool CompilerFilter::ParseCompilerFilter(const char* option, Filter* filter) {
CHECK(filter != nullptr);
if (strcmp(option, "verify-none") == 0) {
- *filter = kVerifyNone;
+ LOG(WARNING) << "'verify-none' is an obsolete compiler filter name that will be "
+ << "removed in future releases, please use 'assume-verified' instead.";
+ *filter = kAssumeVerified;
} else if (strcmp(option, "interpret-only") == 0) {
- *filter = kInterpretOnly;
+ LOG(WARNING) << "'interpret-only' is an obsolete compiler filter name that will be "
+ << "removed in future releases, please use 'quicken' instead.";
+ *filter = kQuicken;
} else if (strcmp(option, "verify-profile") == 0) {
- *filter = kVerifyProfile;
+ LOG(WARNING) << "'verify-profile' is an obsolete compiler filter name that will be "
+ << "removed in future releases, please use 'verify' instead.";
+ *filter = kVerify;
} else if (strcmp(option, "verify-at-runtime") == 0) {
- *filter = kVerifyAtRuntime;
+ LOG(WARNING) << "'verify-at-runtime' is an obsolete compiler filter name that will be "
+ << "removed in future releases, please use 'extract' instead.";
+ *filter = kExtract;
+ } else if (strcmp(option, "balanced") == 0) {
+ LOG(WARNING) << "'balanced' is an obsolete compiler filter name that will be "
+ << "removed in future releases, please use 'speed' instead.";
+ *filter = kSpeed;
+ } else if (strcmp(option, "time") == 0) {
+ LOG(WARNING) << "'time' is an obsolete compiler filter name that will be "
+ << "removed in future releases, please use 'space' instead.";
+ *filter = kSpace;
+ } else if (strcmp(option, "assume-verified") == 0) {
+ *filter = kAssumeVerified;
+ } else if (strcmp(option, "extract") == 0) {
+ *filter = kExtract;
+ } else if (strcmp(option, "verify") == 0) {
+ *filter = kVerify;
+ } else if (strcmp(option, "quicken") == 0) {
+ *filter = kQuicken;
} else if (strcmp(option, "space") == 0) {
*filter = kSpace;
} else if (strcmp(option, "space-profile") == 0) {
*filter = kSpaceProfile;
- } else if (strcmp(option, "balanced") == 0) {
- *filter = kBalanced;
} else if (strcmp(option, "speed") == 0) {
*filter = kSpeed;
} else if (strcmp(option, "speed-profile") == 0) {
@@ -201,8 +208,6 @@ bool CompilerFilter::ParseCompilerFilter(const char* option, Filter* filter) {
*filter = kEverything;
} else if (strcmp(option, "everything-profile") == 0) {
*filter = kEverythingProfile;
- } else if (strcmp(option, "time") == 0) {
- *filter = kTime;
} else {
return false;
}
diff --git a/runtime/compiler_filter.h b/runtime/compiler_filter.h
index 796f4aad0c..9cb54b14b6 100644
--- a/runtime/compiler_filter.h
+++ b/runtime/compiler_filter.h
@@ -30,14 +30,12 @@ class CompilerFilter FINAL {
// Note: Order here matters. Later filter choices are considered "as good
// as" earlier filter choices.
enum Filter {
- kVerifyNone, // Skip verification but mark all classes as verified anyway.
- kVerifyAtRuntime, // Delay verication to runtime, do not compile anything.
- kVerifyProfile, // Verify only the classes in the profile, compile only JNI stubs.
- kInterpretOnly, // Verify everything, compile only JNI stubs.
- kTime, // Compile methods, but minimize compilation time.
+ 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.
- kBalanced, // Good performance return on compilation investment.
kSpeedProfile, // Maximize runtime performance based on profile.
kSpeed, // Maximize runtime performance.
kEverythingProfile, // Compile everything capable of being compiled based on profile.
@@ -48,17 +46,21 @@ class CompilerFilter FINAL {
// Returns true if an oat file with this compiler filter contains
// compiled executable code for bytecode.
- static bool IsBytecodeCompilationEnabled(Filter filter);
+ static bool IsAotCompilationEnabled(Filter filter);
// Returns true if an oat file with this compiler filter contains
// compiled executable code for bytecode, JNI methods, or quickened dex
// bytecode.
- static bool IsAnyMethodCompilationEnabled(Filter filter);
+ static bool IsAnyCompilationEnabled(Filter filter);
// Returns true if an oat file with this compiler filter contains
// compiled executable code for JNI methods.
static bool IsJniCompilationEnabled(Filter filter);
+ // Returns true if an oat file with this compiler filter contains
+ // quickened dex bytecode.
+ static bool IsQuickeningCompilationEnabled(Filter filter);
+
// Returns true if this compiler filter requires running verification.
static bool IsVerificationEnabled(Filter filter);
diff --git a/runtime/compiler_filter_test.cc b/runtime/compiler_filter_test.cc
index c603be6e52..a59165f958 100644
--- a/runtime/compiler_filter_test.cc
+++ b/runtime/compiler_filter_test.cc
@@ -33,14 +33,12 @@ static void TestCompilerFilterName(CompilerFilter::Filter filter, std::string na
TEST(CompilerFilterTest, ParseCompilerFilter) {
CompilerFilter::Filter filter;
- TestCompilerFilterName(CompilerFilter::kVerifyNone, "verify-none");
- TestCompilerFilterName(CompilerFilter::kVerifyAtRuntime, "verify-at-runtime");
- TestCompilerFilterName(CompilerFilter::kVerifyProfile, "verify-profile");
- TestCompilerFilterName(CompilerFilter::kInterpretOnly, "interpret-only");
- TestCompilerFilterName(CompilerFilter::kTime, "time");
+ 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::kBalanced, "balanced");
TestCompilerFilterName(CompilerFilter::kSpeedProfile, "speed-profile");
TestCompilerFilterName(CompilerFilter::kSpeed, "speed");
TestCompilerFilterName(CompilerFilter::kEverythingProfile, "everything-profile");
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 63794bff6f..d0b50fe820 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1092,6 +1092,23 @@ JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId class_id, std::string* signatu
return JDWP::ERR_NONE;
}
+JDWP::JdwpError Dbg::GetSourceDebugExtension(JDWP::RefTypeId class_id,
+ std::string* extension_data) {
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
+ }
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> klass(hs.NewHandle(c));
+ const char* data = annotations::GetSourceDebugExtension(klass);
+ if (data == nullptr) {
+ return JDWP::ERR_ABSENT_INFORMATION;
+ }
+ *extension_data = data;
+ return JDWP::ERR_NONE;
+}
+
JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string* result) {
JDWP::JdwpError error;
mirror::Class* c = DecodeClass(class_id, &error);
diff --git a/runtime/debugger.h b/runtime/debugger.h
index 27124e19fb..4f3ff40e86 100644
--- a/runtime/debugger.h
+++ b/runtime/debugger.h
@@ -288,6 +288,9 @@ class Dbg {
REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError GetSignature(JDWP::RefTypeId ref_type_id, std::string* signature)
REQUIRES_SHARED(Locks::mutator_lock_);
+ static JDWP::JdwpError GetSourceDebugExtension(JDWP::RefTypeId ref_type_id,
+ std::string* extension_data)
+ REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string* source_file)
REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t* tag)
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 6b9654dc49..7d56bca6ce 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -1420,6 +1420,40 @@ mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirro
return GetSignatureValue(data, annotation_set);
}
+const char* GetSourceDebugExtension(Handle<mirror::Class> klass) {
+ ClassData data(klass);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ if (annotation_set == nullptr) {
+ return nullptr;
+ }
+ const DexFile::AnnotationItem* annotation_item = SearchAnnotationSet(
+ data.GetDexFile(),
+ annotation_set,
+ "Ldalvik/annotation/SourceDebugExtension;",
+ DexFile::kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return nullptr;
+ }
+ const uint8_t* annotation =
+ SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
+ if (annotation == nullptr) {
+ return nullptr;
+ }
+ DexFile::AnnotationValue annotation_value;
+ if (!ProcessAnnotationValue<false>(data,
+ &annotation,
+ &annotation_value,
+ ScopedNullHandle<mirror::Class>(),
+ DexFile::kAllRaw)) {
+ return nullptr;
+ }
+ if (annotation_value.type_ != DexFile::kDexAnnotationString) {
+ return nullptr;
+ }
+ dex::StringIndex index(static_cast<uint32_t>(annotation_value.value_.GetI()));
+ return data.GetDexFile().StringDataByIdx(index);
+}
+
bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) {
ClassData data(klass);
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
diff --git a/runtime/dex_file_annotations.h b/runtime/dex_file_annotations.h
index c66c5bdb8b..651c9844eb 100644
--- a/runtime/dex_file_annotations.h
+++ b/runtime/dex_file_annotations.h
@@ -89,6 +89,8 @@ bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags)
REQUIRES_SHARED(Locks::mutator_lock_);
mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
+const char* GetSourceDebugExtension(Handle<mirror::Class> klass)
+ REQUIRES_SHARED(Locks::mutator_lock_);
bool IsClassAnnotationPresent(Handle<mirror::Class> klass,
Handle<mirror::Class> annotation_class)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/compiler/dex/dex_to_dex_decompiler.cc b/runtime/dex_to_dex_decompiler.cc
index 85d5784c7a..85d5784c7a 100644
--- a/compiler/dex/dex_to_dex_decompiler.cc
+++ b/runtime/dex_to_dex_decompiler.cc
diff --git a/compiler/dex/dex_to_dex_decompiler.h b/runtime/dex_to_dex_decompiler.h
index b5d5b91915..d7cb1641e1 100644
--- a/compiler/dex/dex_to_dex_decompiler.h
+++ b/runtime/dex_to_dex_decompiler.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_DEX_DEX_TO_DEX_DECOMPILER_H_
-#define ART_COMPILER_DEX_DEX_TO_DEX_DECOMPILER_H_
+#ifndef ART_RUNTIME_DEX_TO_DEX_DECOMPILER_H_
+#define ART_RUNTIME_DEX_TO_DEX_DECOMPILER_H_
#include "base/array_ref.h"
#include "dex_file.h"
@@ -36,4 +36,4 @@ bool ArtDecompileDEX(const DexFile::CodeItem& code_item,
} // namespace optimizer
} // namespace art
-#endif // ART_COMPILER_DEX_DEX_TO_DEX_DECOMPILER_H_
+#endif // ART_RUNTIME_DEX_TO_DEX_DECOMPILER_H_
diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc
index db65e40da5..24b1abbad4 100644
--- a/runtime/dexopt_test.cc
+++ b/runtime/dexopt_test.cc
@@ -122,7 +122,7 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location,
}
if (!with_alternate_image) {
- if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) {
+ if (CompilerFilter::IsAotCompilationEnabled(filter)) {
if (relocate) {
EXPECT_EQ(reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()),
oat_header.GetImageFileLocationOatDataBegin());
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 971d03958c..e8a9904dc6 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -335,7 +335,7 @@ static JdwpError VM_CapabilitiesNew(JdwpState*, Request* request, ExpandBuf* rep
expandBufAdd1(reply, false); // canUnrestrictedlyRedefineClasses
expandBufAdd1(reply, false); // canPopFrames
expandBufAdd1(reply, true); // canUseInstanceFilters
- expandBufAdd1(reply, false); // canGetSourceDebugExtension
+ expandBufAdd1(reply, true); // canGetSourceDebugExtension
expandBufAdd1(reply, false); // canRequestVMDeathEvent
expandBufAdd1(reply, false); // canSetDefaultStratum
expandBufAdd1(reply, true); // 1.6: canGetInstanceInfo
@@ -499,13 +499,18 @@ static JdwpError RT_ClassObject(JdwpState*, Request* request, ExpandBuf* pReply)
/*
* Returns the value of the SourceDebugExtension attribute.
- *
- * JDB seems interested, but DEX files don't currently support this.
*/
-static JdwpError RT_SourceDebugExtension(JdwpState*, Request*, ExpandBuf*)
+static JdwpError RT_SourceDebugExtension(JdwpState*, Request* request, ExpandBuf* pReply)
REQUIRES_SHARED(Locks::mutator_lock_) {
/* referenceTypeId in, string out */
- return ERR_ABSENT_INFORMATION;
+ RefTypeId refTypeId = request->ReadRefTypeId();
+ std::string extension_data;
+ JdwpError status = Dbg::GetSourceDebugExtension(refTypeId, &extension_data);
+ if (status != ERR_NONE) {
+ return status;
+ }
+ expandBufAddUtf8String(pReply, extension_data);
+ return ERR_NONE;
}
static JdwpError RT_Signature(JdwpState*, Request* request, ExpandBuf* pReply, bool with_generic)
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 2eaa8c71b1..0515ec6339 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -192,8 +192,8 @@ static void EnableDebugFeatures(uint32_t debug_flags) {
const bool safe_mode = (debug_flags & DEBUG_ENABLE_SAFEMODE) != 0;
if (safe_mode) {
- // Ensure that any (secondary) oat files will be interpreted.
- runtime->AddCompilerOption("--compiler-filter=interpret-only");
+ // Only quicken oat files.
+ runtime->AddCompilerOption("--compiler-filter=quicken");
runtime->SetSafeMode(true);
debug_flags &= ~DEBUG_ENABLE_SAFEMODE;
}
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 4a85d4795e..9affeb0fcc 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -193,7 +193,7 @@ bool OatFileBase::LoadVdex(const std::string& vdex_filename,
bool writable,
bool low_4gb,
std::string* error_msg) {
- vdex_ = VdexFile::Open(vdex_filename, writable, low_4gb, error_msg);
+ vdex_ = VdexFile::Open(vdex_filename, writable, low_4gb, /* unquicken*/ false, error_msg);
if (vdex_.get() == nullptr) {
*error_msg = StringPrintf("Failed to load vdex file '%s' %s",
vdex_filename.c_str(),
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index a7be73a849..2c2b6fdcc2 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -439,7 +439,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile&
VLOG(oat) << "Image checksum test skipped for compiler filter " << current_compiler_filter;
}
- if (CompilerFilter::IsBytecodeCompilationEnabled(current_compiler_filter)) {
+ if (CompilerFilter::IsAotCompilationEnabled(current_compiler_filter)) {
if (!file.IsPic()) {
const ImageInfo* image_info = GetImageInfo();
if (image_info == nullptr) {
@@ -808,6 +808,7 @@ OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() {
std::unique_ptr<VdexFile> vdex = VdexFile::Open(vdex_filename,
/*writeable*/false,
/*low_4gb*/false,
+ /*unquicken*/false,
&error_msg);
if (vdex == nullptr) {
status_ = kOatCannotOpen;
@@ -834,7 +835,7 @@ OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() {
OatFileAssistant::DexOptNeeded OatFileAssistant::OatFileInfo::GetDexOptNeeded(
CompilerFilter::Filter target, bool profile_changed) {
- bool compilation_desired = CompilerFilter::IsBytecodeCompilationEnabled(target);
+ bool compilation_desired = CompilerFilter::IsAotCompilationEnabled(target);
bool filter_okay = CompilerFilterIsOkay(target, profile_changed);
if (filter_okay && Status() == kOatUpToDate) {
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 4a738ab0a3..198f8e68e0 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -53,9 +53,9 @@ TEST_F(OatFileAssistantTest, DexNoOat) {
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
@@ -99,9 +99,9 @@ TEST_F(OatFileAssistantTest, OatUpToDate) {
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
@@ -204,11 +204,11 @@ TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, false));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, false));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, false));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, true));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, true));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, true));
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -269,7 +269,7 @@ TEST_F(OatFileAssistantTest, StrippedMultiDexNonMainOutOfDate) {
// Compile the odex from GetMultiDexSrc2, which has a different non-main
// dex checksum.
Copy(GetMultiDexSrc2(), dex_location);
- GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kInterpretOnly);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kQuicken);
// Strip the dex file.
Copy(GetStrippedDexSrc1(), dex_location);
@@ -332,7 +332,7 @@ TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
@@ -406,9 +406,9 @@ TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
@@ -427,16 +427,16 @@ TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
Copy(GetDexSrc1(), dex_location);
GenerateOatForTest(dex_location.c_str(),
- CompilerFilter::kVerifyAtRuntime,
+ CompilerFilter::kExtract,
/*relocate*/true,
/*pic*/false,
/*with_alternate_image*/true);
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -457,7 +457,7 @@ TEST_F(OatFileAssistantTest, DexOdexNoOat) {
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
@@ -523,7 +523,7 @@ TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped.
@@ -556,9 +556,9 @@ TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -653,13 +653,13 @@ TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
// Create the dex and odex files
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
// Verify the status.
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
@@ -688,13 +688,13 @@ TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
EXPECT_EQ(1u, dex_files.size());
}
-// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
+// Case: We have a DEX file and up-to-date quicken OAT file for it.
// Expect: We should still load the oat file as executable.
TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
Copy(GetDexSrc1(), dex_location);
- GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
+ GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
// Load the oat using an oat file assistant.
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
@@ -1003,11 +1003,11 @@ TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
std::string error_msg;
- Runtime::Current()->AddCompilerOption("--compiler-filter=interpret-only");
+ Runtime::Current()->AddCompilerOption("--compiler-filter=quicken");
EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
@@ -1015,7 +1015,7 @@ TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
- oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
diff --git a/runtime/openjdkjvmti/fixed_up_dex_file.cc b/runtime/openjdkjvmti/fixed_up_dex_file.cc
index 3338358796..29aebae4b6 100644
--- a/runtime/openjdkjvmti/fixed_up_dex_file.cc
+++ b/runtime/openjdkjvmti/fixed_up_dex_file.cc
@@ -32,10 +32,8 @@
#include "fixed_up_dex_file.h"
#include "dex_file-inl.h"
-// Compiler includes.
-#include "dex/dex_to_dex_decompiler.h"
-
// Runtime includes.
+#include "dex_to_dex_decompiler.h"
#include "oat_file.h"
#include "vdex_file.h"
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 0125539ab0..e61ec23036 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -905,6 +905,7 @@ static bool OpenDexFilesFromImage(const std::string& image_location,
std::unique_ptr<VdexFile> vdex_file(VdexFile::Open(vdex_filename,
false /* writable */,
false /* low_4gb */,
+ false, /* unquicken */
&error_msg));
if (vdex_file.get() == nullptr) {
return false;
@@ -2133,7 +2134,7 @@ void Runtime::SetFaultMessage(const std::string& message) {
void Runtime::AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* argv)
const {
if (GetInstrumentation()->InterpretOnly()) {
- argv->push_back("--compiler-filter=interpret-only");
+ argv->push_back("--compiler-filter=quicken");
}
// Make the dex2oat instruction set match that of the launching runtime. If we have multiple
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 201701a510..62a616b646 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -35,6 +35,7 @@
#include "android-base/stringprintf.h"
#include "arch/context.h"
+#include "arch/context-inl.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/bit_utils.h"
@@ -3413,11 +3414,10 @@ void Thread::VisitRoots(RootVisitor* visitor) {
verifier->VisitRoots(visitor, RootInfo(kRootNativeStack, thread_id));
}
// Visit roots on this thread's stack
- Context* context = GetLongJumpContext();
+ RuntimeContextType context;
RootCallbackVisitor visitor_to_callback(visitor, thread_id);
- ReferenceMapVisitor<RootCallbackVisitor, kPrecise> mapper(this, context, visitor_to_callback);
+ ReferenceMapVisitor<RootCallbackVisitor, kPrecise> mapper(this, &context, visitor_to_callback);
mapper.template WalkStack<StackVisitor::CountTransitions::kNo>(false);
- ReleaseLongJumpContext(context);
for (instrumentation::InstrumentationStackFrame& frame : *GetInstrumentationStack()) {
visitor->VisitRootIfNonNull(&frame.this_object_, RootInfo(kRootVMInternal, thread_id));
}
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 945f08b58a..e93f04d082 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -21,8 +21,10 @@
#include <memory>
#include "base/logging.h"
+#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "dex_file.h"
+#include "dex_to_dex_decompiler.h"
namespace art {
@@ -54,6 +56,7 @@ VdexFile::Header::Header(uint32_t number_of_dex_files,
std::unique_ptr<VdexFile> VdexFile::Open(const std::string& vdex_filename,
bool writable,
bool low_4gb,
+ bool unquicken,
std::string* error_msg) {
if (!OS::FileExists(vdex_filename.c_str())) {
*error_msg = "File " + vdex_filename + " does not exist.";
@@ -78,7 +81,7 @@ std::unique_ptr<VdexFile> VdexFile::Open(const std::string& vdex_filename,
return nullptr;
}
- return Open(vdex_file->Fd(), vdex_length, vdex_filename, writable, low_4gb, error_msg);
+ return Open(vdex_file->Fd(), vdex_length, vdex_filename, writable, low_4gb, unquicken, error_msg);
}
std::unique_ptr<VdexFile> VdexFile::Open(int file_fd,
@@ -86,15 +89,17 @@ std::unique_ptr<VdexFile> VdexFile::Open(int file_fd,
const std::string& vdex_filename,
bool writable,
bool low_4gb,
+ bool unquicken,
std::string* error_msg) {
- std::unique_ptr<MemMap> mmap(MemMap::MapFile(vdex_length,
- writable ? PROT_READ | PROT_WRITE : PROT_READ,
- MAP_SHARED,
- file_fd,
- 0 /* start offset */,
- low_4gb,
- vdex_filename.c_str(),
- error_msg));
+ std::unique_ptr<MemMap> mmap(MemMap::MapFile(
+ vdex_length,
+ (writable || unquicken) ? PROT_READ | PROT_WRITE : PROT_READ,
+ unquicken ? MAP_PRIVATE : MAP_SHARED,
+ file_fd,
+ 0 /* start offset */,
+ low_4gb,
+ vdex_filename.c_str(),
+ error_msg));
if (mmap == nullptr) {
*error_msg = "Failed to mmap file " + vdex_filename + " : " + *error_msg;
return nullptr;
@@ -106,6 +111,16 @@ std::unique_ptr<VdexFile> VdexFile::Open(int file_fd,
return nullptr;
}
+ if (unquicken) {
+ std::vector<std::unique_ptr<const DexFile>> unique_ptr_dex_files;
+ if (!vdex->OpenAllDexFiles(&unique_ptr_dex_files, error_msg)) {
+ return nullptr;
+ }
+ Unquicken(MakeNonOwningPointerVector(unique_ptr_dex_files), vdex->GetQuickeningInfo());
+ // Update the quickening info size to pretend there isn't any.
+ reinterpret_cast<Header*>(vdex->mmap_->Begin())->quickening_info_size_ = 0;
+ }
+
*error_msg = "Success";
return vdex;
}
@@ -148,4 +163,62 @@ bool VdexFile::OpenAllDexFiles(std::vector<std::unique_ptr<const DexFile>>* dex_
return true;
}
+void VdexFile::Unquicken(const std::vector<const DexFile*>& dex_files,
+ const ArrayRef<const uint8_t>& quickening_info) {
+ if (quickening_info.size() == 0) {
+ // If there is no quickening info, we bail early, as the code below expects at
+ // least the size of quickening data for each method that has a code item.
+ return;
+ }
+ 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) {
+ for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
+ const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
+ const uint8_t* class_data = dex_file->GetClassData(class_def);
+ if (class_data == nullptr) {
+ continue;
+ }
+ ClassDataItemIterator it(*dex_file, class_data);
+ // Skip fields
+ while (it.HasNextStaticField()) {
+ it.Next();
+ }
+ while (it.HasNextInstanceField()) {
+ it.Next();
+ }
+
+ while (it.HasNextDirectMethod()) {
+ const DexFile::CodeItem* code_item = it.GetMethodCodeItem();
+ if (code_item != nullptr) {
+ uint32_t quickening_size = *reinterpret_cast<const uint32_t*>(quickening_info_ptr);
+ quickening_info_ptr += sizeof(uint32_t);
+ optimizer::ArtDecompileDEX(*code_item,
+ ArrayRef<const uint8_t>(quickening_info_ptr, quickening_size),
+ /* decompile_return_instruction */ false);
+ quickening_info_ptr += quickening_size;
+ }
+ it.Next();
+ }
+
+ while (it.HasNextVirtualMethod()) {
+ const DexFile::CodeItem* code_item = it.GetMethodCodeItem();
+ if (code_item != nullptr) {
+ uint32_t quickening_size = *reinterpret_cast<const uint32_t*>(quickening_info_ptr);
+ quickening_info_ptr += sizeof(uint32_t);
+ optimizer::ArtDecompileDEX(*code_item,
+ ArrayRef<const uint8_t>(quickening_info_ptr, quickening_size),
+ /* decompile_return_instruction */ false);
+ quickening_info_ptr += quickening_size;
+ }
+ it.Next();
+ }
+ DCHECK(!it.HasNext());
+ }
+ }
+ if (quickening_info_ptr != quickening_info_end) {
+ LOG(FATAL) << "Failed to use all quickening info";
+ }
+}
+
} // namespace art
diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h
index 9840555bbd..9c0d9dba8f 100644
--- a/runtime/vdex_file.h
+++ b/runtime/vdex_file.h
@@ -71,6 +71,8 @@ class VdexFile {
uint32_t dex_size_;
uint32_t verifier_deps_size_;
uint32_t quickening_info_size_;
+
+ friend class VdexFile;
};
typedef uint32_t VdexChecksum;
@@ -79,6 +81,7 @@ class VdexFile {
static std::unique_ptr<VdexFile> Open(const std::string& vdex_filename,
bool writable,
bool low_4gb,
+ bool unquicken,
std::string* error_msg);
// Returns nullptr if the vdex file cannot be opened or is not valid.
@@ -87,6 +90,7 @@ class VdexFile {
const std::string& vdex_filename,
bool writable,
bool low_4gb,
+ bool unquicken,
std::string* error_msg);
const uint8_t* Begin() const { return mmap_->Begin(); }
@@ -124,12 +128,14 @@ class VdexFile {
return reinterpret_cast<const uint32_t*>(Begin() + sizeof(Header))[dex_file_index];
}
- // Opens all the dex files contained in this vdex file. This is currently
- // used for dumping tools only, and has not been tested for use by the
- // remainder of the runtime.
+ // Opens all the dex files contained in this vdex file.
bool OpenAllDexFiles(std::vector<std::unique_ptr<const DexFile>>* dex_files,
std::string* error_msg);
+ // In-place unquicken the given `dex_files` based on `quickening_info`.
+ static void Unquicken(const std::vector<const DexFile*>& dex_files,
+ const ArrayRef<const uint8_t>& quickening_info);
+
private:
explicit VdexFile(MemMap* mmap) : mmap_(mmap) {}
diff --git a/runtime/vdex_file_test.cc b/runtime/vdex_file_test.cc
index 909e117ccc..ced6e28577 100644
--- a/runtime/vdex_file_test.cc
+++ b/runtime/vdex_file_test.cc
@@ -36,10 +36,12 @@ TEST_F(VdexFileTest, OpenEmptyVdex) {
tmp.GetFilename(),
/*writable*/false,
/*low_4gb*/false,
+ /*quicken*/false,
&error_msg);
EXPECT_TRUE(vdex == nullptr);
- vdex = VdexFile::Open(tmp.GetFilename(), /*writable*/false, /*low_4gb*/false, &error_msg);
+ vdex = VdexFile::Open(
+ tmp.GetFilename(), /*writable*/false, /*low_4gb*/false, /*quicken*/ false, &error_msg);
EXPECT_TRUE(vdex == nullptr);
}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 2b0c6127af..cb9c6052a2 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3764,7 +3764,7 @@ const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_i
const RegType& referrer = GetDeclaringClass();
if (!referrer.IsUnresolvedTypes() && !referrer.CanAccess(*result)) {
Fail(VERIFY_ERROR_ACCESS_CLASS) << "illegal class access: '"
- << referrer << "' -> '" << result << "'";
+ << referrer << "' -> '" << *result << "'";
}
}
return *result;
diff --git a/test/117-nopatchoat/nopatchoat.cc b/test/117-nopatchoat/nopatchoat.cc
index 3236bde5a2..2248fc4efd 100644
--- a/test/117-nopatchoat/nopatchoat.cc
+++ b/test/117-nopatchoat/nopatchoat.cc
@@ -56,7 +56,7 @@ class NoPatchoatTest {
const OatFile* oat_file = oat_dex_file->GetOatFile();
return !oat_file->IsPic()
- && CompilerFilter::IsBytecodeCompilationEnabled(oat_file->GetCompilerFilter());
+ && CompilerFilter::IsAotCompilationEnabled(oat_file->GetCompilerFilter());
}
};
diff --git a/test/157-void-class/run b/test/157-void-class/run
index 59e852c8cd..8c6159fc4c 100755
--- a/test/157-void-class/run
+++ b/test/157-void-class/run
@@ -14,9 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Let the test build its own core image with --no-image and use verify-profile,
+# Let the test build its own core image with --no-image and use verify,
# so that the compiler does not try to initialize classes. This leaves the
# java.lang.Void compile-time verified but uninitialized.
./default-run "$@" --no-image \
--runtime-option -Ximage-compiler-option \
- --runtime-option --compiler-filter=verify-profile
+ --runtime-option --compiler-filter=verify
diff --git a/test/595-profile-saving/run b/test/595-profile-saving/run
index 068ad03ce0..fce6ac15d8 100644
--- a/test/595-profile-saving/run
+++ b/test/595-profile-saving/run
@@ -15,13 +15,13 @@
# limitations under the License.
# Use
-# --compiler-filter=interpret-only to make sure that the test is not compiled AOT
+# --compiler-filter=quicken to make sure that the test is not compiled AOT
# and to make sure the test is not compiled when loaded (by PathClassLoader)
# -Xjitsaveprofilinginfo to enable profile saving
# -Xusejit:false to disable jit and only test profiles.
exec ${RUN} \
- -Xcompiler-option --compiler-filter=interpret-only \
- --runtime-option '-Xcompiler-option --compiler-filter=interpret-only' \
+ -Xcompiler-option --compiler-filter=quicken \
+ --runtime-option '-Xcompiler-option --compiler-filter=quicken' \
--runtime-option -Xjitsaveprofilinginfo \
--runtime-option -Xusejit:false \
"${@}"
diff --git a/test/628-vdex/run b/test/628-vdex/run
index 4cbcea3b7e..bf0ac910c1 100644
--- a/test/628-vdex/run
+++ b/test/628-vdex/run
@@ -14,4 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-exec ${RUN} -Xcompiler-option --compiler-filter=verify-profile --vdex "${@}"
+exec ${RUN} -Xcompiler-option --compiler-filter=verify --vdex "${@}"
diff --git a/test/634-vdex-duplicate/run b/test/634-vdex-duplicate/run
index 1ccb84150b..571ccd90e1 100644
--- a/test/634-vdex-duplicate/run
+++ b/test/634-vdex-duplicate/run
@@ -14,4 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-exec ${RUN} -Xcompiler-option --compiler-filter=verify-profile --vdex-filter speed --vdex "${@}"
+exec ${RUN} -Xcompiler-option --compiler-filter=verify --vdex-filter speed --vdex "${@}"
diff --git a/test/648-many-direct-methods/build b/test/648-many-direct-methods/build
deleted file mode 100755
index 7e888e5bca..0000000000
--- a/test/648-many-direct-methods/build
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /bin/bash
-#
-# Copyright 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Exit on a failure.
-set -e
-
-mkdir -p ./src
-
-# Generate the Java file or fail.
-./util-src/generate_java.py ./src
-
-./default-build "$@"
diff --git a/test/648-many-direct-methods/expected.txt b/test/648-many-direct-methods/expected.txt
deleted file mode 100644
index b0aad4deb5..0000000000
--- a/test/648-many-direct-methods/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-passed
diff --git a/test/648-many-direct-methods/info.txt b/test/648-many-direct-methods/info.txt
deleted file mode 100644
index a65ab8066f..0000000000
--- a/test/648-many-direct-methods/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Regression test checking that the runtime can handle a huge number of
-direct methods (b/33650497).
diff --git a/test/648-many-direct-methods/util-src/generate_java.py b/test/648-many-direct-methods/util-src/generate_java.py
deleted file mode 100755
index 6cae868915..0000000000
--- a/test/648-many-direct-methods/util-src/generate_java.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#! /usr/bin/python3
-#
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Generate Java test files for test 648-many-direct-methods.
-"""
-
-import os
-import sys
-from pathlib import Path
-
-BUILD_TOP = os.getenv("ANDROID_BUILD_TOP")
-if BUILD_TOP is None:
- print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr)
- sys.exit(1)
-
-# Allow us to import utils and mixins.
-sys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python"))
-
-from testgen.utils import get_copyright, subtree_sizes, gensym, filter_blanks
-import testgen.mixins as mixins
-
-class MainClass(mixins.DumpMixin, mixins.Named, mixins.JavaFileMixin):
- """
- A Main.java file containing the Main class and the main function. It will run
- all the test functions we have.
- """
-
- MAIN_CLASS_TEMPLATE = """{copyright}
-public class Main {{
-{main_func}
-{test_groups}
-
-}}"""
-
- MAIN_FUNCTION_TEMPLATE = """
- public static void main(String[] args) {
- System.out.println("passed");
- }"""
-
- def __init__(self):
- """
- Initialize this MainClass. We start out with no tests.
- """
- self.tests = set()
-
- def add_test_method(self, num):
- """
- Add test method number 'num'
- """
- self.tests.add(TestMethod(num))
-
- def get_name(self):
- """
- Get the name of this class
- """
- return "Main"
-
- def __str__(self):
- """
- Print the MainClass Java code.
- """
- all_tests = sorted(self.tests)
- test_groups = ""
- for t in all_tests:
- test_groups += str(t)
- main_func = self.MAIN_FUNCTION_TEMPLATE
-
- return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright("java"),
- main_func = main_func,
- test_groups = test_groups)
-
-class TestMethod(mixins.Named, mixins.NameComparableMixin):
- """
- A function that represents a test method. Should only be
- constructed by MainClass.add_test_method.
- """
-
- TEST_FUNCTION_TEMPLATE = """
- public static void {fname}() {{}}"""
-
- def __init__(self, farg):
- """
- Initialize a test method for the given argument.
- """
- self.farg = farg
-
- def get_name(self):
- """
- Get the name of this test method.
- """
- return "method{:05d}".format(self.farg)
-
- def __str__(self):
- """
- Print the Java code of this test method.
- """
- return self.TEST_FUNCTION_TEMPLATE.format(fname=self.get_name())
-
-# Number of generated test methods. This number has been chosen to
-# make sure the number of direct methods in class Main is greater or
-# equal to 2^16, and thus requires an *unsigned* 16-bit (short)
-# integer to be represented (b/33650497).
-NUM_TEST_METHODS = 32768
-
-def create_test_file():
- """
- Creates the object representing the test file. It just needs to be dumped.
- """
- mc = MainClass()
- for i in range(1, NUM_TEST_METHODS + 1):
- mc.add_test_method(i)
- return mc
-
-def main(argv):
- java_dir = Path(argv[1])
- if not java_dir.exists() or not java_dir.is_dir():
- print("{} is not a valid Java dir".format(java_dir), file=sys.stderr)
- sys.exit(1)
- mainclass = create_test_file()
- mainclass.dump(java_dir)
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index b34da08716..f725b89eb1 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -469,15 +469,15 @@ fi
if [ "$INTERPRETER" = "y" ]; then
INT_OPTS="-Xint"
if [ "$VERIFY" = "y" ] ; then
- INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=interpret-only"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
+ INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=quicken"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=quicken"
elif [ "$VERIFY" = "s" ]; then
- INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-at-runtime"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-at-runtime"
+ INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=extract"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=extract"
DEX_VERIFY="${DEX_VERIFY} -Xverify:softfail"
else # VERIFY = "n"
- INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-none"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
+ INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=assume-verified"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=assume-verified"
DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
fi
fi
@@ -485,11 +485,11 @@ fi
if [ "$JIT" = "y" ]; then
INT_OPTS="-Xusejit:true"
if [ "$VERIFY" = "y" ] ; then
- INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=interpret-only"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
+ INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=quicken"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=quicken"
else
- INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-none"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
+ INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=assume-verified"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=assume-verified"
DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
fi
fi
@@ -605,6 +605,8 @@ if [ "$PREBUILD" = "y" ]; then
fi
if [ "$TEST_VDEX" = "y" ]; then
vdex_cmdline="${dex2oat_cmdline} ${VDEX_FILTER} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex"
+ elif [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then
+ vdex_cmdline="${dex2oat_cmdline} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex --output-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex"
fi
fi
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 8df7466cf8..f7fb3573e6 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -667,9 +667,15 @@
"bug": "b/37636792"
},
{
- "tests": "648-many-direct-methods",
- "variant": "optimizing | speed-profile | no-image",
- "description": "Test disabled with AOT because of dex2oatd timeouts.",
- "bug": "b/33650497"
+ "tests": [
+ "536-checker-needs-access-check",
+ "537-checker-inline-and-unverified",
+ "569-checker-pattern-replacement",
+ "586-checker-null-array-get"
+ ],
+ "description": [
+ "Tests that have verify-at-runtime classes, but being compiled when using vdex."
+ ],
+ "variant": "speed-profile"
}
]
diff --git a/tools/art b/tools/art
index 933ad7a375..0bc08f0fce 100644
--- a/tools/art
+++ b/tools/art
@@ -46,17 +46,17 @@ function find_libdir() {
fi
}
-function replace_compiler_filter_with_interepret_only() {
- ARGS_WITH_INTERPRET_ONLY=("$@")
+function replace_compiler_filter_with_quicken() {
+ ARGS_WITH_QUICKEN=("$@")
found="false"
((index=0))
while ((index <= $#)); do
- what="${ARGS_WITH_INTERPRET_ONLY[$index]}"
+ what="${ARGS_WITH_QUICKEN[$index]}"
case "$what" in
--compiler-filter=*)
- ARGS_WITH_INTERPRET_ONLY[$index]="--compiler-filter=interpret-only"
+ ARGS_WITH_QUICKEN[$index]="--compiler-filter=quicken"
found="true"
;;
esac
@@ -65,7 +65,7 @@ function replace_compiler_filter_with_interepret_only() {
shift
done
if [ "$found" != "true" ]; then
- ARGS_WITH_INTERPRET_ONLY=(-Xcompiler-option --compiler-filter=interpret-only "${ARGS_WITH_INTERPRET_ONLY[@]}")
+ ARGS_WITH_QUICKEN=(-Xcompiler-option --compiler-filter=quicken "${ARGS_WITH_QUICKEN[@]}")
fi
}
@@ -224,10 +224,10 @@ if [ "$JIT_PROFILE" = "yes" ]; then
PROFILE_PATH="$ANDROID_DATA/primary.prof"
touch $PROFILE_PATH
- # Replace the compiler filter with interpret-only so that we
+ # Replace the compiler filter with quicken so that we
# can capture the profile.
- ARGS_WITH_INTERPRET_ONLY=
- replace_compiler_filter_with_interepret_only "$@"
+ ARGS_WITH_QUICKEN=
+ replace_compiler_filter_with_quicken "$@"
run_art -Xjitsaveprofilinginfo \
-Xps-min-methods-to-save:1 \
@@ -235,7 +235,7 @@ if [ "$JIT_PROFILE" = "yes" ]; then
-Xps-min-notification-before-wake:10 \
-Xps-profile-path:$PROFILE_PATH \
-Xusejit:true \
- "${ARGS_WITH_INTERPRET_ONLY[@]}" \
+ "${ARGS_WITH_QUICKEN[@]}" \
"&>" "$ANDROID_DATA/profile_gen.log"
EXIT_STATUS=$?
diff --git a/tools/dexfuzz/src/dexfuzz/executors/Executor.java b/tools/dexfuzz/src/dexfuzz/executors/Executor.java
index 2bcf3a1a77..074672d0ff 100644
--- a/tools/dexfuzz/src/dexfuzz/executors/Executor.java
+++ b/tools/dexfuzz/src/dexfuzz/executors/Executor.java
@@ -117,7 +117,7 @@ public abstract class Executor {
commandBuilder.append("--runtime-arg -classpath ");
commandBuilder.append("--runtime-arg ").append(programName).append(" ");
commandBuilder.append("--dex-file=").append(programName).append(" ");
- commandBuilder.append("--compiler-filter=interpret-only --runtime-arg -Xnorelocate ");
+ commandBuilder.append("--compiler-filter=quicken --runtime-arg -Xnorelocate ");
ExecutionResult verificationResult = device.executeCommand(commandBuilder.toString(), true,
outputConsumer, errorConsumer);
diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh
index 07c300e7a7..d48d8579be 100755
--- a/tools/run-jdwp-tests.sh
+++ b/tools/run-jdwp-tests.sh
@@ -132,8 +132,8 @@ if [[ "$image" != "" ]]; then
vm_args="--vm-arg $image"
fi
if $use_jit; then
- vm_args="$vm_args --vm-arg -Xcompiler-option --vm-arg --compiler-filter=interpret-only"
- debuggee_args="$debuggee_args -Xcompiler-option --compiler-filter=interpret-only"
+ vm_args="$vm_args --vm-arg -Xcompiler-option --vm-arg --compiler-filter=quicken"
+ debuggee_args="$debuggee_args -Xcompiler-option --compiler-filter=quicken"
fi
vm_args="$vm_args --vm-arg -Xusejit:$use_jit"
debuggee_args="$debuggee_args -Xusejit:$use_jit"
diff --git a/tools/run-libcore-tests.sh b/tools/run-libcore-tests.sh
index 729a3e5ac4..b860a6273f 100755
--- a/tools/run-libcore-tests.sh
+++ b/tools/run-libcore-tests.sh
@@ -127,7 +127,7 @@ vogar_args="$vogar_args --toolchain jack --language JO"
# JIT settings.
if $use_jit; then
- vogar_args="$vogar_args --vm-arg -Xcompiler-option --vm-arg --compiler-filter=interpret-only"
+ vogar_args="$vogar_args --vm-arg -Xcompiler-option --vm-arg --compiler-filter=quicken"
fi
vogar_args="$vogar_args --vm-arg -Xusejit:$use_jit"