diff options
author | 2021-03-29 08:49:38 +0100 | |
---|---|---|
committer | 2021-03-29 12:46:54 +0000 | |
commit | 982ecedecd2326f9b28ee60a3feb56b299e1c2bc (patch) | |
tree | d319249a25c0f13bab0bb45efd8cf70a4a238985 | |
parent | 09108b274c15b55d8577ae3590005e990694c5b7 (diff) |
Remove '&' class loader context.
This is now an unsupported context.
Test: class_loader_context
Bug: 132357300
Change-Id: I21bc6e3529944a57379845e90c7f49759db30d40
-rw-r--r-- | dex2oat/dex2oat_test.cc | 6 | ||||
-rw-r--r-- | runtime/class_loader_context.cc | 52 | ||||
-rw-r--r-- | runtime/class_loader_context.h | 8 | ||||
-rw-r--r-- | runtime/class_loader_context_test.cc | 62 | ||||
-rw-r--r-- | runtime/oat_file.h | 3 | ||||
-rw-r--r-- | runtime/oat_file_manager.cc | 10 | ||||
-rw-r--r-- | test/172-app-image-twice/run | 13 |
7 files changed, 11 insertions, 143 deletions
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index 7facbc0bfe..e92b81f12d 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -941,12 +941,6 @@ TEST_F(Dex2oatClassLoaderContextTest, EmptyContext) { RunTest("PCL[]", kEmptyClassPathKey, /*expected_success*/ true); } -TEST_F(Dex2oatClassLoaderContextTest, SpecialContext) { - RunTest(OatFile::kSpecialSharedLibrary, - OatFile::kSpecialSharedLibrary, - /*expected_success*/ true); -} - TEST_F(Dex2oatClassLoaderContextTest, ContextWithTheSourceDexFiles) { std::string context = "PCL[" + GetUsedDexLocation() + "]"; RunTest(context.c_str(), kEmptyClassPathKey, /*expected_success*/ true); diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc index 929cf8c31d..b5ce122c95 100644 --- a/runtime/class_loader_context.cc +++ b/runtime/class_loader_context.cc @@ -62,13 +62,11 @@ static constexpr char kDexFileChecksumSeparator = '*'; static constexpr char kInMemoryDexClassLoaderDexLocationMagic[] = "<unknown>"; ClassLoaderContext::ClassLoaderContext() - : special_shared_library_(false), - dex_files_state_(ContextDexFilesState::kDexFilesNotOpened), + : dex_files_state_(ContextDexFilesState::kDexFilesNotOpened), owns_the_dex_files_(true) {} ClassLoaderContext::ClassLoaderContext(bool owns_the_dex_files) - : special_shared_library_(false), - dex_files_state_(ContextDexFilesState::kDexFilesOpened), + : dex_files_state_(ContextDexFilesState::kDexFilesOpened), owns_the_dex_files_(owns_the_dex_files) {} // Utility method to add parent and shared libraries of `info` into @@ -317,15 +315,6 @@ bool ClassLoaderContext::Parse(const std::string& spec, bool parse_checksums) { return true; } - // Stop early if we detect the special shared library, which may be passed as the classpath - // for dex2oat when we want to skip the shared libraries check. - if (spec == OatFile::kSpecialSharedLibrary) { - // TODO(calin): move this out from parsing to the oat manager to prevent log spam. - VLOG(oat) << "The ClassLoaderContext is a special shared library."; - special_shared_library_ = true; - return true; - } - CHECK(class_loader_chain_ == nullptr); class_loader_chain_.reset(ParseInternal(spec, parse_checksums)); return class_loader_chain_ != nullptr; @@ -334,7 +323,6 @@ bool ClassLoaderContext::Parse(const std::string& spec, bool parse_checksums) { ClassLoaderContext::ClassLoaderInfo* ClassLoaderContext::ParseInternal( const std::string& spec, bool parse_checksums) { CHECK(!spec.empty()); - CHECK_NE(spec, OatFile::kSpecialSharedLibrary); std::string remaining = spec; std::unique_ptr<ClassLoaderInfo> first(nullptr); ClassLoaderInfo* previous_iteration = nullptr; @@ -418,11 +406,6 @@ bool ClassLoaderContext::OpenDexFiles(const std::string& classpath_dir, // Assume we can open the files. If not, we will adjust as we go. dex_files_state_ = only_read_checksums ? kDexFilesChecksumsRead : kDexFilesOpened; - if (special_shared_library_) { - // Nothing to open if the context is a special shared library. - return true; - } - // Note that we try to open all dex files even if some fail. // We may get resource-only apks which we cannot load. // TODO(calin): Refine the dex opening interface to be able to tell if an archive contains @@ -617,9 +600,6 @@ std::string ClassLoaderContext::EncodeContext(const std::string& base_dir, bool for_dex2oat, ClassLoaderContext* stored_context) const { CheckDexFilesOpened("EncodeContextForOatFile"); - if (special_shared_library_) { - return OatFile::kSpecialSharedLibrary; - } if (stored_context != nullptr) { DCHECK_EQ(GetParentChainSize(), stored_context->GetParentChainSize()); @@ -860,12 +840,7 @@ jobject ClassLoaderContext::CreateClassLoader( Thread* self = Thread::Current(); ScopedObjectAccess soa(self); - ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); - - if (class_loader_chain_ == nullptr) { - CHECK(special_shared_library_); - return class_linker->CreatePathClassLoader(self, compilation_sources); - } + CHECK(class_loader_chain_ != nullptr); // Create a map of canonicalized shared libraries. As we're holding objects, // we're creating a variable size handle scope to put handles in the map. @@ -1243,22 +1218,6 @@ ClassLoaderContext::VerificationResult ClassLoaderContext::VerifyClassLoaderCont return VerificationResult::kMismatch; } - // Special shared library contexts always match. They essentially instruct the runtime - // to ignore the class path check because the oat file is known to be loaded in different - // contexts. OatFileManager will further verify if the oat file can be loaded based on the - // collision check. - if (expected_context.special_shared_library_) { - // Special case where we are the only entry in the class path. - if (class_loader_chain_ != nullptr && - class_loader_chain_->parent == nullptr && - class_loader_chain_->classpath.size() == 0) { - return VerificationResult::kVerifies; - } - return VerificationResult::kForcedToSkipChecks; - } else if (special_shared_library_) { - return VerificationResult::kForcedToSkipChecks; - } - ClassLoaderInfo* info = class_loader_chain_.get(); ClassLoaderInfo* expected = expected_context.class_loader_chain_.get(); CHECK(info != nullptr); @@ -1410,11 +1369,10 @@ std::set<const DexFile*> ClassLoaderContext::CheckForDuplicateDexFiles( std::set<const DexFile*> result; - // If we are the special shared library or the chain is null there's nothing - // we can check, return an empty list; + // If the chain is null there's nothing we can check, return an empty list. // The class loader chain can be null if there were issues when creating the // class loader context (e.g. tests). - if (special_shared_library_ || class_loader_chain_ == nullptr) { + if (class_loader_chain_ == nullptr) { return result; } diff --git a/runtime/class_loader_context.h b/runtime/class_loader_context.h index 88e82dd285..33af16a225 100644 --- a/runtime/class_loader_context.h +++ b/runtime/class_loader_context.h @@ -39,7 +39,6 @@ class ClassLoaderContext { public: enum class VerificationResult { kVerifies, - kForcedToSkipChecks, kMismatch, }; @@ -365,13 +364,6 @@ class ClassLoaderContext { // The class loader chain. std::unique_ptr<ClassLoaderInfo> class_loader_chain_; - // Whether or not the class loader context should be ignored at runtime when loading the oat - // files. When true, dex2oat will use OatFile::kSpecialSharedLibrary as the classpath key in - // the oat file. - // TODO(calin): Can we get rid of this and cover all relevant use cases? - // (e.g. packages using prebuild system packages as shared libraries b/36480683) - bool special_shared_library_; - // The opening state of the dex files. ContextDexFilesState dex_files_state_; diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc index ec51dee06c..bf51ae3a0f 100644 --- a/runtime/class_loader_context_test.cc +++ b/runtime/class_loader_context_test.cc @@ -208,7 +208,6 @@ class ClassLoaderContextTest : public CommonRuntimeTest { ASSERT_TRUE(context != nullptr); ASSERT_EQ(context->dex_files_state_, ClassLoaderContext::ContextDexFilesState::kDexFilesOpened); ASSERT_FALSE(context->owns_the_dex_files_); - ASSERT_FALSE(context->special_shared_library_); } void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa, @@ -390,10 +389,10 @@ TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) { VerifyClassLoaderPCL(context.get(), 0, ""); } -TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) { +TEST_F(ClassLoaderContextTest, ParseInvalidSharedLibraryContext) { + // '&' used to be a special context. std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&"); - // An shared library context should have no class loader in the chain. - VerifyContextSize(context.get(), 0); + ASSERT_TRUE(context == nullptr); } TEST_F(ClassLoaderContextTest, ParseValidContextPCL) { @@ -486,12 +485,6 @@ TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) { VerifySharedLibrariesSize(context.get(), 0, 0); } -TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) { - std::unique_ptr<ClassLoaderContext> context = - ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary); - VerifyContextSize(context.get(), 0); -} - TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) { ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]")); ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL")); @@ -675,34 +668,6 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) { soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); } -TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) { - std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&"); - - ASSERT_TRUE(context->OpenDexFiles()); - - 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<1> hs(soa.Self()); - Handle<mirror::ClassLoader> class_loader = hs.NewHandle( - soa.Decode<mirror::ClassLoader>(jclass_loader)); - - // A shared library context should create a single PathClassLoader with only the compilation - // sources. - VerifyClassLoaderDexFiles(soa, - class_loader, - WellKnownClasses::dalvik_system_PathClassLoader, - compilation_sources_raw); - ASSERT_TRUE(class_loader->GetParent()->GetClass() == - soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); -} - TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) { // Setup the context. std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA"); @@ -1470,16 +1435,6 @@ TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) { VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA"); } -TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) { - std::string context_spec = "PCL[]"; - std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); - ASSERT_TRUE(context != nullptr); - PretendContextOpenedDexFilesForChecksums(context.get()); - // Ensure that the special shared library marks as verified for the first thing in the class path. - ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary), - ClassLoaderContext::VerificationResult::kVerifies); -} - TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) { std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]"; std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); @@ -1539,17 +1494,6 @@ TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) { ClassLoaderContext::VerificationResult::kVerifies); } -TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) { - std::string context_spec = "&"; - std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); - // Pretend that we successfully open the dex files to pass the DCHECKS. - // (as it's much easier to test all the corner cases without relying on actual dex files). - PretendContextOpenedDexFiles(context.get()); - - ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), - ClassLoaderContext::VerificationResult::kForcedToSkipChecks); -} - TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) { std::string context_spec = "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}" diff --git a/runtime/oat_file.h b/runtime/oat_file.h index bcb4d52821..7332cc9e89 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -94,9 +94,6 @@ class PACKED(4) OatMethodOffsets { class OatFile { public: - // Special classpath that skips shared library check. - static constexpr const char* kSpecialSharedLibrary = "&"; - // Open an oat file. Returns null on failure. // The `dex_filenames` argument, if provided, overrides the dex locations // from oat file when opening the dex files if they are not embedded in the diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 80afd91312..8547d543f1 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -179,7 +179,6 @@ std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles( static bool ClassLoaderContextMatches( const OatFile* oat_file, const ClassLoaderContext* context, - bool* is_special_shared_library, /*out*/ std::string* error_msg) { DCHECK(oat_file != nullptr); DCHECK(error_msg != nullptr); @@ -203,14 +202,9 @@ static bool ClassLoaderContextMatches( /*verify_names=*/ true, /*verify_checksums=*/ true); switch (result) { - case ClassLoaderContext::VerificationResult::kForcedToSkipChecks: - *is_special_shared_library = true; - return true; case ClassLoaderContext::VerificationResult::kMismatch: - *is_special_shared_library = false; return false; case ClassLoaderContext::VerificationResult::kVerifies: - *is_special_shared_library = false; return true; } LOG(FATAL) << "Unreachable"; @@ -287,14 +281,12 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( const OatFile* source_oat_file = nullptr; std::string error_msg; - bool is_special_shared_library = false; bool class_loader_context_matches = false; bool check_context = oat_file != nullptr && context != nullptr; if (check_context) { class_loader_context_matches = ClassLoaderContextMatches(oat_file.get(), context.get(), - /*out*/ &is_special_shared_library, /*out*/ &error_msg); } ScopedTrace context_results(StringPrintf( @@ -311,7 +303,7 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( // We need to throw away the image space if we are debuggable but the oat-file source of the // image is not otherwise we might get classes with inlined methods or other such things. std::unique_ptr<gc::space::ImageSpace> image_space; - if (!is_special_shared_library && ShouldLoadAppImage(oat_file.get())) { + if (ShouldLoadAppImage(oat_file.get())) { image_space = oat_file_assistant.OpenImageSpace(oat_file.get()); } if (image_space != nullptr) { diff --git a/test/172-app-image-twice/run b/test/172-app-image-twice/run index aa2819075f..2987b4b933 100644 --- a/test/172-app-image-twice/run +++ b/test/172-app-image-twice/run @@ -14,15 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Build an app image with TestClass (specified by profile) and class loader -# context that skips the duplicate class checks. +# Build an app image with TestClass (specified by profile). -# Target and host use a different shell, and we need to special case the -# passing of the class loader context marker. -if [[ "$@" = *" --host "* ]]; then - ${RUN} $@ --profile -Xcompiler-option --compiler-filter=speed-profile \ - -Xcompiler-option --class-loader-context=\& -else - ${RUN} $@ --profile -Xcompiler-option --compiler-filter=speed-profile \ - -Xcompiler-option '--class-loader-context=\&' -fi +${RUN} $@ --profile -Xcompiler-option --compiler-filter=speed-profile |