common_test.h revision 3f47c12487250f61f3be95e9f275e3b08e2c49fb
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
17b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <dirent.h>
180af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h>
1927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h>
20b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/stat.h>
21b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/types.h>
22b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
23f66330a747eff155eb571b634fc9d901c55a78a7Elliott Hughes#include "../../external/icu4c/common/unicode/uvernum.h"
24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
251aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
26e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h"
27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h"
28578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h"
291212a022fa5f8ef9585d765b1809521812af882cIan Rogers#include "compiler/driver/compiler_driver.h"
30578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h"
3190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h"
321f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "heap.h"
330f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "instruction_set.h"
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
3733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "os.h"
381f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
3900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
40e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "ScopedLocalRef.h"
4190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h"
420f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "UniquePtr.h"
4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h"
440af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
45934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art {
46934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
47b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstromstatic const byte kBase64Map[256] = {
48b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
52b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
53b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
54a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18, // NOLINT
55a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes   19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255, // NOLINT
56b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
57a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes   37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48, // NOLINT
58a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes   49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
59b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
68b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
69b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255
70b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom};
71b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom
72b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrombyte* DecodeBase64(const char* src, size_t* dst_size) {
73b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  std::vector<byte> tmp;
74a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  uint32_t t = 0, y = 0;
75b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  int g = 3;
76b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  for (size_t i = 0; src[i] != '\0'; ++i) {
77b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    byte c = kBase64Map[src[i] & 0xFF];
78b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (c == 255) continue;
79b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    // the final = symbols are read and used to trim the remaining bytes
80b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (c == 254) {
81b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      c = 0;
82b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      // prevent g < 0 which would potentially allow an overflow later
83b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (--g < 0) {
845147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom        *dst_size = 0;
85b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        return NULL;
86b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
87b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    } else if (g != 3) {
88b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      // we only allow = to be at the end
895147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom      *dst_size = 0;
90b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      return NULL;
91b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    }
92b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    t = (t << 6) | c;
93b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (++y == 4) {
94b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      tmp.push_back((t >> 16) & 255);
95b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (g > 1) {
96b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        tmp.push_back((t >> 8) & 255);
97b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
98b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (g > 2) {
99b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        tmp.push_back(t & 255);
100b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
101b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      y = t = 0;
102b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    }
103b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
104b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  if (y != 0) {
1055147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom    *dst_size = 0;
106b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    return NULL;
107b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
108b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  UniquePtr<byte[]> dst(new byte[tmp.size()]);
109b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  if (dst_size != NULL) {
110b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    *dst_size = tmp.size();
1115147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom  } else {
1125147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom    *dst_size = 0;
113b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
114b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  std::copy(tmp.begin(), tmp.end(), dst.get());
115b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  return dst.release();
116b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom}
117b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom
1189f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic inline const DexFile* OpenDexFileBase64(const char* base64,
1199f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom                                               const std::string& location) {
12033f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // decode base64
121578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(base64 != NULL);
122578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  size_t length;
1234d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
1244d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  CHECK(dex_bytes.get() != NULL);
12533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
12633f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // write to provided file
12733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
12833f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  CHECK(file.get() != NULL);
1294d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  if (!file->WriteFully(dex_bytes.get(), length)) {
13033f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom    PLOG(FATAL) << "Failed to write base64 as dex file";
13133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  }
13233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  file.reset();
13333f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
13433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // read dex file
135a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const DexFile* dex_file = DexFile::Open(location, location);
136578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(dex_file != NULL);
137f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  return dex_file;
138578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}
139578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
140db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile {
141db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public:
142db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ScratchFile() {
14334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ = getenv("ANDROID_DATA");
14434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ += "/TmpFile-XXXXXX";
145761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    int fd = mkstemp(&filename_[0]);
146761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    CHECK_NE(-1, fd);
147761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    file_.reset(new File(fd, GetFilename()));
148db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
149db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
150db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ~ScratchFile() {
15134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int unlink_result = unlink(filename_.c_str());
152db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, unlink_result);
153db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
154db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
155a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const std::string& GetFilename() const {
156a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    return filename_;
157db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
158db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
159234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  File* GetFile() const {
160234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    return file_.get();
161234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
162234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes
163db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int GetFd() const {
164761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return file_->Fd();
165db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
166db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
167db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private:
16834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string filename_;
169234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  UniquePtr<File> file_;
170db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom};
171db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
172f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test {
1739baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public:
1742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static void MakeExecutable(const mirror::ByteArray* code_array) {
1753320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_array != NULL);
1763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(code_array->GetData(), code_array->GetLength());
1773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1791cb0ae742072b5ea2c7f677e6ad220ba01255daeShih-wei Liao  static void MakeExecutable(const std::vector<uint8_t>& code) {
1803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code.size(), 0U);
1813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(&code[0], code.size());
1823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
184ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Create an OatMethod based on pointers (for unit tests)
185ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  OatFile::OatMethod CreateOatMethod(const void* code,
186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const size_t frame_size_in_bytes,
187ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t core_spill_mask,
188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t fp_spill_mask,
189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t* mapping_table,
190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint16_t* vmap_table,
191e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                     const uint8_t* gc_map,
1922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                     const mirror::AbstractMethod::InvokeStub* invoke_stub) {
193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return OatFile::OatMethod(NULL,
194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(code),
195ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                frame_size_in_bytes,
196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                core_spill_mask,
197ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                fp_spill_mask,
198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(mapping_table),
199ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(vmap_table),
200e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                reinterpret_cast<uint32_t>(gc_map),
2010c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien                                reinterpret_cast<uint32_t>(invoke_stub)
202c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#if defined(ART_USE_PORTABLE_COMPILER)
203971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien                              , 0
2040c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien#endif
2050c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien                                );
206ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(method != NULL);
2103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2116d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    MethodHelper mh(method);
2120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const CompiledInvokeStub* compiled_invoke_stub =
2131212a022fa5f8ef9585d765b1809521812af882cIan Rogers        compiler_driver_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
2143320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
215f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
216971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien    const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
217971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien    MakeExecutable(invoke_stub);
2182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    const mirror::AbstractMethod::InvokeStub* method_invoke_stub =
2192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        reinterpret_cast<const mirror::AbstractMethod::InvokeStub*>(
2204284bb9e8b79add46e61da897fa02df3625888f7Logan Chien          CompiledCode::CodePointer(&invoke_stub[0],
2214284bb9e8b79add46e61da897fa02df3625888f7Logan Chien                                    compiled_invoke_stub->GetInstructionSet()));
222f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
2233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
2243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom              << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
2253320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2263320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    if (!method->IsAbstract()) {
2272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
2284445a7e3398a6143939168097a3aa275b734504dIan Rogers      const DexFile& dex_file = *dex_cache->GetDexFile();
2290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const CompiledMethod* compiled_method =
2301212a022fa5f8ef9585d765b1809521812af882cIan Rogers          compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(&dex_file,
2311212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                              method->GetDexMethodIndex()));
2323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      CHECK(compiled_method != NULL) << PrettyMethod(method);
233f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
234971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      const std::vector<uint8_t>& code = compiled_method->GetCode();
235971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      MakeExecutable(code);
236971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      const void* method_code = CompiledMethod::CodePointer(&code[0],
237971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien                                                            compiled_method->GetInstructionSet());
238f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
2393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
240f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
241ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
242ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFrameSizeInBytes(),
243ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetCoreSpillMask(),
244ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFpSpillMask(),
245ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetMappingTable()[0],
246ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetVmapTable()[0],
247e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
248ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
249265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_method.LinkMethod(method);
2503320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    } else {
2513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
2523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
2533320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
254ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
255ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      kStackAlignment,
256ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
257ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
258ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
259ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
260e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
261ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
262265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_method.LinkMethod(method);
2633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    }
2643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
2653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const void* code_start, size_t code_length) {
2673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_start != NULL);
2683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code_length, 0U);
2693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
2709baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t base = RoundDown(data, kPageSize);
2713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t limit = RoundUp(data + code_length, kPageSize);
2729baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t len = limit - base;
2739baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
2747a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom    CHECK_EQ(result, 0);
27524782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao
2761634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    // Flush instruction cache
27724782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Only uses __builtin___clear_cache if GCC >= 4.3.3
27824782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303
2791634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
2807a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#elif defined(__APPLE__)
28124782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
28224782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // need to generate clear_cache on x86.
2837a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else
2847a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#error unsupported
28524782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif
2869baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
2879baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
288761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  static void SetEnvironmentVariables(std::string& android_data) {
289761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
2900af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // $ANDROID_ROOT is set on the device, but not on the host.
2910af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // We need to set this so that icu4c can find its locale data.
2920af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      std::string root;
2930af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += getenv("ANDROID_BUILD_TOP");
294a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__)
2950af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += "/out/host/linux-x86";
296a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__)
297a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes      root += "/out/host/darwin-x86";
298a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else
299a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS
300a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif
3010af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      setenv("ANDROID_ROOT", root.c_str(), 1);
3022fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
3030af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    }
3040af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
30569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
306761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
307761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (mkdtemp(&android_data[0]) == NULL) {
308761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes      PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
3090f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    }
310761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    setenv("ANDROID_DATA", android_data.c_str(), 1);
311761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
312761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
313761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes protected:
314761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  static bool IsHost() {
315761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return (getenv("ANDROID_BUILD_TOP") != NULL);
316761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
317761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
318761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  virtual void SetUp() {
319761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    SetEnvironmentVariables(android_data_);
32034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    art_cache_.append(android_data_.c_str());
321b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    art_cache_.append("/art-cache");
322b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int mkdir_result = mkdir(art_cache_.c_str(), 0700);
323b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(mkdir_result, 0);
324b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
325a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
326a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    boot_class_path_.push_back(java_lang_dex_file_);
327578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
3280051be6d118c511308ed7764ef41e0d594292c49Mathieu Chartier    std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
3290051be6d118c511308ed7764ef41e0d594292c49Mathieu Chartier    std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
33030fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers
33169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    Runtime::Options options;
332a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom    options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
333a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
33469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
33530fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
33630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if(!Runtime::Create(options, false)) {
33800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      LOG(FATAL) << "Failed to create runtime";
33900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return;
34000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
34100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_.reset(Runtime::Current());
34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
34300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // give it away now and then switch to a more managable ScopedObjectAccess.
34400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread::Current()->TransitionFromRunnableToSuspended(kNative);
34500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Whilst we're in native take the opportunity to initialize well known classes.
34600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
34700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
34890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes    ASSERT_TRUE(runtime_.get() != NULL);
3497a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro    class_linker_ = runtime_->GetClassLinker();
3500cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3514f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    InstructionSet instruction_set = kNone;
352c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#if defined(__arm__)
3534f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kThumb2;
354c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#elif defined(__mips__)
355c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao    instruction_set = kMips;
356c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#elif defined(__i386__)
357c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao    instruction_set = kX86;
3582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif
359c531cefbfb5394413122e9f57d211ba436cff012buzbee
360c531cefbfb5394413122e9f57d211ba436cff012buzbee    // TODO: make selectable
361c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER)
362c531cefbfb5394413122e9f57d211ba436cff012buzbee    CompilerBackend compiler_backend = kPortable;
363c531cefbfb5394413122e9f57d211ba436cff012buzbee#else
364c531cefbfb5394413122e9f57d211ba436cff012buzbee    CompilerBackend compiler_backend = kQuick;
365c531cefbfb5394413122e9f57d211ba436cff012buzbee#endif
366c531cefbfb5394413122e9f57d211ba436cff012buzbee
3671212a022fa5f8ef9585d765b1809521812af882cIan Rogers    runtime_->SetJniDlsymLookupStub(CompilerDriver::CreateJniDlsymLookupStub(instruction_set));
3681212a022fa5f8ef9585d765b1809521812af882cIan Rogers    runtime_->SetAbstractMethodErrorStubArray(CompilerDriver::CreateAbstractMethodErrorStub(instruction_set));
369362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
3701cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      Runtime::TrampolineType type = Runtime::TrampolineType(i);
3711cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      if (!runtime_->HasResolutionStubArray(type)) {
3724f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetResolutionStubArray(
3731212a022fa5f8ef9585d765b1809521812af882cIan Rogers            CompilerDriver::CreateResolutionStub(instruction_set, type), type);
3741cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      }
3751cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    }
3761984651929744dd603fd082e23eacd877b9bc177Ian Rogers    if (!runtime_->HasResolutionMethod()) {
3771984651929744dd603fd082e23eacd877b9bc177Ian Rogers      runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
3781984651929744dd603fd082e23eacd877b9bc177Ian Rogers    }
379362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
3804f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
3814f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      if (!runtime_->HasCalleeSaveMethod(type)) {
3824f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetCalleeSaveMethod(
3834f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
3844f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      }
3854f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
3861984651929744dd603fd082e23eacd877b9bc177Ian Rogers    class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
387e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset(new std::set<std::string>);
3881212a022fa5f8ef9585d765b1809521812af882cIan Rogers    compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
3891212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                              true, true));
3902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
39102b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
39202b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    // pool is created by the runtime.
39302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    runtime_->GetHeap()->CreateThreadPool();
39402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
39500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
396578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  }
397578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
398b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  virtual void TearDown() {
399b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    const char* android_data = getenv("ANDROID_DATA");
400b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(android_data != NULL);
401b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    DIR* dir = opendir(art_cache_.c_str());
402b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(dir != NULL);
4034696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes    dirent* e;
4044696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes    while ((e = readdir(dir)) != NULL) {
4054696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes      if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
406b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        continue;
407b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
408b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      std::string filename(art_cache_);
409b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.push_back('/');
4104696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes      filename.append(e->d_name);
411b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int unlink_result = unlink(filename.c_str());
412b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, unlink_result);
413b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    }
414b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    closedir(dir);
415b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int rmdir_cache_result = rmdir(art_cache_.c_str());
416b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_cache_result);
41734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int rmdir_data_result = rmdir(android_data_.c_str());
418b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_data_result);
4190af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
4200af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // icu4c has a fixed 10-element array "gCommonICUDataArray".
4210af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // If we run > 10 tests, we fill that array and u_setCommonData fails.
4220af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // There's a function to clear the array, but it's not public...
4230af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    typedef void (*IcuCleanupFn)();
4240af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
4250af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    CHECK(sym != NULL);
4260af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
4270af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    (*icu_cleanup_fn)();
4280cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
4291212a022fa5f8ef9585d765b1809521812af882cIan Rogers    compiler_driver_.reset();
430e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset();
4314d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    STLDeleteElements(&opened_dex_files_);
4322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
433b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
434b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
435b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
436b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string GetLibCoreDexFileName() {
437265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return GetDexFileName("core");
438265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
439265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
440265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string GetDexFileName(const std::string& jar_prefix) {
441761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
442b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
443b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      CHECK(host_dir != NULL);
444265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
445ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson    }
446265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
447b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
448ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
4493f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  std::string GetTestAndroidRoot() {
4503f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    if (IsHost()) {
4513f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
4523f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      CHECK(host_dir != NULL);
4533f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      return host_dir;
4543f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    }
4553f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    return GetAndroidRoot();
4563f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  }
4573f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom
4589f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  const DexFile* OpenTestDexFile(const char* name) {
4599f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    CHECK(name != NULL);
4609f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    std::string filename;
461761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
462b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += getenv("ANDROID_HOST_OUT");
463b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/framework/";
464b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    } else {
465b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/data/nativetest/art/";
4669f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    }
467b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    filename += "art-test-dex-";
4689f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += name;
4699f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += ".jar";
470a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const DexFile* dex_file = DexFile::Open(filename, filename);
47169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    CHECK(dex_file != NULL) << "Failed to open " << filename;
4724d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    opened_dex_files_.push_back(dex_file);
4739f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    return dex_file;
4749f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  }
4759f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
47600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject LoadDex(const char* dex_name)
477b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4789baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    const DexFile* dex_file = OpenTestDexFile(dex_name);
4799baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(dex_file != NULL);
4809baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_linker_->RegisterDexFile(*dex_file);
4819baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    std::vector<const DexFile*> class_path;
4829baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_path.push_back(dex_file);
48300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccessUnchecked soa(Thread::Current());
48400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedLocalRef<jobject> class_loader_local(soa.Env(),
48500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
48600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
4872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
48800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
48900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return class_loader;
4909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4919baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
493955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
4942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
495aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
496aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
497aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetDirectMethod(i));
498aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
499aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
500aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetVirtualMethod(i));
501aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
502aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
503aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
5042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
5059baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(method != NULL);
5061212a022fa5f8ef9585d765b1809521812af882cIan Rogers    compiler_driver_->CompileOne(method);
5073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(method);
5083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
509169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    MakeExecutable(runtime_->GetJniDlsymLookupStub());
5109baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5119baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileDirectMethod(mirror::ClassLoader* class_loader,
5139baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* class_name,
5149baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* method_name,
51500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                           const char* signature)
516b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
517955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
5182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
5199baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
5202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
5210f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Direct method not found: "
5220f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
5239baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5249baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5259baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileVirtualMethod(mirror::ClassLoader* class_loader,
5279baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* class_name,
5289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* method_name,
52900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            const char* signature)
530b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
531955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
5322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
5339baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
5342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
5350f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Virtual method not found: "
5360f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
5379baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5389baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5399baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
540700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  void ReserveImageSpace() {
541700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    // Reserve where the image will be loaded up front so that other parts of test set up don't
542700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    // accidentally end up colliding with the fixed memory address when we need to load the image.
543a40307e8562c20d9b9ce46e773864d07d95512a1Ian Rogers    image_reservation_.reset(MemMap::MapAnonymous("image reservation", (byte*)ART_BASE_ADDRESS,
544700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                                  (size_t)100 * 1024 * 1024,  // 100MB
545700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                                  PROT_NONE));
546700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
547700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
548700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  void UnreserveImageSpace() {
549700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    image_reservation_.reset();
550700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
551700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
55234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string android_data_;
553b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string art_cache_;
554a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const DexFile* java_lang_dex_file_;  // owned by runtime_
5559ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
55690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<Runtime> runtime_;
5570e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  // Owned by the runtime
5587a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro  ClassLinker* class_linker_;
5591212a022fa5f8ef9585d765b1809521812af882cIan Rogers  UniquePtr<CompilerDriver> compiler_driver_;
560e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes  UniquePtr<std::set<std::string> > image_classes_;
5619baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5629baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private:
5634d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  std::vector<const DexFile*> opened_dex_files_;
564700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  UniquePtr<MemMap> image_reservation_;
565578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom};
566578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
567b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
568b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// rather than aborting, so be careful!
569b264f081424642b06b0bbe7102781895d41faa9dElliott Hughesclass CheckJniAbortCatcher {
570b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes public:
571b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
572b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = Hook;
573b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = &actual_;
574b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
575b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
576b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  ~CheckJniAbortCatcher() {
577b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = NULL;
578b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = NULL;
57956ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    EXPECT_TRUE(actual_.empty()) << actual_;
580b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
581b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
582b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  void Check(const char* expected_text) {
583b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
584b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "Expected to find: " << expected_text << "\n"
585b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "In the output   : " << actual_;
5863f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    actual_.clear();
587b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
588b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
589b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes private:
590b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  static void Hook(void* data, const std::string& reason) {
5913f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    // We use += because when we're hooking the aborts like this, multiple problems can be found.
5923f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    *reinterpret_cast<std::string*>(data) += reason;
593b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
594b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
595b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  JavaVMExt* vm_;
596b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  std::string actual_;
597b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
598b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
599b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes};
600b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
601265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// TODO: These tests were disabled for portable when we went to having
602265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// MCLinker link LLVM ELF output because we no longer just have code
603265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// blobs in memory. We'll need to dlopen to load and relocate
604265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// temporary output to resurrect these tests.
605265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER)
606265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
607265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#else
608265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define TEST_DISABLED_FOR_PORTABLE()
609265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif
610265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
611934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom}  // namespace art
61234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
61334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std {
61434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
61534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself?
61634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T>
61734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
61814134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes  os << ::art::ToString(rhs);
61934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  return os;
62034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}
62134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
62234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}  // namespace std
623