diff options
-rw-r--r-- | compiler/driver/compiler_driver.cc | 30 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 4 | ||||
-rw-r--r-- | compiler/driver/compiler_options.h | 19 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 2 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 3 | ||||
-rwxr-xr-x | test/etc/run-test-jar | 2 |
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" |