summaryrefslogtreecommitdiffstats
path: root/runtime/common_runtime_test.h
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-05-21 18:46:59 -0700
committerAndreas Gampe <agampe@google.com>2014-06-25 19:34:58 -0700
commit833a48501d560c9fa7fc78ef619888138c2d374f (patch)
treeadd308298a5486d44caddea120cc9200dd70c38a /runtime/common_runtime_test.h
parentb849f6dd638fd1246724160cd5c01ab1a5ff33bd (diff)
downloadart-833a48501d560c9fa7fc78ef619888138c2d374f.tar.gz
art-833a48501d560c9fa7fc78ef619888138c2d374f.tar.bz2
art-833a48501d560c9fa7fc78ef619888138c2d374f.zip
ART: Native support for multidex
Native support for zip files with multiple classesX.dex. Works by explicitly looking for those files in ascending order. As these files have no file system representation for themselves, introduce synthetic dex locations: the name of the originating file plus a colon plus the name of the dex file, e.g., test.jar:classes2.dex. Opening a zip dex file will return all dex files in this way. This keeps the changes to dex2oat minimal. To hide multidex/synthetic names from the Java layer, let the handle of dalvik.system.DexFile refer to a vector of DexFile objects. When opening a location, test possible synthetic names and add them to the vector. Thus, the original multidex jar in the classpath will be associated with all embedded dex files. Change-Id: I0de107e1369cbc94416c544aca3b17525c9eac8b
Diffstat (limited to 'runtime/common_runtime_test.h')
-rw-r--r--runtime/common_runtime_test.h58
1 files changed, 38 insertions, 20 deletions
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 044d08b540..1df4c05e36 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -156,6 +156,18 @@ class CommonRuntimeTest : public testing::Test {
return !kIsTargetBuild;
}
+ const DexFile* LoadExpectSingleDexFile(const char* location) {
+ std::vector<const DexFile*> dex_files;
+ std::string error_msg;
+ if (!DexFile::Open(location, location, &error_msg, &dex_files)) {
+ LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
+ return nullptr;
+ } else {
+ CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
+ return dex_files[0];
+ }
+ }
+
virtual void SetUp() {
SetEnvironmentVariables(android_data_);
dalvik_cache_.append(android_data_.c_str());
@@ -164,12 +176,7 @@ class CommonRuntimeTest : public testing::Test {
ASSERT_EQ(mkdir_result, 0);
std::string error_msg;
- java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName().c_str(),
- GetLibCoreDexFileName().c_str(), &error_msg);
- if (java_lang_dex_file_ == nullptr) {
- LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "': "
- << error_msg << "\n";
- }
+ java_lang_dex_file_ = LoadExpectSingleDexFile(GetLibCoreDexFileName().c_str());
boot_class_path_.push_back(java_lang_dex_file_);
std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
@@ -233,7 +240,7 @@ class CommonRuntimeTest : public testing::Test {
// There's a function to clear the array, but it's not public...
typedef void (*IcuCleanupFn)();
void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
- CHECK(sym != nullptr);
+ CHECK(sym != nullptr) << dlerror();
IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
(*icu_cleanup_fn)();
@@ -264,7 +271,8 @@ class CommonRuntimeTest : public testing::Test {
return GetAndroidRoot();
}
- const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ std::vector<const DexFile*> OpenTestDexFiles(const char* name)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(name != nullptr);
std::string filename;
if (IsHost()) {
@@ -277,26 +285,36 @@ class CommonRuntimeTest : public testing::Test {
filename += name;
filename += ".jar";
std::string error_msg;
- const DexFile* dex_file = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg);
- CHECK(dex_file != nullptr) << "Failed to open '" << filename << "': " << error_msg;
- CHECK_EQ(PROT_READ, dex_file->GetPermissions());
- CHECK(dex_file->IsReadOnly());
- opened_dex_files_.push_back(dex_file);
- return dex_file;
+ std::vector<const DexFile*> dex_files;
+ bool success = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg, &dex_files);
+ CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
+ for (const DexFile* dex_file : dex_files) {
+ CHECK_EQ(PROT_READ, dex_file->GetPermissions());
+ CHECK(dex_file->IsReadOnly());
+ }
+ opened_dex_files_.insert(opened_dex_files_.end(), dex_files.begin(), dex_files.end());
+ return dex_files;
+ }
+
+ const DexFile* OpenTestDexFile(const char* name)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ std::vector<const DexFile*> vector = OpenTestDexFiles(name);
+ EXPECT_EQ(1U, vector.size());
+ return vector[0];
}
jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile* dex_file = OpenTestDexFile(dex_name);
- CHECK(dex_file != nullptr);
- class_linker_->RegisterDexFile(*dex_file);
- std::vector<const DexFile*> class_path;
- class_path.push_back(dex_file);
+ std::vector<const DexFile*> dex_files = OpenTestDexFiles(dex_name);
+ CHECK_NE(0U, dex_files.size());
+ for (const DexFile* dex_file : dex_files) {
+ class_linker_->RegisterDexFile(*dex_file);
+ }
ScopedObjectAccessUnchecked soa(Thread::Current());
ScopedLocalRef<jobject> class_loader_local(soa.Env(),
soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
- Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
+ Runtime::Current()->SetCompileTimeClassPath(class_loader, dex_files);
return class_loader;
}