diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-10-05 20:03:33 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-10-05 20:03:33 +0000 |
commit | 779370939375d14923a63386f1e108e99f9c91e5 (patch) | |
tree | 9d4c8ea116aa3b11a360ce3ccb9d3fdedb5e24ea /runtime | |
parent | e4a73b63b76d8bedf782d2c708695f8e4c99b0b9 (diff) | |
parent | 02706fcb35325ba11825d575eb7278e3b9d6dfac (diff) | |
download | art-779370939375d14923a63386f1e108e99f9c91e5.tar.gz art-779370939375d14923a63386f1e108e99f9c91e5.tar.bz2 art-779370939375d14923a63386f1e108e99f9c91e5.zip |
am 02706fcb: Merge "Delete DexFiles in closeDexFiles"
* commit '02706fcb35325ba11825d575eb7278e3b9d6dfac':
Delete DexFiles in closeDexFiles
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/native/dalvik_system_DexFile.cc | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index 3b84bfa026..4aebc2c35f 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -192,28 +192,38 @@ static jobject DexFile_openDexFileNative( } } -static void DexFile_closeDexFile(JNIEnv* env, jclass, jobject cookie) { - std::unique_ptr<std::vector<const DexFile*>> dex_files = ConvertJavaArrayToNative(env, cookie); - if (dex_files.get() == nullptr) { - DCHECK(env->ExceptionCheck()); - return; - } - +static jboolean DexFile_closeDexFile(JNIEnv* env, jclass, jobject cookie) { ScopedObjectAccess soa(env); + mirror::Object* dex_files_object = soa.Decode<mirror::Object*>(cookie); + if (dex_files_object == nullptr) { + ThrowNullPointerException("cookie == null"); + return JNI_FALSE; + } + mirror::LongArray* dex_files = dex_files_object->AsLongArray(); - // The Runtime currently never unloads classes, which means any registered - // dex files must be kept around forever in case they are used. We - // accomplish this here by explicitly leaking those dex files that are - // registered. - // - // TODO: The Runtime should support unloading of classes and freeing of the - // dex files for those unloaded classes rather than leaking dex files here. + // Delete dex files associated with this dalvik.system.DexFile since there should not be running + // code using it. dex_files is a vector due to multidex. ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); - for (const DexFile* dex_file : *dex_files) { + bool all_deleted = true; + for (int32_t i = 0, count = dex_files->GetLength(); i < count; ++i) { + auto* dex_file = reinterpret_cast<DexFile*>(dex_files->Get(i)); + if (dex_file == nullptr) { + continue; + } + // Only delete the dex file if the dex cache is not found to prevent runtime crashes if there + // are calls to DexFile.close while the ART DexFile is still in use. if (class_linker->FindDexCache(soa.Self(), *dex_file, true) == nullptr) { + // Clear the element in the array so that we can call close again. + dex_files->Set(i, 0); delete dex_file; + } else { + all_deleted = false; } } + + // TODO: Also unmap the OatFile for this dalvik.system.DexFile. + + return all_deleted ? JNI_TRUE : JNI_FALSE; } static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, jobject javaLoader, @@ -379,7 +389,7 @@ static jboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename } static JNINativeMethod gMethods[] = { - NATIVE_METHOD(DexFile, closeDexFile, "(Ljava/lang/Object;)V"), + NATIVE_METHOD(DexFile, closeDexFile, "(Ljava/lang/Object;)Z"), NATIVE_METHOD(DexFile, defineClassNative, "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Object;)Ljava/lang/Class;"), NATIVE_METHOD(DexFile, getClassNameList, "(Ljava/lang/Object;)[Ljava/lang/String;"), |