diff options
Diffstat (limited to 'runtime/oat_file_manager.cc')
-rw-r--r-- | runtime/oat_file_manager.cc | 96 |
1 files changed, 26 insertions, 70 deletions
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 59a1045ba2..16e6cf375c 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -276,19 +276,9 @@ static void AddNext(/*inout*/DexFileAndClassPair& original, } } -static bool CheckClassCollision(const OatFile* oat_file, - const ClassLoaderContext* context, - std::string* error_msg /*out*/) { - std::vector<const DexFile*> dex_files_loaded = context->FlattenOpenedDexFiles(); - - // Vector that holds the newly opened dex files live, this is done to prevent leaks. - std::vector<std::unique_ptr<const DexFile>> opened_dex_files; - - ScopedTrace st("Collision check"); - // Add dex files from the oat file to check. - std::vector<const DexFile*> dex_files_unloaded; - AddDexFilesFromOat(oat_file, &dex_files_unloaded, &opened_dex_files); - +static bool CollisionCheck(std::vector<const DexFile*>& dex_files_loaded, + std::vector<const DexFile*>& dex_files_unloaded, + std::string* error_msg /*out*/) { // Generate type index information for each dex file. std::vector<TypeIndexInfo> loaded_types; for (const DexFile* dex_file : dex_files_loaded) { @@ -365,10 +355,9 @@ static bool CheckClassCollision(const OatFile* oat_file, // against the following top element. If the descriptor is the same, it is now checked whether // the two elements agree on whether their dex file was from an already-loaded oat-file or the // new oat file. Any disagreement indicates a collision. -OatFileManager::CheckCollisionResult OatFileManager::CheckCollision( - const OatFile* oat_file, - const ClassLoaderContext* context, - /*out*/ std::string* error_msg) const { +bool OatFileManager::HasCollisions(const OatFile* oat_file, + const ClassLoaderContext* context, + std::string* error_msg /*out*/) const { DCHECK(oat_file != nullptr); DCHECK(error_msg != nullptr); @@ -378,59 +367,28 @@ OatFileManager::CheckCollisionResult OatFileManager::CheckCollision( // Note that this has correctness implications as we cannot guarantee that the class resolution // used during compilation is OK (b/37777332). if (context == nullptr) { - LOG(WARNING) << "Skipping duplicate class check due to unsupported classloader"; - return CheckCollisionResult::kSkippedUnsupportedClassLoader; + LOG(WARNING) << "Skipping duplicate class check due to unsupported classloader"; + return false; } - // If the oat file loading context matches the context used during compilation then we accept + // If the pat file loading context matches the context used during compilation then we accept // the oat file without addition checks - ClassLoaderContext::VerificationResult result = context->VerifyClassLoaderContextMatch( - oat_file->GetClassLoaderContext(), - /*verify_names*/ true, - /*verify_checksums*/ true); - switch (result) { - case ClassLoaderContext::VerificationResult::kForcedToSkipChecks: - return CheckCollisionResult::kSkippedClassLoaderContextSharedLibrary; - case ClassLoaderContext::VerificationResult::kMismatch: - // Mismatched context, do the actual collision check. - break; - case ClassLoaderContext::VerificationResult::kVerifies: - return CheckCollisionResult::kNoCollisions; + if (context->VerifyClassLoaderContextMatch(oat_file->GetClassLoaderContext())) { + return false; } // The class loader context does not match. Perform a full duplicate classes check. - return CheckClassCollision(oat_file, context, error_msg) - ? CheckCollisionResult::kPerformedHasCollisions : CheckCollisionResult::kNoCollisions; -} -bool OatFileManager::AcceptOatFile(CheckCollisionResult result) const { - // Take the file only if it has no collisions, or we must take it because of preopting. - // Also accept oat files for shared libraries and unsupported class loaders. - return result != CheckCollisionResult::kPerformedHasCollisions; -} + std::vector<const DexFile*> dex_files_loaded = context->FlattenOpenedDexFiles(); -bool OatFileManager::ShouldLoadAppImage(CheckCollisionResult check_collision_result, - const OatFile* source_oat_file, - ClassLoaderContext* context, - std::string* error_msg) { - Runtime* const runtime = Runtime::Current(); - if (kEnableAppImage && (!runtime->IsJavaDebuggable() || source_oat_file->IsDebuggable())) { - // If we verified the class loader context (skipping due to the special marker doesn't - // count), then also avoid the collision check. - bool load_image = check_collision_result == CheckCollisionResult::kNoCollisions; - // If we skipped the collision check, we need to reverify to be sure its OK to load the - // image. - if (!load_image && - check_collision_result == - CheckCollisionResult::kSkippedClassLoaderContextSharedLibrary) { - // We can load the app image only if there are no collisions. If we know the - // class loader but didn't do the full collision check in HasCollisions(), - // do it now. b/77342775 - load_image = !CheckClassCollision(source_oat_file, context, error_msg); - } - return load_image; - } - return false; + // Vector that holds the newly opened dex files live, this is done to prevent leaks. + std::vector<std::unique_ptr<const DexFile>> opened_dex_files; + + ScopedTrace st("Collision check"); + // Add dex files from the oat file to check. + std::vector<const DexFile*> dex_files_unloaded; + AddDexFilesFromOat(oat_file, &dex_files_unloaded, &opened_dex_files); + return CollisionCheck(dex_files_loaded, dex_files_unloaded, error_msg); } std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( @@ -515,17 +473,16 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( << reinterpret_cast<uintptr_t>(oat_file.get()) << " (executable=" << (oat_file != nullptr ? oat_file->IsExecutable() : false) << ")"; - CheckCollisionResult check_collision_result = CheckCollisionResult::kPerformedHasCollisions; if ((class_loader != nullptr || dex_elements != nullptr) && oat_file != nullptr) { // Prevent oat files from being loaded if no class_loader or dex_elements are provided. // This can happen when the deprecated DexFile.<init>(String) is called directly, and it // could load oat files without checking the classpath, which would be incorrect. // Take the file only if it has no collisions, or we must take it because of preopting. - check_collision_result = CheckCollision(oat_file.get(), context.get(), /*out*/ &error_msg); - bool accept_oat_file = AcceptOatFile(check_collision_result); + bool accept_oat_file = + !HasCollisions(oat_file.get(), context.get(), /*out*/ &error_msg); if (!accept_oat_file) { // Failed the collision check. Print warning. - if (runtime->IsDexFileFallbackEnabled()) { + if (Runtime::Current()->IsDexFileFallbackEnabled()) { if (!oat_file_assistant.HasOriginalDexFiles()) { // We need to fallback but don't have original dex files. We have to // fallback to opening the existing oat file. This is potentially @@ -572,11 +529,10 @@ 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 (ShouldLoadAppImage(check_collision_result, - source_oat_file, - context.get(), - &error_msg)) { + if (kEnableAppImage && (!runtime->IsJavaDebuggable() || source_oat_file->IsDebuggable())) { image_space = oat_file_assistant.OpenImageSpace(source_oat_file); + } else { + image_space = nullptr; } if (image_space != nullptr) { ScopedObjectAccess soa(self); |