diff options
| -rw-r--r-- | compiler/dex/verification_results.cc | 4 | ||||
| -rw-r--r-- | compiler/dex/verified_method.cc | 23 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 10 |
3 files changed, 21 insertions, 16 deletions
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 60d24068b1..4daed67784 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -57,8 +57,8 @@ bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method const VerifiedMethod* verified_method = VerifiedMethod::Create(method_verifier, compile); if (verified_method == nullptr) { - DCHECK(method_verifier->HasFailures()); - return false; + // Do not report an error to the verifier. We'll just punt this later. + return true; } WriterMutexLock mu(Thread::Current(), verified_methods_lock_); diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc index d684bc9006..93e9a51da1 100644 --- a/compiler/dex/verified_method.cc +++ b/compiler/dex/verified_method.cc @@ -49,7 +49,6 @@ const VerifiedMethod* VerifiedMethod::Create(verifier::MethodVerifier* method_ve if (compile) { /* Generate a register map. */ if (!verified_method->GenerateGcMap(method_verifier)) { - CHECK(method_verifier->HasFailures()); return nullptr; // Not a real failure, but a failure to encode. } if (kIsDebugBuild) { @@ -83,17 +82,17 @@ bool VerifiedMethod::GenerateGcMap(verifier::MethodVerifier* method_verifier) { ComputeGcMapSizes(method_verifier, &num_entries, &ref_bitmap_bits, &pc_bits); // There's a single byte to encode the size of each bitmap. if (ref_bitmap_bits >= kBitsPerByte * 8192 /* 13-bit size */) { - // TODO: either a better GC map format or per method failures - method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) - << "Cannot encode GC map for method with " << ref_bitmap_bits << " registers"; + LOG(WARNING) << "Cannot encode GC map for method with " << ref_bitmap_bits << " registers: " + << PrettyMethod(method_verifier->GetMethodReference().dex_method_index, + *method_verifier->GetMethodReference().dex_file); return false; } size_t ref_bitmap_bytes = RoundUp(ref_bitmap_bits, kBitsPerByte) / kBitsPerByte; // There are 2 bytes to encode the number of entries. if (num_entries >= 65536) { - // TODO: Either a better GC map format or per method failures. - method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) - << "Cannot encode GC map for method with " << num_entries << " entries"; + LOG(WARNING) << "Cannot encode GC map for method with " << num_entries << " entries: " + << PrettyMethod(method_verifier->GetMethodReference().dex_method_index, + *method_verifier->GetMethodReference().dex_file); return false; } size_t pc_bytes; @@ -105,10 +104,10 @@ bool VerifiedMethod::GenerateGcMap(verifier::MethodVerifier* method_verifier) { format = verifier::kRegMapFormatCompact16; pc_bytes = 2; } else { - // TODO: Either a better GC map format or per method failures. - method_verifier->Fail(verifier::VERIFY_ERROR_BAD_CLASS_HARD) - << "Cannot encode GC map for method with " - << (1 << pc_bits) << " instructions (number is rounded up to nearest power of 2)"; + LOG(WARNING) << "Cannot encode GC map for method with " + << (1 << pc_bits) << " instructions (number is rounded up to nearest power of 2): " + << PrettyMethod(method_verifier->GetMethodReference().dex_method_index, + *method_verifier->GetMethodReference().dex_file); return false; } size_t table_size = ((pc_bytes + ref_bitmap_bytes) * num_entries) + 4; @@ -161,7 +160,7 @@ void VerifiedMethod::VerifyGcMap(verifier::MethodVerifier* method_verifier, } } } else { - DCHECK(reg_bitmap == NULL); + DCHECK(i >= 65536 || reg_bitmap == NULL); } } } diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 051b310f89..cbb23c26b9 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -2120,8 +2120,12 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t } else if ((access_flags & kAccAbstract) != 0) { // Abstract methods don't have code. } else { + bool has_verified_method = verification_results_->GetVerifiedMethod(method_ref) != nullptr; bool compile = compilation_enabled && - verification_results_->IsCandidateForCompilation(method_ref, access_flags); + // Basic checks, e.g., not <clinit>. + verification_results_->IsCandidateForCompilation(method_ref, access_flags) && + // Did not fail to create VerifiedMethod metadata. + has_verified_method; if (compile) { // NOTE: if compiler declines to compile this method, it will return nullptr. compiled_method = compiler_->Compile(code_item, access_flags, invoke_type, class_def_idx, @@ -2129,10 +2133,12 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t } if (compiled_method == nullptr && dex_to_dex_compilation_level != kDontDexToDexCompile) { // TODO: add a command-line option to disable DEX-to-DEX compilation ? + // Do not optimize if a VerifiedMethod is missing. SafeCast elision, for example, relies on + // it. (*dex_to_dex_compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx, method_idx, class_loader, dex_file, - dex_to_dex_compilation_level); + has_verified_method ? dex_to_dex_compilation_level : kRequired); } } if (kTimeCompileMethod) { |