diff options
| -rw-r--r-- | runtime/native/dalvik_system_DexFile.cc | 2 | ||||
| -rw-r--r-- | runtime/oat_file_manager.cc | 30 | ||||
| -rw-r--r-- | test/131-structural-change/expected.txt | 1 | ||||
| -rw-r--r-- | test/131-structural-change/src/Main.java | 6 | ||||
| -rw-r--r-- | test/Android.run-test.mk | 10 |
5 files changed, 31 insertions, 18 deletions
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index e9ce02bd0d..8e6eae921a 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -74,7 +74,7 @@ static jlongArray ConvertDexFilesToJavaArray(JNIEnv* env, const OatFile* oat_file, std::vector<std::unique_ptr<const DexFile>>& vec) { // Add one for the oat file. - jlongArray long_array = env->NewLongArray(static_cast<jsize>(1u + vec.size())); + jlongArray long_array = env->NewLongArray(static_cast<jsize>(kDexFileIndexStart + vec.size())); if (env->ExceptionCheck() == JNI_TRUE) { return nullptr; } diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 3371a3955e..9eee156bb0 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -22,7 +22,7 @@ #include "base/logging.h" #include "base/stl_util.h" -#include "dex_file.h" +#include "dex_file-inl.h" #include "gc/space/image_space.h" #include "oat_file_assistant.h" #include "thread-inl.h" @@ -30,7 +30,9 @@ namespace art { // For b/21333911. -static constexpr bool kDuplicateClassesCheck = false; +// Only enabled for debug builds to prevent bit rot. There are too many performance regressions for +// normal builds. +static constexpr bool kDuplicateClassesCheck = kIsDebugBuild; const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) { WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); @@ -115,9 +117,9 @@ class DexFileAndClassPair : ValueObject { current_class_index_(current_class_index), from_loaded_oat_(from_loaded_oat) {} - DexFileAndClassPair(DexFileAndClassPair&& rhs) = default; + DexFileAndClassPair(const DexFileAndClassPair& rhs) = default; - DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) = default; + DexFileAndClassPair& operator=(const DexFileAndClassPair& rhs) = default; const char* GetCachedDescriptor() const { return cached_descriptor_; @@ -139,7 +141,7 @@ class DexFileAndClassPair : ValueObject { void Next() { ++current_class_index_; - cached_descriptor_ = nullptr; + cached_descriptor_ = GetClassDescriptor(dex_file_.get(), current_class_index_); } size_t GetCurrentClassIndex() const { @@ -162,7 +164,7 @@ class DexFileAndClassPair : ValueObject { } const char* cached_descriptor_; - std::unique_ptr<const DexFile> dex_file_; + std::shared_ptr<const DexFile> dex_file_; size_t current_class_index_; bool from_loaded_oat_; // We only need to compare mismatches between what we load now // and what was loaded before. Any old duplicates must have been @@ -215,8 +217,17 @@ bool OatFileManager::HasCollisions(const OatFile* oat_file, // Add dex files from already loaded oat files, but skip boot. const OatFile* boot_oat = GetBootOatFile(); + // The same OatFile can be loaded multiple times at different addresses. In this case, we don't + // need to check both against each other since they would have resolved the same way at compile + // time. + std::unordered_set<std::string> unique_locations; for (const std::unique_ptr<const OatFile>& loaded_oat_file : oat_files_) { - if (loaded_oat_file.get() != boot_oat) { + DCHECK_NE(loaded_oat_file.get(), oat_file); + const std::string& location = loaded_oat_file->GetLocation(); + if (loaded_oat_file.get() != boot_oat && + location != oat_file->GetLocation() && + unique_locations.find(location) == unique_locations.end()) { + unique_locations.insert(location); AddDexFilesFromOat(loaded_oat_file.get(), /*already_loaded*/true, &queue); } } @@ -232,12 +243,12 @@ bool OatFileManager::HasCollisions(const OatFile* oat_file, // Now drain the queue. while (!queue.empty()) { // Modifying the top element is only safe if we pop right after. - DexFileAndClassPair compare_pop(std::move(const_cast<DexFileAndClassPair&>(queue.top()))); + DexFileAndClassPair compare_pop(queue.top()); queue.pop(); // Compare against the following elements. while (!queue.empty()) { - DexFileAndClassPair top(std::move(const_cast<DexFileAndClassPair&>(queue.top()))); + DexFileAndClassPair top(queue.top()); if (strcmp(compare_pop.GetCachedDescriptor(), top.GetCachedDescriptor()) == 0) { // Same descriptor. Check whether it's crossing old-oat-files to new-oat-files. @@ -249,7 +260,6 @@ bool OatFileManager::HasCollisions(const OatFile* oat_file, top.GetDexFile()->GetLocation().c_str()); return true; } - // Pop it. queue.pop(); AddNext(&top, &queue); } else { diff --git a/test/131-structural-change/expected.txt b/test/131-structural-change/expected.txt index cc7713d252..1d19278f1e 100644 --- a/test/131-structural-change/expected.txt +++ b/test/131-structural-change/expected.txt @@ -1,2 +1,3 @@ +JNI_OnLoad called Should really reach here. Done. diff --git a/test/131-structural-change/src/Main.java b/test/131-structural-change/src/Main.java index 6cbbd12387..c7488992df 100644 --- a/test/131-structural-change/src/Main.java +++ b/test/131-structural-change/src/Main.java @@ -35,7 +35,7 @@ public class Main { e.printStackTrace(System.out); } - boolean haveOatFile = hasOat(); + boolean haveOatFile = hasOatFile(); boolean gotError = false; try { Class<?> bClass = getClass().getClassLoader().loadClass("B"); @@ -45,10 +45,10 @@ public class Main { e.printStackTrace(System.out); } if (haveOatFile ^ gotError) { - System.out.println("Did not get expected error."); + System.out.println("Did not get expected error. " + haveOatFile + " " + gotError); } System.out.println("Done."); } - private native static boolean hasOat(); + private native static boolean hasOatFile(); } diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index ad64b68ee2..6beead486a 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -324,13 +324,15 @@ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUIL $(PICTEST_TYPES),$(DEBUGGABLE_TYPES),130-hprof,$(ALL_ADDRESS_SIZES)) # 131 is an old test. The functionality has been implemented at an earlier stage and is checked -# in tests 138. -ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ +# in tests 138. Blacklisted for debug builds since these builds have duplicate classes checks which +# punt to interpreter. +ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),debug,$(PREBUILD_TYPES), \ $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \ $(PICTEST_TYPES),$(DEBUGGABLE_TYPES),131-structural-change,$(ALL_ADDRESS_SIZES)) -# 138-duplicate-classes-check. Turned off temporarily, b/21333911. -ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ +# 138-duplicate-classes-check. Turned on for debug builds since debug builds have duplicate classes +# checks enabled, b/2133391. +ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),ndebug,$(PREBUILD_TYPES), \ $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \ $(PICTEST_TYPES),$(DEBUGGABLE_TYPES),138-duplicate-classes-check,$(ALL_ADDRESS_SIZES)) |