Merge "Revert "Unload oat files""
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 370ea5c..9349fe3 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -41,20 +41,25 @@
#include "compiler_callbacks.h"
#include "debugger.h"
#include "dex_file-inl.h"
-#include "entrypoints/entrypoint_utils.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "gc_root-inl.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/accounting/heap_bitmap.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"
-#include "handle_scope-inl.h"
+#include "handle_scope.h"
#include "intern_table.h"
#include "interpreter/interpreter.h"
#include "jit/jit.h"
#include "jit/jit_code_cache.h"
#include "leb128.h"
#include "linear_alloc.h"
+#include "oat.h"
+#include "oat_file.h"
+#include "oat_file-inl.h"
+#include "oat_file_assistant.h"
+#include "oat_file_manager.h"
+#include "object_lock.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
@@ -68,17 +73,12 @@
#include "mirror/reference-inl.h"
#include "mirror/stack_trace_element.h"
#include "mirror/string-inl.h"
-#include "native/dalvik_system_DexFile.h"
-#include "oat.h"
-#include "oat_file.h"
-#include "oat_file-inl.h"
-#include "oat_file_assistant.h"
-#include "oat_file_manager.h"
-#include "object_lock.h"
#include "os.h"
#include "runtime.h"
+#include "entrypoints/entrypoint_utils.h"
#include "ScopedLocalRef.h"
#include "scoped_thread_state_change.h"
+#include "handle_scope-inl.h"
#include "thread-inl.h"
#include "trace.h"
#include "utils.h"
@@ -1429,18 +1429,13 @@
break;
}
int32_t long_array_size = long_array->GetLength();
- // First element is the oat file.
- for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
+ for (int32_t j = 0; j < long_array_size; ++j) {
const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
long_array->GetWithoutChecks(j)));
const DexFile::ClassDef* dex_class_def = cp_dex_file->FindClassDef(descriptor, hash);
if (dex_class_def != nullptr) {
- mirror::Class* klass = DefineClass(self,
- descriptor,
- hash,
- class_loader,
- *cp_dex_file,
- *dex_class_def);
+ mirror::Class* klass = DefineClass(self, descriptor, hash, class_loader,
+ *cp_dex_file, *dex_class_def);
if (klass == nullptr) {
CHECK(self->IsExceptionPending()) << descriptor;
self->ClearException();
@@ -5799,13 +5794,9 @@
for (const DexFile* dex_file : dex_files) {
StackHandleScope<3> hs2(self);
- // CreatePathClassLoader is only used by gtests. Index 0 of h_long_array is supposed to be the
- // oat file but we can leave it null.
- Handle<mirror::LongArray> h_long_array = hs2.NewHandle(mirror::LongArray::Alloc(
- self,
- kDexFileIndexStart + 1));
+ Handle<mirror::LongArray> h_long_array = hs2.NewHandle(mirror::LongArray::Alloc(self, 1));
DCHECK(h_long_array.Get() != nullptr);
- h_long_array->Set(kDexFileIndexStart, reinterpret_cast<intptr_t>(dex_file));
+ h_long_array->Set(0, reinterpret_cast<intptr_t>(dex_file));
Handle<mirror::Object> h_dex_file = hs2.NewHandle(
cookie_field->GetDeclaringClass()->AllocObject(self));
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index b6b5141..56c5d1a 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -42,7 +42,6 @@
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mem_map.h"
-#include "native/dalvik_system_DexFile.h"
#include "noop_compiler_callbacks.h"
#include "os.h"
#include "primitive.h"
@@ -517,7 +516,7 @@
mirror::LongArray* long_array = cookie_field->GetObject(dex_file)->AsLongArray();
DCHECK(long_array != nullptr);
int32_t long_array_size = long_array->GetLength();
- for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
+ for (int32_t j = 0; j < long_array_size; ++j) {
const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
long_array->GetWithoutChecks(j)));
if (cp_dex_file == nullptr) {
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 1a6bead..4850b6f 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -40,16 +40,13 @@
namespace art {
-static bool ConvertJavaArrayToDexFiles(
- JNIEnv* env,
- jobject arrayObject,
- /*out*/ std::vector<const DexFile*>& dex_files,
- /*out*/ const OatFile*& oat_file) {
+static std::unique_ptr<std::vector<const DexFile*>>
+ConvertJavaArrayToNative(JNIEnv* env, jobject arrayObject) {
jarray array = reinterpret_cast<jarray>(arrayObject);
jsize array_size = env->GetArrayLength(array);
if (env->ExceptionCheck() == JNI_TRUE) {
- return false;
+ return std::unique_ptr<std::vector<const DexFile*>>();
}
// TODO: Optimize. On 32bit we can use an int array.
@@ -57,24 +54,27 @@
jlong* long_data = env->GetLongArrayElements(reinterpret_cast<jlongArray>(array),
&is_long_data_copied);
if (env->ExceptionCheck() == JNI_TRUE) {
- return false;
+ return std::unique_ptr<std::vector<const DexFile*>>();
}
- oat_file = reinterpret_cast<const OatFile*>(static_cast<uintptr_t>(long_data[kOatFileIndex]));
- dex_files.reserve(array_size - 1);
- for (jsize i = kDexFileIndexStart; i < array_size; ++i) {
- dex_files.push_back(reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(long_data[i])));
+ std::unique_ptr<std::vector<const DexFile*>> ret(new std::vector<const DexFile*>());
+ ret->reserve(array_size);
+ for (jsize i = 0; i < array_size; ++i) {
+ ret->push_back(reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(*(long_data + i))));
}
env->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array), long_data, JNI_ABORT);
- return env->ExceptionCheck() != JNI_TRUE;
+ if (env->ExceptionCheck() == JNI_TRUE) {
+ return std::unique_ptr<std::vector<const DexFile*>>();
+ }
+
+ return ret;
}
-static jlongArray ConvertDexFilesToJavaArray(JNIEnv* env,
- const OatFile* oat_file,
- std::vector<std::unique_ptr<const DexFile>>& vec) {
- // Add one for the oat file.
- jlongArray long_array = env->NewLongArray(static_cast<jsize>(1u + vec.size()));
+static jlongArray ConvertNativeToJavaArray(JNIEnv* env,
+ std::vector<std::unique_ptr<const DexFile>>& vec) {
+ size_t vec_size = vec.size();
+ jlongArray long_array = env->NewLongArray(static_cast<jsize>(vec_size));
if (env->ExceptionCheck() == JNI_TRUE) {
return nullptr;
}
@@ -85,9 +85,10 @@
return nullptr;
}
- long_data[kOatFileIndex] = reinterpret_cast<uintptr_t>(oat_file);
- for (size_t i = 0; i < vec.size(); ++i) {
- long_data[kDexFileIndexStart + i] = reinterpret_cast<uintptr_t>(vec[i].get());
+ jlong* tmp = long_data;
+ for (auto& dex_file : vec) {
+ *tmp = reinterpret_cast<uintptr_t>(dex_file.get());
+ tmp++;
}
env->ReleaseLongArrayElements(long_array, long_data, 0);
@@ -164,15 +165,13 @@
ClassLinker* linker = runtime->GetClassLinker();
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::vector<std::string> error_msgs;
- const OatFile* oat_file = nullptr;
dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),
outputName.c_str(),
- /*out*/ &oat_file,
- /*out*/ &error_msgs);
+ &error_msgs);
if (!dex_files.empty()) {
- jlongArray array = ConvertDexFilesToJavaArray(env, oat_file, dex_files);
+ jlongArray array = ConvertNativeToJavaArray(env, dex_files);
if (array == nullptr) {
ScopedObjectAccess soa(env);
for (auto& dex_file : dex_files) {
@@ -198,54 +197,43 @@
}
static jboolean DexFile_closeDexFile(JNIEnv* env, jclass, jobject cookie) {
- std::vector<const DexFile*> dex_files;
- const OatFile* oat_file;
- if (!ConvertJavaArrayToDexFiles(env, cookie, dex_files, oat_file)) {
- Thread::Current()->AssertPendingException();
+ ScopedObjectAccess soa(env);
+ mirror::Object* dex_files_object = soa.Decode<mirror::Object*>(cookie);
+ if (dex_files_object == nullptr) {
+ ThrowNullPointerException("cookie == null");
return JNI_FALSE;
}
- Runtime* const runtime = Runtime::Current();
+ mirror::LongArray* dex_files = dex_files_object->AsLongArray();
+
+ // 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();
bool all_deleted = true;
- {
- ScopedObjectAccess soa(env);
- mirror::Object* dex_files_object = soa.Decode<mirror::Object*>(cookie);
- mirror::LongArray* long_dex_files = dex_files_object->AsLongArray();
- // 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->GetClassLinker();
- int32_t i = kDexFileIndexStart; // Oat file is at index 0.
- for (const DexFile* dex_file : dex_files) {
- if (dex_file != nullptr) {
- // 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.
- long_dex_files->Set(i, 0);
- delete dex_file;
- } else {
- all_deleted = false;
- }
- }
- ++i;
+ 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;
}
}
- if (all_deleted) {
- // If all of the dex files are no longer in use we can unmap the corresponding oat file.
- VLOG(class_linker) << "Unregistering " << oat_file;
- runtime->GetOatFileManager().UnRegisterAndDeleteOatFile(oat_file);
- }
+ // 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,
+static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, jobject javaLoader,
jobject cookie) {
- std::vector<const DexFile*> dex_files;
- const OatFile* oat_file;
- if (!ConvertJavaArrayToDexFiles(env, cookie, /*out*/ dex_files, /*out*/ oat_file)) {
+ std::unique_ptr<std::vector<const DexFile*>> dex_files = ConvertJavaArrayToNative(env, cookie);
+ if (dex_files.get() == nullptr) {
VLOG(class_linker) << "Failed to find dex_file";
DCHECK(env->ExceptionCheck());
return nullptr;
@@ -258,7 +246,7 @@
}
const std::string descriptor(DotToDescriptor(class_name.c_str()));
const size_t hash(ComputeModifiedUtf8Hash(descriptor.c_str()));
- for (auto& dex_file : dex_files) {
+ for (auto& dex_file : *dex_files) {
const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor.c_str(), hash);
if (dex_class_def != nullptr) {
ScopedObjectAccess soa(env);
@@ -267,12 +255,8 @@
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(javaLoader)));
- mirror::Class* result = class_linker->DefineClass(soa.Self(),
- descriptor.c_str(),
- hash,
- class_loader,
- *dex_file,
- *dex_class_def);
+ mirror::Class* result = class_linker->DefineClass(soa.Self(), descriptor.c_str(), hash,
+ class_loader, *dex_file, *dex_class_def);
if (result != nullptr) {
VLOG(class_linker) << "DexFile_defineClassNative returning " << result
<< " for " << class_name.c_str();
@@ -293,9 +277,8 @@
// Note: this can be an expensive call, as we sort out duplicates in MultiDex files.
static jobjectArray DexFile_getClassNameList(JNIEnv* env, jclass, jobject cookie) {
- const OatFile* oat_file = nullptr;
- std::vector<const DexFile*> dex_files;
- if (!ConvertJavaArrayToDexFiles(env, cookie, /*out */ dex_files, /* out */ oat_file)) {
+ std::unique_ptr<std::vector<const DexFile*>> dex_files = ConvertJavaArrayToNative(env, cookie);
+ if (dex_files.get() == nullptr) {
DCHECK(env->ExceptionCheck());
return nullptr;
}
@@ -303,7 +286,7 @@
// Push all class descriptors into a set. Use set instead of unordered_set as we want to
// retrieve all in the end.
std::set<const char*, CharPointerComparator> descriptors;
- for (auto& dex_file : dex_files) {
+ for (auto& dex_file : *dex_files) {
for (size_t i = 0; i < dex_file->NumClassDefs(); ++i) {
const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
const char* descriptor = dex_file->GetClassDescriptor(class_def);
@@ -312,8 +295,7 @@
}
// Now create output array and copy the set into it.
- jobjectArray result = env->NewObjectArray(descriptors.size(),
- WellKnownClasses::java_lang_String,
+ jobjectArray result = env->NewObjectArray(descriptors.size(), WellKnownClasses::java_lang_String,
nullptr);
if (result != nullptr) {
auto it = descriptors.begin();
@@ -331,11 +313,9 @@
return result;
}
-static jint GetDexOptNeeded(JNIEnv* env,
- const char* filename,
- const char* pkgname,
- const char* instruction_set,
- const jboolean defer) {
+static jint GetDexOptNeeded(JNIEnv* env, const char* filename,
+ const char* pkgname, const char* instruction_set, const jboolean defer) {
+
if ((filename == nullptr) || !OS::FileExists(filename)) {
LOG(ERROR) << "DexFile_getDexOptNeeded file '" << filename << "' does not exist";
ScopedLocalRef<jclass> fnfe(env, env->FindClass("java/io/FileNotFoundException"));
@@ -385,12 +365,8 @@
return oat_file_assistant.GetDexOptNeeded();
}
-static jint DexFile_getDexOptNeeded(JNIEnv* env,
- jclass,
- jstring javaFilename,
- jstring javaPkgname,
- jstring javaInstructionSet,
- jboolean defer) {
+static jint DexFile_getDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename,
+ jstring javaPkgname, jstring javaInstructionSet, jboolean defer) {
ScopedUtfChars filename(env, javaFilename);
if (env->ExceptionCheck()) {
return 0;
@@ -403,11 +379,8 @@
return 0;
}
- return GetDexOptNeeded(env,
- filename.c_str(),
- pkgname.c_str(),
- instruction_set.c_str(),
- defer);
+ return GetDexOptNeeded(env, filename.c_str(), pkgname.c_str(),
+ instruction_set.c_str(), defer);
}
// public API, null pkgname
diff --git a/runtime/native/dalvik_system_DexFile.h b/runtime/native/dalvik_system_DexFile.h
index 77d219d..7585ab9 100644
--- a/runtime/native/dalvik_system_DexFile.h
+++ b/runtime/native/dalvik_system_DexFile.h
@@ -18,13 +18,9 @@
#define ART_RUNTIME_NATIVE_DALVIK_SYSTEM_DEXFILE_H_
#include <jni.h>
-#include <unistd.h>
namespace art {
-constexpr size_t kOatFileIndex = 0;
-constexpr size_t kDexFileIndexStart = 1;
-
class DexFile;
void register_dalvik_system_DexFile(JNIEnv* env);
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index cef8702..de4e8ec 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -961,16 +961,13 @@
// we can verify only one oat file was loaded for the dex location.
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::vector<std::string> error_msgs;
- const OatFile* oat_file = nullptr;
dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
dex_location_.c_str(),
oat_location_.c_str(),
- &oat_file,
&error_msgs);
CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
- CHECK_EQ(loaded_oat_file_, oat_file);
}
const OatFile* GetLoadedOatFile() const {
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index f7a2943..73b065f 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -33,10 +33,9 @@
static constexpr bool kDuplicateClassesCheck = false;
const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) {
- WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
+ ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
DCHECK(oat_file != nullptr);
if (kIsDebugBuild) {
- CHECK(oat_files_.find(oat_file) == oat_files_.end());
for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
// Check that we don't have an oat file with the same address. Copies of the same oat file
@@ -45,19 +44,8 @@
}
}
have_non_pic_oat_file_ = have_non_pic_oat_file_ || !oat_file->IsPic();
- const OatFile* ret = oat_file.get();
- oat_files_.insert(std::move(oat_file));
- return ret;
-}
-
-void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
- WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
- DCHECK(oat_file != nullptr);
- std::unique_ptr<const OatFile> compare(oat_file);
- auto it = oat_files_.find(compare);
- CHECK(it != oat_files_.end());
- oat_files_.erase(it);
- compare.release();
+ oat_files_.push_back(std::move(oat_file));
+ return oat_files_.back().get();
}
const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
@@ -107,9 +95,17 @@
current_class_index_(current_class_index),
from_loaded_oat_(from_loaded_oat) {}
- DexFileAndClassPair(DexFileAndClassPair&& rhs) = default;
+ DexFileAndClassPair(DexFileAndClassPair&& rhs) {
+ *this = std::move(rhs);
+ }
- DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) = default;
+ DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) {
+ cached_descriptor_ = rhs.cached_descriptor_;
+ dex_file_ = std::move(rhs.dex_file_);
+ current_class_index_ = rhs.current_class_index_;
+ from_loaded_oat_ = rhs.from_loaded_oat_;
+ return *this;
+ }
const char* GetCachedDescriptor() const {
return cached_descriptor_;
@@ -131,7 +127,6 @@
void Next() {
++current_class_index_;
- cached_descriptor_ = nullptr;
}
size_t GetCurrentClassIndex() const {
@@ -258,7 +253,6 @@
std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
const char* dex_location,
const char* oat_location,
- const OatFile** out_oat_file,
std::vector<std::string>* error_msgs) {
CHECK(dex_location != nullptr);
CHECK(error_msgs != nullptr);
@@ -317,7 +311,6 @@
if (accept_oat_file) {
VLOG(class_linker) << "Registering " << oat_file->GetLocation();
source_oat_file = RegisterOatFile(std::move(oat_file));
- *out_oat_file = source_oat_file;
}
}
diff --git a/runtime/oat_file_manager.h b/runtime/oat_file_manager.h
index 0e4912b..3059cb5 100644
--- a/runtime/oat_file_manager.h
+++ b/runtime/oat_file_manager.h
@@ -18,7 +18,6 @@
#define ART_RUNTIME_OAT_FILE_MANAGER_H_
#include <memory>
-#include <set>
#include <string>
#include <vector>
@@ -50,9 +49,6 @@
const OatFile* RegisterOatFile(std::unique_ptr<const OatFile> oat_file)
REQUIRES(!Locks::oat_file_manager_lock_);
- void UnRegisterAndDeleteOatFile(const OatFile* oat_file)
- REQUIRES(!Locks::oat_file_manager_lock_);
-
// Find the first opened oat file with the same location, returns null if there are none.
const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location) const
REQUIRES(!Locks::oat_file_manager_lock_);
@@ -90,8 +86,7 @@
std::vector<std::unique_ptr<const DexFile>> OpenDexFilesFromOat(
const char* dex_location,
const char* oat_location,
- /*out*/ const OatFile** out_oat_file,
- /*out*/ std::vector<std::string>* error_msgs)
+ /*out*/std::vector<std::string>* error_msgs)
REQUIRES(!Locks::oat_file_manager_lock_, !Locks::mutator_lock_);
private:
@@ -100,7 +95,7 @@
bool HasCollisions(const OatFile* oat_file, /*out*/std::string* error_msg) const
REQUIRES(!Locks::oat_file_manager_lock_);
- std::set<std::unique_ptr<const OatFile>> oat_files_ GUARDED_BY(Locks::oat_file_manager_lock_);
+ std::vector<std::unique_ptr<const OatFile>> oat_files_ GUARDED_BY(Locks::oat_file_manager_lock_);
bool have_non_pic_oat_file_;
DISALLOW_COPY_AND_ASSIGN(OatFileManager);
};
diff --git a/test/141-class-unload/expected.txt b/test/141-class-unload/expected.txt
index 11de660..53d7abe 100644
--- a/test/141-class-unload/expected.txt
+++ b/test/141-class-unload/expected.txt
@@ -21,4 +21,3 @@
JNI_OnLoad called
class null false test
JNI_OnUnload called
-Number of loaded unload-ex maps 0
diff --git a/test/141-class-unload/src/Main.java b/test/141-class-unload/src/Main.java
index 0640b36..3cc43ac 100644
--- a/test/141-class-unload/src/Main.java
+++ b/test/141-class-unload/src/Main.java
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@@ -46,28 +43,11 @@
testStackTrace(constructor);
// Stress test to make sure we dont leak memory.
stressTest(constructor);
- // Test that the oat files are unloaded.
- testOatFilesUnloaded(getPid());
} catch (Exception e) {
System.out.println(e);
}
}
- private static void testOatFilesUnloaded(int pid) throws Exception {
- BufferedReader reader = new BufferedReader(new FileReader ("/proc/" + pid + "/maps"));
- String line;
- int count = 0;
- Runtime.getRuntime().gc();
- System.runFinalization();
- while ((line = reader.readLine()) != null) {
- if (line.contains("@141-class-unload-ex.jar")) {
- System.out.println(line);
- ++count;
- }
- }
- System.out.println("Number of loaded unload-ex maps " + count);
- }
-
private static void stressTest(Constructor constructor) throws Exception {
for (int i = 0; i <= 100; ++i) {
setUpUnloadLoader(constructor, false);
@@ -183,8 +163,4 @@
loadLibrary.invoke(intHolder, nativeLibraryName);
return new WeakReference(loader);
}
-
- private static int getPid() throws Exception {
- return Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
- }
}