Remove '&' class loader context.
This is now an unsupported context.
Test: class_loader_context
Bug: 132357300
Change-Id: I21bc6e3529944a57379845e90c7f49759db30d40
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 7facbc0..e92b81f 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -941,12 +941,6 @@
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 929cf8c..b5ce122 100644
--- a/runtime/class_loader_context.cc
+++ b/runtime/class_loader_context.cc
@@ -62,13 +62,11 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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*> 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 88e82dd..33af16a 100644
--- a/runtime/class_loader_context.h
+++ b/runtime/class_loader_context.h
@@ -39,7 +39,6 @@
public:
enum class VerificationResult {
kVerifies,
- kForcedToSkipChecks,
kMismatch,
};
@@ -365,13 +364,6 @@
// 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 ec51dee..bf51ae3 100644
--- a/runtime/class_loader_context_test.cc
+++ b/runtime/class_loader_context_test.cc
@@ -208,7 +208,6 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 bcb4d52..7332cc9 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -94,9 +94,6 @@
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 80afd91..8547d54 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -179,7 +179,6 @@
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 @@
/*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 @@
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 @@
// 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 aa28190..2987b4b 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