summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/driver/compiler_driver.cc30
-rw-r--r--compiler/driver/compiler_driver.h4
-rw-r--r--compiler/driver/compiler_options.h19
-rw-r--r--dex2oat/dex2oat.cc2
-rw-r--r--runtime/verifier/method_verifier.cc3
-rwxr-xr-xtest/etc/run-test-jar2
6 files changed, 45 insertions, 15 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index ff4e0d850a..34963a9675 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -491,11 +491,12 @@ void CompilerDriver::CompileAll(jobject class_loader,
}
}
-static DexToDexCompilationLevel GetDexToDexCompilationlevel(
+DexToDexCompilationLevel CompilerDriver::GetDexToDexCompilationlevel(
Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file,
- const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::ClassDef& class_def) {
auto* const runtime = Runtime::Current();
- if (runtime->UseJit()) {
+ if (runtime->UseJit() || GetCompilerOptions().VerifyAtRuntime()) {
+ // Verify at runtime shouldn't dex to dex since we didn't resolve of verify.
return kDontDexToDexCompile;
}
const char* descriptor = dex_file.GetClassDescriptor(class_def);
@@ -605,12 +606,22 @@ void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const De
LoadImageClasses(timings);
VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString(false);
- Resolve(class_loader, dex_files, thread_pool, timings);
- VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
+ const bool verification_enabled = compiler_options_->IsVerificationEnabled();
+ const bool never_verify = compiler_options_->NeverVerify();
- if (!compiler_options_->IsVerificationEnabled()) {
+ // We need to resolve for never_verify since it needs to run dex to dex to add the
+ // RETURN_VOID_NO_BARRIER.
+ if (never_verify || verification_enabled) {
+ Resolve(class_loader, dex_files, thread_pool, timings);
+ VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
+ }
+
+ if (never_verify) {
VLOG(compiler) << "Verify none mode specified, skipping verification.";
SetVerified(class_loader, dex_files, thread_pool, timings);
+ }
+
+ if (!verification_enabled) {
return;
}
@@ -2090,6 +2101,8 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz
return;
}
+ CompilerDriver* const driver = manager->GetCompiler();
+
// Can we run DEX-to-DEX compiler on this class ?
DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
{
@@ -2097,8 +2110,8 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
- dex_to_dex_compilation_level = GetDexToDexCompilationlevel(soa.Self(), class_loader, dex_file,
- class_def);
+ dex_to_dex_compilation_level = driver->GetDexToDexCompilationlevel(
+ soa.Self(), class_loader, dex_file, class_def);
}
ClassDataItemIterator it(dex_file, class_data);
// Skip fields
@@ -2108,7 +2121,6 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz
while (it.HasNextInstanceField()) {
it.Next();
}
- CompilerDriver* driver = manager->GetCompiler();
bool compilation_enabled = driver->IsClassToCompile(
dex_file.StringByTypeIdx(class_def.class_idx_));
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 28a82457cc..9463c2c9bd 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -468,6 +468,10 @@ class CompilerDriver {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
private:
+ DexToDexCompilationLevel GetDexToDexCompilationlevel(
+ Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file,
+ const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
void PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
ThreadPool* thread_pool, TimingLogger* timings)
LOCKS_EXCLUDED(Locks::mutator_lock_);
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 5042c7594c..d06ec278ab 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -32,7 +32,8 @@ class CompilerOptions FINAL {
public:
enum CompilerFilter {
kVerifyNone, // Skip verification and compile nothing except JNI stubs.
- kInterpretOnly, // Compile nothing except JNI stubs.
+ kInterpretOnly, // Verify, and compile only JNI stubs.
+ kVerifyAtRuntime, // Only compile JNI stubs and verify at runtime.
kSpace, // Maximize space savings.
kBalanced, // Try to get the best performance return on compilation investment.
kSpeed, // Maximize runtime performance.
@@ -81,13 +82,23 @@ class CompilerOptions FINAL {
compiler_filter_ = compiler_filter;
}
+ bool VerifyAtRuntime() const {
+ return compiler_filter_ == CompilerOptions::kVerifyAtRuntime;
+ }
+
bool IsCompilationEnabled() const {
- return ((compiler_filter_ != CompilerOptions::kVerifyNone) &&
- (compiler_filter_ != CompilerOptions::kInterpretOnly));
+ return compiler_filter_ != CompilerOptions::kVerifyNone &&
+ compiler_filter_ != CompilerOptions::kInterpretOnly &&
+ compiler_filter_ != CompilerOptions::kVerifyAtRuntime;
}
bool IsVerificationEnabled() const {
- return (compiler_filter_ != CompilerOptions::kVerifyNone);
+ return compiler_filter_ != CompilerOptions::kVerifyNone &&
+ compiler_filter_ != CompilerOptions::kVerifyAtRuntime;
+ }
+
+ bool NeverVerify() const {
+ return compiler_filter_ == CompilerOptions::kVerifyNone;
}
size_t GetHugeMethodThreshold() const {
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index a372179296..67c96fd63b 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -894,6 +894,8 @@ class Dex2Oat FINAL {
compiler_filter = CompilerOptions::kVerifyNone;
} else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
compiler_filter = CompilerOptions::kInterpretOnly;
+ } else if (strcmp(compiler_filter_string, "verify-at-runtime") == 0) {
+ compiler_filter = CompilerOptions::kVerifyAtRuntime;
} else if (strcmp(compiler_filter_string, "space") == 0) {
compiler_filter = CompilerOptions::kSpace;
} else if (strcmp(compiler_filter_string, "balanced") == 0) {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index c67a58a022..3b98e47010 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2748,7 +2748,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
auto* klass = declaring_class.GetClass();
for (uint32_t i = 0, num_fields = klass->NumInstanceFields(); i < num_fields; ++i) {
if (klass->GetInstanceField(i)->IsFinal()) {
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected";
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for "
+ << PrettyField(klass->GetInstanceField(i));
break;
}
}
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 840ff80a80..414e4df9f5 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -267,7 +267,7 @@ fi
if [ "$JIT" = "y" ]; then
INT_OPTS="-Xusejit:true"
if [ "$VERIFY" = "y" ] ; then
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-at-runtime"
else
COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
DEX_VERIFY="${DEX_VERIFY} -Xverify:none"