diff options
| -rw-r--r-- | dex2oat/dex2oat.cc | 5 | ||||
| -rw-r--r-- | runtime/common_throws.cc | 4 | ||||
| -rw-r--r-- | runtime/debug_print.cc | 46 | ||||
| -rw-r--r-- | runtime/debug_print.h | 3 | ||||
| -rw-r--r-- | runtime/jit/profile_compilation_info.h | 6 | ||||
| -rw-r--r-- | runtime/verifier/register_line-inl.h | 9 |
6 files changed, 69 insertions, 4 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 760147e62e..1e4ed58c8c 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -2516,7 +2516,10 @@ class Dex2Oat FINAL { compiler_options_.get(), oat_file.get())); elf_writers_.back()->Start(); - const bool do_oat_writer_layout = DoDexLayoutOptimizations() || DoOatLayoutOptimizations(); + bool do_oat_writer_layout = DoDexLayoutOptimizations() || DoOatLayoutOptimizations(); + if (profile_compilation_info_ != nullptr && profile_compilation_info_->IsEmpty()) { + do_oat_writer_layout = false; + } oat_writers_.emplace_back(new linker::OatWriter( IsBootImage(), timings_, diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc index 1b088e24f1..b72dc3ff4c 100644 --- a/runtime/common_throws.cc +++ b/runtime/common_throws.cc @@ -24,6 +24,7 @@ #include "art_field-inl.h" #include "art_method-inl.h" #include "class_linker-inl.h" +#include "debug_print.h" #include "dex/dex_file-inl.h" #include "dex/dex_instruction-inl.h" #include "dex/invoke_type.h" @@ -152,6 +153,7 @@ void ThrowWrappedBootstrapMethodError(const char* fmt, ...) { // ClassCastException void ThrowClassCastException(ObjPtr<mirror::Class> dest_type, ObjPtr<mirror::Class> src_type) { + DumpB77342775DebugData(dest_type, src_type); ThrowException("Ljava/lang/ClassCastException;", nullptr, StringPrintf("%s cannot be cast to %s", mirror::Class::PrettyDescriptor(src_type).c_str(), @@ -279,6 +281,7 @@ void ThrowIncompatibleClassChangeErrorClassForInterfaceSuper(ArtMethod* method, << "' does not implement interface '" << mirror::Class::PrettyDescriptor(target_class) << "' in call to '" << ArtMethod::PrettyMethod(method) << "'"; + DumpB77342775DebugData(target_class, this_object->GetClass()); ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, msg.str().c_str()); @@ -295,6 +298,7 @@ void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* inter << "' does not implement interface '" << mirror::Class::PrettyDescriptor(interface_method->GetDeclaringClass()) << "' in call to '" << ArtMethod::PrettyMethod(interface_method) << "'"; + DumpB77342775DebugData(interface_method->GetDeclaringClass(), this_object->GetClass()); ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, msg.str().c_str()); diff --git a/runtime/debug_print.cc b/runtime/debug_print.cc index 44a183669d..c7530bec6e 100644 --- a/runtime/debug_print.cc +++ b/runtime/debug_print.cc @@ -110,4 +110,50 @@ std::string DescribeLoaders(ObjPtr<mirror::ClassLoader> loader, const char* clas return oss.str(); } +void DumpB77342775DebugData(ObjPtr<mirror::Class> target_class, ObjPtr<mirror::Class> src_class) { + std::string target_descriptor_storage; + const char* target_descriptor = target_class->GetDescriptor(&target_descriptor_storage); + const char kCheckedPrefix[] = "Lorg/apache/http/"; + // Avoid spam for other packages. (That spam would break some ART run-tests for example.) + if (strncmp(target_descriptor, kCheckedPrefix, sizeof(kCheckedPrefix) - 1) != 0) { + return; + } + auto matcher = [target_descriptor, target_class](ObjPtr<mirror::Class> klass) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (klass->DescriptorEquals(target_descriptor)) { + LOG(ERROR) << " descriptor match in " + << DescribeLoaders(klass->GetClassLoader(), target_descriptor) + << " match? " << std::boolalpha << (klass == target_class); + } + }; + + std::string source_descriptor_storage; + const char* source_descriptor = src_class->GetDescriptor(&source_descriptor_storage); + + if (target_class->IsInterface()) { + ObjPtr<mirror::IfTable> iftable = src_class->GetIfTable(); + CHECK(iftable != nullptr); + size_t ifcount = iftable->Count(); + LOG(ERROR) << "Maybe bug 77342775, looking for " << target_descriptor + << " with loader " << DescribeLoaders(src_class->GetClassLoader(), target_descriptor) + << " in interface table for " << source_descriptor << " ifcount=" << ifcount; + for (size_t i = 0; i != ifcount; ++i) { + ObjPtr<mirror::Class> iface = iftable->GetInterface(i); + CHECK(iface != nullptr); + LOG(ERROR) << " iface #" << i << ": " << iface->PrettyDescriptor(); + matcher(iface); + } + } else { + LOG(ERROR) << "Maybe bug 77342775, looking for " << target_descriptor + << " with loader " << DescribeLoaders(src_class->GetClassLoader(), target_descriptor) + << " in superclass chain for " << source_descriptor; + for (ObjPtr<mirror::Class> klass = src_class; + klass != nullptr; + klass = klass->GetSuperClass()) { + LOG(ERROR) << " - " << klass->PrettyDescriptor(); + matcher(klass); + } + } +} + } // namespace art diff --git a/runtime/debug_print.h b/runtime/debug_print.h index 479c36a02f..df00f064bd 100644 --- a/runtime/debug_print.h +++ b/runtime/debug_print.h @@ -29,6 +29,9 @@ std::string DescribeSpace(ObjPtr<mirror::Class> klass) std::string DescribeLoaders(ObjPtr<mirror::ClassLoader> loader, const char* class_descriptor) REQUIRES_SHARED(Locks::mutator_lock_) COLD_ATTR; +void DumpB77342775DebugData(ObjPtr<mirror::Class> target_class, ObjPtr<mirror::Class> src_class) + REQUIRES_SHARED(Locks::mutator_lock_) COLD_ATTR; + } // namespace art #endif // ART_RUNTIME_DEBUG_PRINT_H_ diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h index 6c56db9f49..5c4b9e7202 100644 --- a/runtime/jit/profile_compilation_info.h +++ b/runtime/jit/profile_compilation_info.h @@ -439,6 +439,9 @@ class ProfileCompilationInfo { // the method returns false. Otherwise it returns true. bool UpdateProfileKeys(const std::vector<std::unique_ptr<const DexFile>>& dex_files); + // Checks if the profile is empty. + bool IsEmpty() const; + private: enum ProfileLoadStatus { kProfileLoadWouldOverwiteData, @@ -586,9 +589,6 @@ class ProfileCompilationInfo { // the key or the checksum mismatches. const DexFileData* FindDexData(const DexFile* dex_file) const; - // Checks if the profile is empty. - bool IsEmpty() const; - // Inflate the input buffer (in_buffer) of size in_size. It returns a buffer of // compressed data for the input buffer of "compressed_data_size" size. std::unique_ptr<uint8_t[]> DeflateBuffer(const uint8_t* in_buffer, diff --git a/runtime/verifier/register_line-inl.h b/runtime/verifier/register_line-inl.h index 39d73f54d8..5160daf42d 100644 --- a/runtime/verifier/register_line-inl.h +++ b/runtime/verifier/register_line-inl.h @@ -20,6 +20,7 @@ #include "register_line.h" #include "base/logging.h" // For VLOG. +#include "debug_print.h" #include "method_verifier.h" #include "reg_type_cache-inl.h" @@ -147,6 +148,14 @@ inline bool RegisterLine::VerifyRegisterType(MethodVerifier* verifier, uint32_t } verifier->Fail(fail_type) << "register v" << vsrc << " has type " << src_type << " but expected " << check_type; + if (check_type.IsNonZeroReferenceTypes() && + !check_type.IsUnresolvedTypes() && + check_type.HasClass() && + src_type.IsNonZeroReferenceTypes() && + !src_type.IsUnresolvedTypes() && + src_type.HasClass()) { + DumpB77342775DebugData(check_type.GetClass(), src_type.GetClass()); + } return false; } if (check_type.IsLowHalf()) { |