Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "common_runtime_test.h"
     18 
     19 #include <dirent.h>
     20 #include <dlfcn.h>
     21 #include <fcntl.h>
     22 #include <stdlib.h>
     23 #include <cstdio>
     24 #include "nativehelper/scoped_local_ref.h"
     25 
     26 #include "android-base/stringprintf.h"
     27 #include <unicode/uvernum.h>
     28 
     29 #include "art_field-inl.h"
     30 #include "base/file_utils.h"
     31 #include "base/logging.h"
     32 #include "base/macros.h"
     33 #include "base/mutex.h"
     34 #include "base/os.h"
     35 #include "base/runtime_debug.h"
     36 #include "base/stl_util.h"
     37 #include "base/unix_file/fd_file.h"
     38 #include "class_linker.h"
     39 #include "class_loader_utils.h"
     40 #include "compiler_callbacks.h"
     41 #include "dex/art_dex_file_loader.h"
     42 #include "dex/dex_file-inl.h"
     43 #include "dex/dex_file_loader.h"
     44 #include "dex/primitive.h"
     45 #include "gc/heap.h"
     46 #include "gc_root-inl.h"
     47 #include "gtest/gtest.h"
     48 #include "handle_scope-inl.h"
     49 #include "interpreter/unstarted_runtime.h"
     50 #include "java_vm_ext.h"
     51 #include "jni_internal.h"
     52 #include "mem_map.h"
     53 #include "mirror/class-inl.h"
     54 #include "mirror/class_loader.h"
     55 #include "native/dalvik_system_DexFile.h"
     56 #include "noop_compiler_callbacks.h"
     57 #include "runtime-inl.h"
     58 #include "scoped_thread_state_change-inl.h"
     59 #include "thread.h"
     60 #include "well_known_classes.h"
     61 
     62 int main(int argc, char **argv) {
     63   // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
     64   // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
     65   // everything else. In case you want to see all messages, comment out the line.
     66   setenv("ANDROID_LOG_TAGS", "*:e", 1);
     67 
     68   art::Locks::Init();
     69   art::InitLogging(argv, art::Runtime::Abort);
     70   LOG(INFO) << "Running main() from common_runtime_test.cc...";
     71   testing::InitGoogleTest(&argc, argv);
     72   return RUN_ALL_TESTS();
     73 }
     74 
     75 namespace art {
     76 
     77 using android::base::StringPrintf;
     78 
     79 ScratchFile::ScratchFile() {
     80   // ANDROID_DATA needs to be set
     81   CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
     82       "Are you subclassing RuntimeTest?";
     83   filename_ = getenv("ANDROID_DATA");
     84   filename_ += "/TmpFile-XXXXXX";
     85   int fd = mkstemp(&filename_[0]);
     86   CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
     87   file_.reset(new File(fd, GetFilename(), true));
     88 }
     89 
     90 ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
     91     : ScratchFile(other.GetFilename() + suffix) {}
     92 
     93 ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
     94   int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
     95   CHECK_NE(-1, fd);
     96   file_.reset(new File(fd, GetFilename(), true));
     97 }
     98 
     99 ScratchFile::ScratchFile(File* file) {
    100   CHECK(file != nullptr);
    101   filename_ = file->GetPath();
    102   file_.reset(file);
    103 }
    104 
    105 ScratchFile::ScratchFile(ScratchFile&& other) {
    106   *this = std::move(other);
    107 }
    108 
    109 ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
    110   if (GetFile() != other.GetFile()) {
    111     std::swap(filename_, other.filename_);
    112     std::swap(file_, other.file_);
    113   }
    114   return *this;
    115 }
    116 
    117 ScratchFile::~ScratchFile() {
    118   Unlink();
    119 }
    120 
    121 int ScratchFile::GetFd() const {
    122   return file_->Fd();
    123 }
    124 
    125 void ScratchFile::Close() {
    126   if (file_.get() != nullptr) {
    127     if (file_->FlushCloseOrErase() != 0) {
    128       PLOG(WARNING) << "Error closing scratch file.";
    129     }
    130   }
    131 }
    132 
    133 void ScratchFile::Unlink() {
    134   if (!OS::FileExists(filename_.c_str())) {
    135     return;
    136   }
    137   Close();
    138   int unlink_result = unlink(filename_.c_str());
    139   CHECK_EQ(0, unlink_result);
    140 }
    141 
    142 static bool unstarted_initialized_ = false;
    143 
    144 CommonRuntimeTestImpl::CommonRuntimeTestImpl()
    145     : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
    146 }
    147 
    148 CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
    149   // Ensure the dex files are cleaned up before the runtime.
    150   loaded_dex_files_.clear();
    151   runtime_.reset();
    152 }
    153 
    154 void CommonRuntimeTestImpl::SetUpAndroidRoot() {
    155   if (IsHost()) {
    156     // $ANDROID_ROOT is set on the device, but not necessarily on the host.
    157     // But it needs to be set so that icu4c can find its locale data.
    158     const char* android_root_from_env = getenv("ANDROID_ROOT");
    159     if (android_root_from_env == nullptr) {
    160       // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
    161       const char* android_host_out = getenv("ANDROID_HOST_OUT");
    162       if (android_host_out != nullptr) {
    163         setenv("ANDROID_ROOT", android_host_out, 1);
    164       } else {
    165         // Build it from ANDROID_BUILD_TOP or cwd
    166         std::string root;
    167         const char* android_build_top = getenv("ANDROID_BUILD_TOP");
    168         if (android_build_top != nullptr) {
    169           root += android_build_top;
    170         } else {
    171           // Not set by build server, so default to current directory
    172           char* cwd = getcwd(nullptr, 0);
    173           setenv("ANDROID_BUILD_TOP", cwd, 1);
    174           root += cwd;
    175           free(cwd);
    176         }
    177 #if defined(__linux__)
    178         root += "/out/host/linux-x86";
    179 #elif defined(__APPLE__)
    180         root += "/out/host/darwin-x86";
    181 #else
    182 #error unsupported OS
    183 #endif
    184         setenv("ANDROID_ROOT", root.c_str(), 1);
    185       }
    186     }
    187     setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
    188 
    189     // Not set by build server, so default
    190     if (getenv("ANDROID_HOST_OUT") == nullptr) {
    191       setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
    192     }
    193   }
    194 }
    195 
    196 void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
    197   // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
    198   if (IsHost()) {
    199     const char* tmpdir = getenv("TMPDIR");
    200     if (tmpdir != nullptr && tmpdir[0] != 0) {
    201       android_data = tmpdir;
    202     } else {
    203       android_data = "/tmp";
    204     }
    205   } else {
    206     android_data = "/data/dalvik-cache";
    207   }
    208   android_data += "/art-data-XXXXXX";
    209   if (mkdtemp(&android_data[0]) == nullptr) {
    210     PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
    211   }
    212   setenv("ANDROID_DATA", android_data.c_str(), 1);
    213 }
    214 
    215 void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
    216                                                 bool fail_on_error) {
    217   if (fail_on_error) {
    218     ASSERT_EQ(rmdir(android_data.c_str()), 0);
    219   } else {
    220     rmdir(android_data.c_str());
    221   }
    222 }
    223 
    224 // Helper - find directory with the following format:
    225 // ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
    226 static std::string GetAndroidToolsDir(const std::string& subdir1,
    227                                       const std::string& subdir2,
    228                                       const std::string& subdir3) {
    229   std::string root;
    230   const char* android_build_top = getenv("ANDROID_BUILD_TOP");
    231   if (android_build_top != nullptr) {
    232     root = android_build_top;
    233   } else {
    234     // Not set by build server, so default to current directory
    235     char* cwd = getcwd(nullptr, 0);
    236     setenv("ANDROID_BUILD_TOP", cwd, 1);
    237     root = cwd;
    238     free(cwd);
    239   }
    240 
    241   std::string toolsdir = root + "/" + subdir1;
    242   std::string founddir;
    243   DIR* dir;
    244   if ((dir = opendir(toolsdir.c_str())) != nullptr) {
    245     float maxversion = 0;
    246     struct dirent* entry;
    247     while ((entry = readdir(dir)) != nullptr) {
    248       std::string format = subdir2 + "-%f";
    249       float version;
    250       if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
    251         if (version > maxversion) {
    252           maxversion = version;
    253           founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
    254         }
    255       }
    256     }
    257     closedir(dir);
    258   }
    259 
    260   if (founddir.empty()) {
    261     ADD_FAILURE() << "Cannot find Android tools directory.";
    262   }
    263   return founddir;
    264 }
    265 
    266 std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
    267   return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
    268                             "x86_64-linux-glibc2.15",
    269                             "x86_64-linux");
    270 }
    271 
    272 std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
    273   switch (isa) {
    274     case InstructionSet::kArm:
    275     case InstructionSet::kThumb2:
    276       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
    277                                 "arm-linux-androideabi",
    278                                 "arm-linux-androideabi");
    279     case InstructionSet::kArm64:
    280       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
    281                                 "aarch64-linux-android",
    282                                 "aarch64-linux-android");
    283     case InstructionSet::kX86:
    284     case InstructionSet::kX86_64:
    285       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
    286                                 "x86_64-linux-android",
    287                                 "x86_64-linux-android");
    288     case InstructionSet::kMips:
    289     case InstructionSet::kMips64:
    290       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
    291                                 "mips64el-linux-android",
    292                                 "mips64el-linux-android");
    293     case InstructionSet::kNone:
    294       break;
    295   }
    296   ADD_FAILURE() << "Invalid isa " << isa;
    297   return "";
    298 }
    299 
    300 std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
    301   return GetCoreFileLocation("art");
    302 }
    303 
    304 std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
    305   return GetCoreFileLocation("oat");
    306 }
    307 
    308 std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
    309     const char* location) {
    310   std::vector<std::unique_ptr<const DexFile>> dex_files;
    311   std::string error_msg;
    312   MemMap::Init();
    313   static constexpr bool kVerifyChecksum = true;
    314   const ArtDexFileLoader dex_file_loader;
    315   if (!dex_file_loader.Open(
    316         location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files)) {
    317     LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
    318     UNREACHABLE();
    319   } else {
    320     CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
    321     return std::move(dex_files[0]);
    322   }
    323 }
    324 
    325 void CommonRuntimeTestImpl::SetUp() {
    326   SetUpAndroidRoot();
    327   SetUpAndroidData(android_data_);
    328   dalvik_cache_.append(android_data_.c_str());
    329   dalvik_cache_.append("/dalvik-cache");
    330   int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
    331   ASSERT_EQ(mkdir_result, 0);
    332 
    333   std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
    334   std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
    335 
    336 
    337   RuntimeOptions options;
    338   std::string boot_class_path_string = "-Xbootclasspath";
    339   for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
    340     boot_class_path_string += ":";
    341     boot_class_path_string += core_dex_file_name;
    342   }
    343 
    344   options.push_back(std::make_pair(boot_class_path_string, nullptr));
    345   options.push_back(std::make_pair("-Xcheck:jni", nullptr));
    346   options.push_back(std::make_pair(min_heap_string, nullptr));
    347   options.push_back(std::make_pair(max_heap_string, nullptr));
    348   options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
    349   static bool gSlowDebugTestFlag = false;
    350   RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
    351 
    352   callbacks_.reset(new NoopCompilerCallbacks());
    353 
    354   SetUpRuntimeOptions(&options);
    355 
    356   // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
    357   if (callbacks_.get() != nullptr) {
    358     options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
    359   }
    360 
    361   PreRuntimeCreate();
    362   if (!Runtime::Create(options, false)) {
    363     LOG(FATAL) << "Failed to create runtime";
    364     return;
    365   }
    366   PostRuntimeCreate();
    367   runtime_.reset(Runtime::Current());
    368   class_linker_ = runtime_->GetClassLinker();
    369 
    370   // Runtime::Create acquired the mutator_lock_ that is normally given away when we
    371   // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
    372   Thread::Current()->TransitionFromRunnableToSuspended(kNative);
    373 
    374   // Get the boot class path from the runtime so it can be used in tests.
    375   boot_class_path_ = class_linker_->GetBootClassPath();
    376   ASSERT_FALSE(boot_class_path_.empty());
    377   java_lang_dex_file_ = boot_class_path_[0];
    378 
    379   FinalizeSetup();
    380 
    381   // Ensure that we're really running with debug checks enabled.
    382   CHECK(gSlowDebugTestFlag);
    383 }
    384 
    385 void CommonRuntimeTestImpl::FinalizeSetup() {
    386   // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
    387   // set up.
    388   if (!unstarted_initialized_) {
    389     interpreter::UnstartedRuntime::Initialize();
    390     unstarted_initialized_ = true;
    391   }
    392 
    393   {
    394     ScopedObjectAccess soa(Thread::Current());
    395     class_linker_->RunRootClinits();
    396   }
    397 
    398   // We're back in native, take the opportunity to initialize well known classes.
    399   WellKnownClasses::Init(Thread::Current()->GetJniEnv());
    400 
    401   // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
    402   // pool is created by the runtime.
    403   runtime_->GetHeap()->CreateThreadPool();
    404   runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
    405   // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
    406   runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
    407 }
    408 
    409 void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
    410   ASSERT_TRUE(dirpath != nullptr);
    411   DIR* dir = opendir(dirpath);
    412   ASSERT_TRUE(dir != nullptr);
    413   dirent* e;
    414   struct stat s;
    415   while ((e = readdir(dir)) != nullptr) {
    416     if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
    417       continue;
    418     }
    419     std::string filename(dirpath);
    420     filename.push_back('/');
    421     filename.append(e->d_name);
    422     int stat_result = lstat(filename.c_str(), &s);
    423     ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
    424     if (S_ISDIR(s.st_mode)) {
    425       if (recursive) {
    426         ClearDirectory(filename.c_str());
    427         int rmdir_result = rmdir(filename.c_str());
    428         ASSERT_EQ(0, rmdir_result) << filename;
    429       }
    430     } else {
    431       int unlink_result = unlink(filename.c_str());
    432       ASSERT_EQ(0, unlink_result) << filename;
    433     }
    434   }
    435   closedir(dir);
    436 }
    437 
    438 void CommonRuntimeTestImpl::TearDown() {
    439   const char* android_data = getenv("ANDROID_DATA");
    440   ASSERT_TRUE(android_data != nullptr);
    441   ClearDirectory(dalvik_cache_.c_str());
    442   int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
    443   ASSERT_EQ(0, rmdir_cache_result);
    444   TearDownAndroidData(android_data_, true);
    445   dalvik_cache_.clear();
    446 
    447   if (runtime_ != nullptr) {
    448     runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
    449   }
    450 }
    451 
    452 static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
    453   std::string path;
    454   if (host) {
    455     const char* host_dir = getenv("ANDROID_HOST_OUT");
    456     CHECK(host_dir != nullptr);
    457     path = host_dir;
    458   } else {
    459     path = GetAndroidRoot();
    460   }
    461 
    462   std::string suffix = host
    463       ? "-hostdex"                 // The host version.
    464       : "-testdex";                // The unstripped target version.
    465 
    466   return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
    467 }
    468 
    469 std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
    470   return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
    471                                    GetDexFileName("core-libart", IsHost())});
    472 }
    473 
    474 std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
    475   if (IsHost()) {
    476     const char* host_dir = getenv("ANDROID_HOST_OUT");
    477     CHECK(host_dir != nullptr);
    478     return host_dir;
    479   }
    480   return GetAndroidRoot();
    481 }
    482 
    483 // Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
    484 #ifdef ART_TARGET
    485 #ifndef ART_TARGET_NATIVETEST_DIR
    486 #error "ART_TARGET_NATIVETEST_DIR not set."
    487 #endif
    488 // Wrap it as a string literal.
    489 #define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
    490 #else
    491 #define ART_TARGET_NATIVETEST_DIR_STRING ""
    492 #endif
    493 
    494 std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
    495   CHECK(name != nullptr);
    496   std::string filename;
    497   if (IsHost()) {
    498     filename += getenv("ANDROID_HOST_OUT");
    499     filename += "/framework/";
    500   } else {
    501     filename += ART_TARGET_NATIVETEST_DIR_STRING;
    502   }
    503   filename += "art-gtest-";
    504   filename += name;
    505   filename += ".jar";
    506   return filename;
    507 }
    508 
    509 std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
    510     const char* name) {
    511   std::string filename = GetTestDexFileName(name);
    512   static constexpr bool kVerifyChecksum = true;
    513   std::string error_msg;
    514   const ArtDexFileLoader dex_file_loader;
    515   std::vector<std::unique_ptr<const DexFile>> dex_files;
    516   bool success = dex_file_loader.Open(filename.c_str(),
    517                                       filename.c_str(),
    518                                       /* verify */ true,
    519                                       kVerifyChecksum,
    520                                       &error_msg, &dex_files);
    521   CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
    522   for (auto& dex_file : dex_files) {
    523     CHECK_EQ(PROT_READ, dex_file->GetPermissions());
    524     CHECK(dex_file->IsReadOnly());
    525   }
    526   return dex_files;
    527 }
    528 
    529 std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
    530   std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
    531   EXPECT_EQ(1U, vector.size());
    532   return std::move(vector[0]);
    533 }
    534 
    535 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
    536   ScopedObjectAccess soa(Thread::Current());
    537 
    538   StackHandleScope<1> hs(soa.Self());
    539   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
    540       soa.Decode<mirror::ClassLoader>(jclass_loader));
    541   return GetDexFiles(soa, class_loader);
    542 }
    543 
    544 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
    545     ScopedObjectAccess& soa,
    546     Handle<mirror::ClassLoader> class_loader) {
    547   DCHECK(
    548       (class_loader->GetClass() ==
    549           soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
    550       (class_loader->GetClass() ==
    551           soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
    552 
    553   std::vector<const DexFile*> ret;
    554   VisitClassLoaderDexFiles(soa,
    555                            class_loader,
    556                            [&](const DexFile* cp_dex_file) {
    557                              if (cp_dex_file == nullptr) {
    558                                LOG(WARNING) << "Null DexFile";
    559                              } else {
    560                                ret.push_back(cp_dex_file);
    561                              }
    562                              return true;
    563                            });
    564   return ret;
    565 }
    566 
    567 const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
    568   std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
    569   DCHECK(!tmp.empty());
    570   const DexFile* ret = tmp[0];
    571   DCHECK(ret != nullptr);
    572   return ret;
    573 }
    574 
    575 jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
    576                                             const char* second_dex_name) {
    577   std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
    578   std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
    579   std::vector<const DexFile*> class_path;
    580   CHECK_NE(0U, first_dex_files.size());
    581   CHECK_NE(0U, second_dex_files.size());
    582   for (auto& dex_file : first_dex_files) {
    583     class_path.push_back(dex_file.get());
    584     loaded_dex_files_.push_back(std::move(dex_file));
    585   }
    586   for (auto& dex_file : second_dex_files) {
    587     class_path.push_back(dex_file.get());
    588     loaded_dex_files_.push_back(std::move(dex_file));
    589   }
    590 
    591   Thread* self = Thread::Current();
    592   jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
    593                                                                                      class_path);
    594   self->SetClassLoaderOverride(class_loader);
    595   return class_loader;
    596 }
    597 
    598 jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
    599   jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
    600   Thread::Current()->SetClassLoaderOverride(class_loader);
    601   return class_loader;
    602 }
    603 
    604 jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
    605                                                              jclass loader_class,
    606                                                              jobject parent_loader) {
    607   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
    608   std::vector<const DexFile*> class_path;
    609   CHECK_NE(0U, dex_files.size());
    610   for (auto& dex_file : dex_files) {
    611     class_path.push_back(dex_file.get());
    612     loaded_dex_files_.push_back(std::move(dex_file));
    613   }
    614   Thread* self = Thread::Current();
    615   ScopedObjectAccess soa(self);
    616 
    617   jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
    618       self,
    619       class_path,
    620       loader_class,
    621       parent_loader);
    622 
    623   {
    624     // Verify we build the correct chain.
    625 
    626     ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
    627     // Verify that the result has the correct class.
    628     CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
    629     // Verify that the parent is not null. The boot class loader will be set up as a
    630     // proper object.
    631     ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
    632     CHECK(actual_parent != nullptr);
    633 
    634     if (parent_loader != nullptr) {
    635       // We were given a parent. Verify that it's what we expect.
    636       ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
    637       CHECK_EQ(expected_parent, actual_parent);
    638     } else {
    639       // No parent given. The parent must be the BootClassLoader.
    640       CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
    641     }
    642   }
    643 
    644   return result;
    645 }
    646 
    647 jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
    648                                                         jobject parent_loader) {
    649   return LoadDexInWellKnownClassLoader(dex_name,
    650                                        WellKnownClasses::dalvik_system_PathClassLoader,
    651                                        parent_loader);
    652 }
    653 
    654 jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
    655                                                                 jobject parent_loader) {
    656   return LoadDexInWellKnownClassLoader(dex_name,
    657                                        WellKnownClasses::dalvik_system_DelegateLastClassLoader,
    658                                        parent_loader);
    659 }
    660 
    661 std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
    662   CHECK(suffix != nullptr);
    663 
    664   std::string location;
    665   if (IsHost()) {
    666     const char* host_dir = getenv("ANDROID_HOST_OUT");
    667     CHECK(host_dir != nullptr);
    668     location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
    669   } else {
    670     location = StringPrintf("/data/art-test/core.%s", suffix);
    671   }
    672 
    673   return location;
    674 }
    675 
    676 std::string CommonRuntimeTestImpl::CreateClassPath(
    677     const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
    678   CHECK(!dex_files.empty());
    679   std::string classpath = dex_files[0]->GetLocation();
    680   for (size_t i = 1; i < dex_files.size(); i++) {
    681     classpath += ":" + dex_files[i]->GetLocation();
    682   }
    683   return classpath;
    684 }
    685 
    686 std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
    687     const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
    688   CHECK(!dex_files.empty());
    689   std::string classpath = dex_files[0]->GetLocation() + "*" +
    690       std::to_string(dex_files[0]->GetLocationChecksum());
    691   for (size_t i = 1; i < dex_files.size(); i++) {
    692     classpath += ":" + dex_files[i]->GetLocation() + "*" +
    693         std::to_string(dex_files[i]->GetLocationChecksum());
    694   }
    695   return classpath;
    696 }
    697 
    698 void CommonRuntimeTestImpl::FillHeap(Thread* self,
    699                                      ClassLinker* class_linker,
    700                                      VariableSizedHandleScope* handle_scope) {
    701   DCHECK(handle_scope != nullptr);
    702 
    703   Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
    704 
    705   // Class java.lang.Object.
    706   Handle<mirror::Class> c(handle_scope->NewHandle(
    707       class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
    708   // Array helps to fill memory faster.
    709   Handle<mirror::Class> ca(handle_scope->NewHandle(
    710       class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
    711 
    712   // Start allocating with ~128K
    713   size_t length = 128 * KB;
    714   while (length > 40) {
    715     const int32_t array_length = length / 4;  // Object[] has elements of size 4.
    716     MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
    717         mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
    718     if (self->IsExceptionPending() || h == nullptr) {
    719       self->ClearException();
    720 
    721       // Try a smaller length
    722       length = length / 2;
    723       // Use at most a quarter the reported free space.
    724       size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
    725       if (length * 4 > mem) {
    726         length = mem / 4;
    727       }
    728     }
    729   }
    730 
    731   // Allocate simple objects till it fails.
    732   while (!self->IsExceptionPending()) {
    733     handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
    734   }
    735   self->ClearException();
    736 }
    737 
    738 void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
    739   // Use a smaller heap
    740   bool found = false;
    741   for (std::pair<std::string, const void*>& pair : *options) {
    742     if (pair.first.find("-Xmx") == 0) {
    743       pair.first = "-Xmx4M";  // Smallest we can go.
    744       found = true;
    745     }
    746   }
    747   if (!found) {
    748     options->emplace_back("-Xmx4M", nullptr);
    749   }
    750 }
    751 
    752 CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
    753   vm_->SetCheckJniAbortHook(Hook, &actual_);
    754 }
    755 
    756 CheckJniAbortCatcher::~CheckJniAbortCatcher() {
    757   vm_->SetCheckJniAbortHook(nullptr, nullptr);
    758   EXPECT_TRUE(actual_.empty()) << actual_;
    759 }
    760 
    761 void CheckJniAbortCatcher::Check(const std::string& expected_text) {
    762   Check(expected_text.c_str());
    763 }
    764 
    765 void CheckJniAbortCatcher::Check(const char* expected_text) {
    766   EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
    767       << "Expected to find: " << expected_text << "\n"
    768       << "In the output   : " << actual_;
    769   actual_.clear();
    770 }
    771 
    772 void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
    773   // We use += because when we're hooking the aborts like this, multiple problems can be found.
    774   *reinterpret_cast<std::string*>(data) += reason;
    775 }
    776 
    777 }  // namespace art
    778