summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/class_linker.cc8
-rw-r--r--runtime/class_linker.h2
-rw-r--r--runtime/class_linker_test.cc38
-rw-r--r--runtime/dex_file.h1
-rw-r--r--runtime/mirror/dex_cache.cc6
-rw-r--r--runtime/mirror/dex_cache.h7
-rw-r--r--tools/libcore_failures.txt1
7 files changed, 54 insertions, 9 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 894cf67ccb..bb709e8774 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2927,19 +2927,19 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file,
CHECK(dex_cache.Get() != nullptr) << dex_file.GetLocation();
// For app images, the dex cache location may be a suffix of the dex file location since the
// dex file location is an absolute path.
- const size_t dex_cache_length = dex_cache->GetLocation()->GetLength();
+ const std::string dex_cache_location = dex_cache->GetLocation()->ToModifiedUtf8();
+ const size_t dex_cache_length = dex_cache_location.length();
CHECK_GT(dex_cache_length, 0u) << dex_file.GetLocation();
std::string dex_file_location = dex_file.GetLocation();
CHECK_GE(dex_file_location.length(), dex_cache_length)
- << dex_cache->GetLocation()->ToModifiedUtf8() << " " << dex_file.GetLocation();
+ << dex_cache_location << " " << dex_file.GetLocation();
// Take suffix.
const std::string dex_file_suffix = dex_file_location.substr(
dex_file_location.length() - dex_cache_length,
dex_cache_length);
// Example dex_cache location is SettingsProvider.apk and
// dex file location is /system/priv-app/SettingsProvider/SettingsProvider.apk
- CHECK(dex_cache->GetLocation()->Equals(dex_file_suffix))
- << dex_cache->GetLocation()->ToModifiedUtf8() << " " << dex_file.GetLocation();
+ CHECK_EQ(dex_cache_location, dex_file_suffix);
// Clean up pass to remove null dex caches.
// Null dex caches can occur due to class unloading and we are lazily removing null entries.
JavaVMExt* const vm = self->GetJniEnv()->vm;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index d503dd4704..4975c29742 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -1063,8 +1063,8 @@ class ClassLinker {
friend class ImageWriter; // for GetClassRoots
friend class JniCompilerTest; // for GetRuntimeQuickGenericJniStub
friend class JniInternalTest; // for GetRuntimeQuickGenericJniStub
+ ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName); // for DexLock, and RegisterDexFileLocked
ART_FRIEND_TEST(mirror::DexCacheTest, Open); // for AllocDexCache
-
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
};
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 471d7ca5e6..40dfda9316 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -1201,4 +1201,42 @@ TEST_F(ClassLinkerTest, IsBootStrapClassLoaded) {
EXPECT_FALSE(statics.Get()->IsBootStrapClassLoaded());
}
+// Regression test for b/26799552.
+TEST_F(ClassLinkerTest, RegisterDexFileName) {
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<2> hs(soa.Self());
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
+ {
+ ReaderMutexLock mu(soa.Self(), *class_linker->DexLock());
+ for (const ClassLinker::DexCacheData& data : class_linker->GetDexCachesData()) {
+ dex_cache.Assign(down_cast<mirror::DexCache*>(soa.Self()->DecodeJObject(data.weak_root)));
+ if (dex_cache.Get() != nullptr) {
+ break;
+ }
+ }
+ ASSERT_TRUE(dex_cache.Get() != nullptr);
+ }
+ // Make a copy of the dex cache and change the name.
+ dex_cache.Assign(dex_cache->Clone(soa.Self())->AsDexCache());
+ const uint16_t data[] = { 0x20AC, 0x20A1 };
+ Handle<mirror::String> location(hs.NewHandle(mirror::String::AllocFromUtf16(soa.Self(),
+ arraysize(data),
+ data)));
+ dex_cache->SetLocation(location.Get());
+ const DexFile* old_dex_file = dex_cache->GetDexFile();
+
+ DexFile* dex_file = new DexFile(old_dex_file->Begin(),
+ old_dex_file->Size(),
+ location->ToModifiedUtf8(),
+ 0u,
+ nullptr,
+ nullptr);
+ {
+ WriterMutexLock mu(soa.Self(), *class_linker->DexLock());
+ // Check that inserting with a UTF16 name works.
+ class_linker->RegisterDexFileLocked(*dex_file, dex_cache);
+ }
+}
+
} // namespace art
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 968b37ba86..200121e61f 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -1260,6 +1260,7 @@ class DexFile {
mutable std::unique_ptr<TypeLookupTable> lookup_table_;
friend class DexFileVerifierTest;
+ ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName); // for constructor
};
struct DexFileReference {
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index 7b058d0c92..692c6cb0c1 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -50,7 +50,7 @@ void DexCache::Init(const DexFile* dex_file,
CHECK_EQ(num_resolved_fields != 0u, resolved_fields != nullptr);
SetDexFile(dex_file);
- SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location);
+ SetLocation(location);
SetStrings(strings);
SetResolvedTypes(resolved_types);
SetResolvedMethods(resolved_methods);
@@ -79,5 +79,9 @@ void DexCache::Fixup(ArtMethod* trampoline, size_t pointer_size) {
}
}
+void DexCache::SetLocation(mirror::String* location) {
+ SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location);
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 5ed061f6a4..0002076ce0 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -191,11 +191,12 @@ class MANAGED DexCache FINAL : public Object {
return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
}
- void SetDexFile(const DexFile* dex_file) SHARED_REQUIRES(Locks::mutator_lock_)
- ALWAYS_INLINE {
- return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
+ void SetDexFile(const DexFile* dex_file) SHARED_REQUIRES(Locks::mutator_lock_) {
+ SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
}
+ void SetLocation(mirror::String* location) SHARED_REQUIRES(Locks::mutator_lock_);
+
// NOTE: Get/SetElementPtrSize() are intended for working with ArtMethod** and ArtField**
// provided by GetResolvedMethods/Fields() and ArtMethod::GetDexCacheResolvedMethods(),
// so they need to be public.
diff --git a/tools/libcore_failures.txt b/tools/libcore_failures.txt
index 351e99e8d4..6d67f8477d 100644
--- a/tools/libcore_failures.txt
+++ b/tools/libcore_failures.txt
@@ -260,6 +260,7 @@
"dalvik.system.JniTest#testPassingShorts",
"dalvik.system.JniTest#testPassingThis",
"libcore.util.NativeAllocationRegistryTest#testBadSize",
+ "libcore.util.NativeAllocationRegistryTest#testEarlyFree",
"libcore.util.NativeAllocationRegistryTest#testNativeAllocationAllocatorAndNoSharedRegistry",
"libcore.util.NativeAllocationRegistryTest#testNativeAllocationAllocatorAndSharedRegistry",
"libcore.util.NativeAllocationRegistryTest#testNativeAllocationNoAllocatorAndNoSharedRegistry",