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