Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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 #ifndef ART_RUNTIME_COMMON_TEST_H_
     18 #define ART_RUNTIME_COMMON_TEST_H_
     19 
     20 #include <dirent.h>
     21 #include <dlfcn.h>
     22 #include <sys/mman.h>
     23 #include <sys/stat.h>
     24 #include <sys/types.h>
     25 
     26 #include "../../external/icu4c/common/unicode/uvernum.h"
     27 #include "base/macros.h"
     28 #include "base/stl_util.h"
     29 #include "base/stringprintf.h"
     30 #include "base/unix_file/fd_file.h"
     31 #include "class_linker.h"
     32 #include "compiler/driver/compiler_driver.h"
     33 #include "dex_file-inl.h"
     34 #include "entrypoints/entrypoint_utils.h"
     35 #include "gc/heap.h"
     36 #include "gtest/gtest.h"
     37 #include "instruction_set.h"
     38 #include "interpreter/interpreter.h"
     39 #include "mirror/class_loader.h"
     40 #include "oat_file.h"
     41 #include "object_utils.h"
     42 #include "os.h"
     43 #include "runtime.h"
     44 #include "scoped_thread_state_change.h"
     45 #include "ScopedLocalRef.h"
     46 #include "thread.h"
     47 #include "UniquePtr.h"
     48 #include "well_known_classes.h"
     49 
     50 namespace art {
     51 
     52 static const byte kBase64Map[256] = {
     53   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     54   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     55   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     56   255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
     57   52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
     58   255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
     59     7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  // NOLINT
     60    19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,  // NOLINT
     61   255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
     62    37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  // NOLINT
     63    49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,  // NOLINT
     64   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     65   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     66   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     67   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     68   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     69   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     70   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     71   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     72   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     73   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     74   255, 255, 255, 255
     75 };
     76 
     77 byte* DecodeBase64(const char* src, size_t* dst_size) {
     78   std::vector<byte> tmp;
     79   uint32_t t = 0, y = 0;
     80   int g = 3;
     81   for (size_t i = 0; src[i] != '\0'; ++i) {
     82     byte c = kBase64Map[src[i] & 0xFF];
     83     if (c == 255) continue;
     84     // the final = symbols are read and used to trim the remaining bytes
     85     if (c == 254) {
     86       c = 0;
     87       // prevent g < 0 which would potentially allow an overflow later
     88       if (--g < 0) {
     89         *dst_size = 0;
     90         return NULL;
     91       }
     92     } else if (g != 3) {
     93       // we only allow = to be at the end
     94       *dst_size = 0;
     95       return NULL;
     96     }
     97     t = (t << 6) | c;
     98     if (++y == 4) {
     99       tmp.push_back((t >> 16) & 255);
    100       if (g > 1) {
    101         tmp.push_back((t >> 8) & 255);
    102       }
    103       if (g > 2) {
    104         tmp.push_back(t & 255);
    105       }
    106       y = t = 0;
    107     }
    108   }
    109   if (y != 0) {
    110     *dst_size = 0;
    111     return NULL;
    112   }
    113   UniquePtr<byte[]> dst(new byte[tmp.size()]);
    114   if (dst_size != NULL) {
    115     *dst_size = tmp.size();
    116   } else {
    117     *dst_size = 0;
    118   }
    119   std::copy(tmp.begin(), tmp.end(), dst.get());
    120   return dst.release();
    121 }
    122 
    123 class ScratchFile {
    124  public:
    125   ScratchFile() {
    126     filename_ = getenv("ANDROID_DATA");
    127     filename_ += "/TmpFile-XXXXXX";
    128     int fd = mkstemp(&filename_[0]);
    129     CHECK_NE(-1, fd);
    130     file_.reset(new File(fd, GetFilename()));
    131   }
    132 
    133   ~ScratchFile() {
    134     int unlink_result = unlink(filename_.c_str());
    135     CHECK_EQ(0, unlink_result);
    136   }
    137 
    138   const std::string& GetFilename() const {
    139     return filename_;
    140   }
    141 
    142   File* GetFile() const {
    143     return file_.get();
    144   }
    145 
    146   int GetFd() const {
    147     return file_->Fd();
    148   }
    149 
    150  private:
    151   std::string filename_;
    152   UniquePtr<File> file_;
    153 };
    154 
    155 class CommonTest : public testing::Test {
    156  public:
    157   static void MakeExecutable(const mirror::ByteArray* code_array) {
    158     CHECK(code_array != NULL);
    159     MakeExecutable(code_array->GetData(), code_array->GetLength());
    160   }
    161 
    162   static void MakeExecutable(const std::vector<uint8_t>& code) {
    163     CHECK_NE(code.size(), 0U);
    164     MakeExecutable(&code[0], code.size());
    165   }
    166 
    167   // Create an OatMethod based on pointers (for unit tests)
    168   OatFile::OatMethod CreateOatMethod(const void* code,
    169                                      const size_t frame_size_in_bytes,
    170                                      const uint32_t core_spill_mask,
    171                                      const uint32_t fp_spill_mask,
    172                                      const uint8_t* mapping_table,
    173                                      const uint8_t* vmap_table,
    174                                      const uint8_t* gc_map) {
    175       return OatFile::OatMethod(NULL,
    176                                 reinterpret_cast<uint32_t>(code),
    177                                 frame_size_in_bytes,
    178                                 core_spill_mask,
    179                                 fp_spill_mask,
    180                                 reinterpret_cast<uint32_t>(mapping_table),
    181                                 reinterpret_cast<uint32_t>(vmap_table),
    182                                 reinterpret_cast<uint32_t>(gc_map));
    183   }
    184 
    185   void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    186     CHECK(method != NULL);
    187     LOG(INFO) << "MakeExecutable " << PrettyMethod(method);
    188 
    189     const CompiledMethod* compiled_method = NULL;
    190     if (!method->IsAbstract()) {
    191       const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
    192       const DexFile& dex_file = *dex_cache->GetDexFile();
    193       compiled_method =
    194           compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
    195                                                               method->GetDexMethodIndex()));
    196     }
    197     if (compiled_method != NULL) {
    198       const std::vector<uint8_t>& code = compiled_method->GetCode();
    199       MakeExecutable(code);
    200       const void* method_code = CompiledMethod::CodePointer(&code[0],
    201                                                             compiled_method->GetInstructionSet());
    202       LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
    203       OatFile::OatMethod oat_method = CreateOatMethod(method_code,
    204                                                       compiled_method->GetFrameSizeInBytes(),
    205                                                       compiled_method->GetCoreSpillMask(),
    206                                                       compiled_method->GetFpSpillMask(),
    207                                                       &compiled_method->GetMappingTable()[0],
    208                                                       &compiled_method->GetVmapTable()[0],
    209                                                       NULL);
    210       oat_method.LinkMethod(method);
    211       method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
    212     } else {
    213       const void* method_code;
    214       // No code? You must mean to go into the interpreter.
    215       method_code = GetCompiledCodeToInterpreterBridge();
    216       LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
    217       OatFile::OatMethod oat_method = CreateOatMethod(method_code,
    218                                                       kStackAlignment,
    219                                                       0,
    220                                                       0,
    221                                                       NULL,
    222                                                       NULL,
    223                                                       NULL);
    224       oat_method.LinkMethod(method);
    225       method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
    226     }
    227   }
    228 
    229   static void MakeExecutable(const void* code_start, size_t code_length) {
    230     CHECK(code_start != NULL);
    231     CHECK_NE(code_length, 0U);
    232     uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
    233     uintptr_t base = RoundDown(data, kPageSize);
    234     uintptr_t limit = RoundUp(data + code_length, kPageSize);
    235     uintptr_t len = limit - base;
    236     int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
    237     CHECK_EQ(result, 0);
    238 
    239     // Flush instruction cache
    240     // Only uses __builtin___clear_cache if GCC >= 4.3.3
    241 #if GCC_VERSION >= 40303
    242     __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
    243 #else
    244     LOG(FATAL) << "UNIMPLEMENTED: cache flush";
    245 #endif
    246   }
    247 
    248   static void SetEnvironmentVariables(std::string& android_data) {
    249     if (IsHost()) {
    250       // $ANDROID_ROOT is set on the device, but not on the host.
    251       // We need to set this so that icu4c can find its locale data.
    252       std::string root;
    253       root += getenv("ANDROID_BUILD_TOP");
    254 #if defined(__linux__)
    255       root += "/out/host/linux-x86";
    256 #elif defined(__APPLE__)
    257       root += "/out/host/darwin-x86";
    258 #else
    259 #error unsupported OS
    260 #endif
    261       setenv("ANDROID_ROOT", root.c_str(), 1);
    262       setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
    263     }
    264 
    265     // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
    266     android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
    267     if (mkdtemp(&android_data[0]) == NULL) {
    268       PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
    269     }
    270     setenv("ANDROID_DATA", android_data.c_str(), 1);
    271   }
    272 
    273  protected:
    274   static bool IsHost() {
    275     return (getenv("ANDROID_BUILD_TOP") != NULL);
    276   }
    277 
    278   virtual void SetUp() {
    279     SetEnvironmentVariables(android_data_);
    280     dalvik_cache_.append(android_data_.c_str());
    281     dalvik_cache_.append("/dalvik-cache");
    282     int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
    283     ASSERT_EQ(mkdir_result, 0);
    284 
    285     java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
    286     if (java_lang_dex_file_ == NULL) {
    287       LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "'\n";
    288     }
    289     conscrypt_file_ = DexFile::Open(GetConscryptFileName(), GetConscryptFileName());
    290     if (conscrypt_file_  == NULL) {
    291       LOG(FATAL) << "Could not open .dex file '" << GetConscryptFileName() << "'\n";
    292     }
    293     boot_class_path_.push_back(java_lang_dex_file_);
    294     boot_class_path_.push_back(conscrypt_file_);
    295 
    296     std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
    297     std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
    298 
    299     Runtime::Options options;
    300     options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
    301     options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
    302     options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
    303     options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
    304     options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
    305     if (!Runtime::Create(options, false)) {
    306       LOG(FATAL) << "Failed to create runtime";
    307       return;
    308     }
    309     runtime_.reset(Runtime::Current());
    310     // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
    311     // give it away now and then switch to a more managable ScopedObjectAccess.
    312     Thread::Current()->TransitionFromRunnableToSuspended(kNative);
    313     {
    314       ScopedObjectAccess soa(Thread::Current());
    315       ASSERT_TRUE(runtime_.get() != NULL);
    316       class_linker_ = runtime_->GetClassLinker();
    317 
    318       InstructionSet instruction_set = kNone;
    319 #if defined(__arm__)
    320       instruction_set = kThumb2;
    321 #elif defined(__mips__)
    322       instruction_set = kMips;
    323 #elif defined(__i386__)
    324       instruction_set = kX86;
    325 #endif
    326 
    327       // TODO: make selectable
    328 #if defined(ART_USE_PORTABLE_COMPILER)
    329       CompilerBackend compiler_backend = kPortable;
    330 #else
    331       CompilerBackend compiler_backend = kQuick;
    332 #endif
    333 
    334       if (!runtime_->HasResolutionMethod()) {
    335         runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
    336       }
    337       for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
    338         Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
    339         if (!runtime_->HasCalleeSaveMethod(type)) {
    340           runtime_->SetCalleeSaveMethod(
    341               runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
    342         }
    343       }
    344       class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
    345       compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set,
    346                                                 true, new CompilerDriver::DescriptorSet,
    347                                                 2, true));
    348     }
    349     // We typically don't generate an image in unit tests, disable this optimization by default.
    350     compiler_driver_->SetSupportBootImageFixup(false);
    351 
    352     // We're back in native, take the opportunity to initialize well known classes.
    353     WellKnownClasses::Init(Thread::Current()->GetJniEnv());
    354     // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
    355     // pool is created by the runtime.
    356     runtime_->GetHeap()->CreateThreadPool();
    357     runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
    358   }
    359 
    360   virtual void TearDown() {
    361     const char* android_data = getenv("ANDROID_DATA");
    362     ASSERT_TRUE(android_data != NULL);
    363     DIR* dir = opendir(dalvik_cache_.c_str());
    364     ASSERT_TRUE(dir != NULL);
    365     dirent* e;
    366     while ((e = readdir(dir)) != NULL) {
    367       if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
    368         continue;
    369       }
    370       std::string filename(dalvik_cache_);
    371       filename.push_back('/');
    372       filename.append(e->d_name);
    373       int unlink_result = unlink(filename.c_str());
    374       ASSERT_EQ(0, unlink_result);
    375     }
    376     closedir(dir);
    377     int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
    378     ASSERT_EQ(0, rmdir_cache_result);
    379     int rmdir_data_result = rmdir(android_data_.c_str());
    380     ASSERT_EQ(0, rmdir_data_result);
    381 
    382     // icu4c has a fixed 10-element array "gCommonICUDataArray".
    383     // If we run > 10 tests, we fill that array and u_setCommonData fails.
    384     // There's a function to clear the array, but it's not public...
    385     typedef void (*IcuCleanupFn)();
    386     void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
    387     CHECK(sym != NULL);
    388     IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
    389     (*icu_cleanup_fn)();
    390 
    391     compiler_driver_.reset();
    392     STLDeleteElements(&opened_dex_files_);
    393 
    394     Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
    395   }
    396 
    397   std::string GetLibCoreDexFileName() {
    398     return GetDexFileName("core-libart");
    399   }
    400 
    401   std::string GetConscryptFileName() {
    402     return GetDexFileName("conscrypt");
    403   }
    404 
    405   std::string GetDexFileName(const std::string& jar_prefix) {
    406     if (IsHost()) {
    407       const char* host_dir = getenv("ANDROID_HOST_OUT");
    408       CHECK(host_dir != NULL);
    409       return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
    410     }
    411     return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
    412   }
    413 
    414   std::string GetTestAndroidRoot() {
    415     if (IsHost()) {
    416       const char* host_dir = getenv("ANDROID_HOST_OUT");
    417       CHECK(host_dir != NULL);
    418       return host_dir;
    419     }
    420     return GetAndroidRoot();
    421   }
    422 
    423   const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    424     CHECK(name != NULL);
    425     std::string filename;
    426     if (IsHost()) {
    427       filename += getenv("ANDROID_HOST_OUT");
    428       filename += "/framework/";
    429     } else {
    430       filename += "/data/nativetest/art/";
    431     }
    432     filename += "art-test-dex-";
    433     filename += name;
    434     filename += ".jar";
    435     const DexFile* dex_file = DexFile::Open(filename, filename);
    436     CHECK(dex_file != NULL) << "Failed to open " << filename;
    437     CHECK_EQ(PROT_READ, dex_file->GetPermissions());
    438     CHECK(dex_file->IsReadOnly());
    439     opened_dex_files_.push_back(dex_file);
    440     return dex_file;
    441   }
    442 
    443   jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    444     const DexFile* dex_file = OpenTestDexFile(dex_name);
    445     CHECK(dex_file != NULL);
    446     class_linker_->RegisterDexFile(*dex_file);
    447     std::vector<const DexFile*> class_path;
    448     class_path.push_back(dex_file);
    449     ScopedObjectAccessUnchecked soa(Thread::Current());
    450     ScopedLocalRef<jobject> class_loader_local(soa.Env(),
    451         soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
    452     jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
    453     soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
    454     Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
    455     return class_loader;
    456   }
    457 
    458   void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
    459       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    460     std::string class_descriptor(DotToDescriptor(class_name));
    461     mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
    462     CHECK(klass != NULL) << "Class not found " << class_name;
    463     for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
    464       CompileMethod(klass->GetDirectMethod(i));
    465     }
    466     for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
    467       CompileMethod(klass->GetVirtualMethod(i));
    468     }
    469   }
    470 
    471   void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    472     CHECK(method != NULL);
    473     base::TimingLogger timings("CommonTest::CompileMethod", false, false);
    474     timings.StartSplit("CompileOne");
    475     compiler_driver_->CompileOne(method, timings);
    476     MakeExecutable(method);
    477   }
    478 
    479   void CompileDirectMethod(mirror::ClassLoader* class_loader,
    480                            const char* class_name,
    481                            const char* method_name,
    482                            const char* signature)
    483       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    484     std::string class_descriptor(DotToDescriptor(class_name));
    485     mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
    486     CHECK(klass != NULL) << "Class not found " << class_name;
    487     mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
    488     CHECK(method != NULL) << "Direct method not found: "
    489                           << class_name << "." << method_name << signature;
    490     CompileMethod(method);
    491   }
    492 
    493   void CompileVirtualMethod(mirror::ClassLoader* class_loader,
    494                             const char* class_name,
    495                             const char* method_name,
    496                             const char* signature)
    497       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    498     std::string class_descriptor(DotToDescriptor(class_name));
    499     mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
    500     CHECK(klass != NULL) << "Class not found " << class_name;
    501     mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
    502     CHECK(method != NULL) << "Virtual method not found: "
    503                           << class_name << "." << method_name << signature;
    504     CompileMethod(method);
    505   }
    506 
    507   void ReserveImageSpace() {
    508     // Reserve where the image will be loaded up front so that other parts of test set up don't
    509     // accidentally end up colliding with the fixed memory address when we need to load the image.
    510     image_reservation_.reset(MemMap::MapAnonymous("image reservation",
    511                                                   reinterpret_cast<byte*>(ART_BASE_ADDRESS),
    512                                                   (size_t)100 * 1024 * 1024,  // 100MB
    513                                                   PROT_NONE));
    514   }
    515 
    516   void UnreserveImageSpace() {
    517     image_reservation_.reset();
    518   }
    519 
    520   std::string android_data_;
    521   std::string dalvik_cache_;
    522   const DexFile* java_lang_dex_file_;  // owned by runtime_
    523   const DexFile* conscrypt_file_;  // owned by runtime_
    524   std::vector<const DexFile*> boot_class_path_;
    525   UniquePtr<Runtime> runtime_;
    526   // Owned by the runtime
    527   ClassLinker* class_linker_;
    528   UniquePtr<CompilerDriver> compiler_driver_;
    529 
    530  private:
    531   std::vector<const DexFile*> opened_dex_files_;
    532   UniquePtr<MemMap> image_reservation_;
    533 };
    534 
    535 // Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
    536 // rather than aborting, so be careful!
    537 class CheckJniAbortCatcher {
    538  public:
    539   CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
    540     vm_->check_jni_abort_hook = Hook;
    541     vm_->check_jni_abort_hook_data = &actual_;
    542   }
    543 
    544   ~CheckJniAbortCatcher() {
    545     vm_->check_jni_abort_hook = NULL;
    546     vm_->check_jni_abort_hook_data = NULL;
    547     EXPECT_TRUE(actual_.empty()) << actual_;
    548   }
    549 
    550   void Check(const char* expected_text) {
    551     EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
    552         << "Expected to find: " << expected_text << "\n"
    553         << "In the output   : " << actual_;
    554     actual_.clear();
    555   }
    556 
    557  private:
    558   static void Hook(void* data, const std::string& reason) {
    559     // We use += because when we're hooking the aborts like this, multiple problems can be found.
    560     *reinterpret_cast<std::string*>(data) += reason;
    561   }
    562 
    563   JavaVMExt* vm_;
    564   std::string actual_;
    565 
    566   DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
    567 };
    568 
    569 // TODO: These tests were disabled for portable when we went to having
    570 // MCLinker link LLVM ELF output because we no longer just have code
    571 // blobs in memory. We'll need to dlopen to load and relocate
    572 // temporary output to resurrect these tests.
    573 #if defined(ART_USE_PORTABLE_COMPILER)
    574 #define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
    575 #else
    576 #define TEST_DISABLED_FOR_PORTABLE()
    577 #endif
    578 
    579 }  // namespace art
    580 
    581 namespace std {
    582 
    583 // TODO: isn't gtest supposed to be able to print STL types for itself?
    584 template <typename T>
    585 std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
    586   os << ::art::ToString(rhs);
    587   return os;
    588 }
    589 
    590 }  // namespace std
    591 
    592 #endif  // ART_RUNTIME_COMMON_TEST_H_
    593