common_test.h revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
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"
299baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "compiler.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)
2020c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien#if defined(ART_USE_LLVM_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 =
2136d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers        compiler_->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 =
2300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers          compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
2310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian 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);
249ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(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);
262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(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#elif defined(ART_USE_LLVM_COMPILER)
364c531cefbfb5394413122e9f57d211ba436cff012buzbee    CompilerBackend compiler_backend = kIceland; // TODO: remove
365c531cefbfb5394413122e9f57d211ba436cff012buzbee#else
366c531cefbfb5394413122e9f57d211ba436cff012buzbee    CompilerBackend compiler_backend = kQuick;
367c531cefbfb5394413122e9f57d211ba436cff012buzbee#endif
368c531cefbfb5394413122e9f57d211ba436cff012buzbee
3698add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes    runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
3704f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
371362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
3721cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      Runtime::TrampolineType type = Runtime::TrampolineType(i);
3731cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      if (!runtime_->HasResolutionStubArray(type)) {
3744f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetResolutionStubArray(
3754f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            Compiler::CreateResolutionStub(instruction_set, type), type);
3761cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      }
3771cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    }
3781984651929744dd603fd082e23eacd877b9bc177Ian Rogers    if (!runtime_->HasResolutionMethod()) {
3791984651929744dd603fd082e23eacd877b9bc177Ian Rogers      runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
3801984651929744dd603fd082e23eacd877b9bc177Ian Rogers    }
381362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
3824f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
3834f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      if (!runtime_->HasCalleeSaveMethod(type)) {
3844f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetCalleeSaveMethod(
3854f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
3864f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      }
3874f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
3881984651929744dd603fd082e23eacd877b9bc177Ian Rogers    class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
389e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset(new std::set<std::string>);
390c531cefbfb5394413122e9f57d211ba436cff012buzbee    compiler_.reset(new Compiler(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
391ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                 true, true));
3922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
39302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
39402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    // pool is created by the runtime.
39502b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    runtime_->GetHeap()->CreateThreadPool();
39602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
39700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
398578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  }
399578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
400b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  virtual void TearDown() {
401b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    const char* android_data = getenv("ANDROID_DATA");
402b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(android_data != NULL);
403b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    DIR* dir = opendir(art_cache_.c_str());
404b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(dir != NULL);
4054696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes    dirent* e;
4064696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes    while ((e = readdir(dir)) != NULL) {
4074696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes      if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
408b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        continue;
409b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
410b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      std::string filename(art_cache_);
411b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.push_back('/');
4124696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes      filename.append(e->d_name);
413b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int unlink_result = unlink(filename.c_str());
414b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, unlink_result);
415b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    }
416b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    closedir(dir);
417b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int rmdir_cache_result = rmdir(art_cache_.c_str());
418b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_cache_result);
41934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int rmdir_data_result = rmdir(android_data_.c_str());
420b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_data_result);
4210af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
4220af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // icu4c has a fixed 10-element array "gCommonICUDataArray".
4230af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // If we run > 10 tests, we fill that array and u_setCommonData fails.
4240af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // There's a function to clear the array, but it's not public...
4250af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    typedef void (*IcuCleanupFn)();
4260af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
4270af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    CHECK(sym != NULL);
4280af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
4290af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    (*icu_cleanup_fn)();
4300cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
4310e073f7b9386a461b470d30415a96480ab1b76afIan Rogers    compiler_.reset();
432e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset();
4334d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    STLDeleteElements(&opened_dex_files_);
4342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
435b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
436b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
437b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
438b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string GetLibCoreDexFileName() {
439761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
440b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
441b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      CHECK(host_dir != NULL);
442b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
443ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson    }
444a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom    return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
445b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
446ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
4479f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  const DexFile* OpenTestDexFile(const char* name) {
4489f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    CHECK(name != NULL);
4499f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    std::string filename;
450761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
451b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += getenv("ANDROID_HOST_OUT");
452b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/framework/";
453b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    } else {
454b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/data/nativetest/art/";
4559f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    }
456b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    filename += "art-test-dex-";
4579f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += name;
4589f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += ".jar";
459a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const DexFile* dex_file = DexFile::Open(filename, filename);
46069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    CHECK(dex_file != NULL) << "Failed to open " << filename;
4614d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    opened_dex_files_.push_back(dex_file);
4629f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    return dex_file;
4639f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  }
4649f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
46500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject LoadDex(const char* dex_name)
466b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4679baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    const DexFile* dex_file = OpenTestDexFile(dex_name);
4689baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(dex_file != NULL);
4699baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_linker_->RegisterDexFile(*dex_file);
4709baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    std::vector<const DexFile*> class_path;
4719baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_path.push_back(dex_file);
47200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccessUnchecked soa(Thread::Current());
47300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedLocalRef<jobject> class_loader_local(soa.Env(),
47400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
47500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
4762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
47700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
47800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return class_loader;
4799baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4809baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
482955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
4832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
484aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
485aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
486aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetDirectMethod(i));
487aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
488aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
489aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetVirtualMethod(i));
490aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
491aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
492aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
4932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4949baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(method != NULL);
4952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    compiler_->CompileOne(method);
4963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(method);
4973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
498169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    MakeExecutable(runtime_->GetJniDlsymLookupStub());
4999baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5009baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileDirectMethod(mirror::ClassLoader* class_loader,
5029baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* class_name,
5039baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* method_name,
50400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                           const char* signature)
505b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
506955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
5072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
5089baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
5092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
5100f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Direct method not found: "
5110f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
5129baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5139baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5149baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileVirtualMethod(mirror::ClassLoader* class_loader,
5169baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* class_name,
5179baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* method_name,
51800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            const char* signature)
519b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
520955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
5212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
5229baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
5232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
5240f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Virtual method not found: "
5250f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
5269baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5279baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
529700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  void ReserveImageSpace() {
530700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    // Reserve where the image will be loaded up front so that other parts of test set up don't
531700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    // accidentally end up colliding with the fixed memory address when we need to load the image.
532700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    image_reservation_.reset(MemMap::MapAnonymous("Image reservation", (byte*)ART_BASE_ADDRESS,
533700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                                  (size_t)100 * 1024 * 1024,  // 100MB
534700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                                  PROT_NONE));
535700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
536700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
537700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  void UnreserveImageSpace() {
538700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    image_reservation_.reset();
539700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
540700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
54134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string android_data_;
542b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string art_cache_;
543a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const DexFile* java_lang_dex_file_;  // owned by runtime_
5449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
54590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<Runtime> runtime_;
5460e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  // Owned by the runtime
5477a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro  ClassLinker* class_linker_;
5480e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  UniquePtr<Compiler> compiler_;
549e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes  UniquePtr<std::set<std::string> > image_classes_;
5509baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5519baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private:
5524d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  std::vector<const DexFile*> opened_dex_files_;
553700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  UniquePtr<MemMap> image_reservation_;
554578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom};
555578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
556b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
557b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// rather than aborting, so be careful!
558b264f081424642b06b0bbe7102781895d41faa9dElliott Hughesclass CheckJniAbortCatcher {
559b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes public:
560b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
561b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = Hook;
562b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = &actual_;
563b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
564b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
565b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  ~CheckJniAbortCatcher() {
566b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = NULL;
567b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = NULL;
56856ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    EXPECT_TRUE(actual_.empty()) << actual_;
569b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
570b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
571b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  void Check(const char* expected_text) {
572b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
573b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "Expected to find: " << expected_text << "\n"
574b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "In the output   : " << actual_;
5753f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    actual_.clear();
576b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
577b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
578b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes private:
579b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  static void Hook(void* data, const std::string& reason) {
5803f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    // We use += because when we're hooking the aborts like this, multiple problems can be found.
5813f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    *reinterpret_cast<std::string*>(data) += reason;
582b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
583b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
584b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  JavaVMExt* vm_;
585b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  std::string actual_;
586b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
587b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
588b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes};
589b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
590934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom}  // namespace art
59134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
59234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std {
59334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
59434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself?
59534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T>
59634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
59714134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes  os << ::art::ToString(rhs);
59834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  return os;
59934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}
60034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
60134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}  // namespace std
602