Move dex files dependencies (en/de)coding to ClassLoaderContext
Encode the full class loader context in the oat file (rather than just a
list of dex files).
The context encoding matches the format used by dex2oat with the addition
of checksums.
Temporarily assert that at decoding time we are operating on a
PathClassLoader until the checking logic covers all supported cases.
Also, bump the version of the oat file because the format of the classpath
key has changed.
This is a transition step to minimize the size of follow up changes.
Test: m test-art-host
Bug: 38138251
Change-Id: I9ec0cfe092ce1afccb741a36e737896880d5f1d2
diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc
index 4643e78..03eb0e4 100644
--- a/runtime/class_loader_context_test.cc
+++ b/runtime/class_loader_context_test.cc
@@ -230,6 +230,42 @@
}
}
+TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
+ std::unique_ptr<ClassLoaderContext> context =
+ ClassLoaderContext::Create("");
+ ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
+
+ std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
+
+ std::vector<const DexFile*> compilation_sources_raw =
+ MakeNonOwningPointerVector(compilation_sources);
+ jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
+ ASSERT_TRUE(jclass_loader != nullptr);
+
+ ScopedObjectAccess soa(Thread::Current());
+
+ StackHandleScope<2> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
+ soa.Decode<mirror::ClassLoader>(jclass_loader));
+
+ ASSERT_TRUE(class_loader->GetClass() ==
+ soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
+ ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
+ soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
+
+
+ std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(jclass_loader);
+
+ // The compilation sources should be the only files present in the class loader
+ ASSERT_EQ(compilation_sources.size(), class_loader_dex_files.size());
+ for (size_t i = 0; i < compilation_sources.size(); i++) {
+ ASSERT_EQ(compilation_sources[i]->GetLocation(),
+ class_loader_dex_files[i]->GetLocation());
+ ASSERT_EQ(compilation_sources[i]->GetLocationChecksum(),
+ class_loader_dex_files[i]->GetLocationChecksum());
+ }
+}
+
TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
std::unique_ptr<ClassLoaderContext> context =
ClassLoaderContext::Create("PCL[a.dex]");
@@ -256,10 +292,46 @@
std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
std::string encoding = context->EncodeContextForOatFile("");
- std::string expected_encoding =
- dex1[0]->GetLocation() + "*" + std::to_string(dex1[0]->GetLocationChecksum()) + "*" +
- dex2[0]->GetLocation() + "*" + std::to_string(dex2[0]->GetLocationChecksum()) + "*";
+ std::string expected_encoding = "PCL[" +
+ dex1[0]->GetLocation() + "*" + std::to_string(dex1[0]->GetLocationChecksum()) + ":" +
+ dex2[0]->GetLocation() + "*" + std::to_string(dex2[0]->GetLocationChecksum()) + "]";
ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
}
+TEST_F(ClassLoaderContextTest, DecodeOatFileKey) {
+ std::string oat_file_encoding = "PCL[a.dex*123:b.dex*456]";
+ std::vector<std::string> classpath;
+ std::vector<uint32_t> checksums;
+ bool is_special_shared_library;
+ bool result = ClassLoaderContext::DecodePathClassLoaderContextFromOatFileKey(
+ oat_file_encoding,
+ &classpath,
+ &checksums,
+ &is_special_shared_library);
+ ASSERT_TRUE(result);
+ ASSERT_FALSE(is_special_shared_library);
+ ASSERT_EQ(2u, classpath.size());
+ ASSERT_EQ(2u, checksums.size());
+ ASSERT_EQ("a.dex", classpath[0]);
+ ASSERT_EQ(123u, checksums[0]);
+ ASSERT_EQ("b.dex", classpath[1]);
+ ASSERT_EQ(456u, checksums[1]);
+}
+
+TEST_F(ClassLoaderContextTest, DecodeOatFileKeySpecialLibrary) {
+ std::string oat_file_encoding = "&";
+ std::vector<std::string> classpath;
+ std::vector<uint32_t> checksums;
+ bool is_special_shared_library;
+ bool result = ClassLoaderContext::DecodePathClassLoaderContextFromOatFileKey(
+ oat_file_encoding,
+ &classpath,
+ &checksums,
+ &is_special_shared_library);
+ ASSERT_TRUE(result);
+ ASSERT_TRUE(is_special_shared_library);
+ ASSERT_TRUE(classpath.empty());
+ ASSERT_TRUE(checksums.empty());
+}
+
} // namespace art