common_test.h revision 33e9566255c426e7a2c8fca5b8a1b6a94a5d352c
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"
304f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.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"
3958df32711162823647356afe25ae2cde04133563Jeff Hao#include "runtime_support.h"
4000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
41e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "ScopedLocalRef.h"
4290a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h"
430f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "UniquePtr.h"
4400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h"
450af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
46934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art {
47934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
48b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstromstatic const byte kBase64Map[256] = {
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, 255, 255, 255, 255, 255,
52b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
53b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
54b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
55a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18, // NOLINT
56a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes   19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255, // NOLINT
57b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
58a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes   37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48, // NOLINT
59a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes   49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
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, 255, 255, 255, 255, 255, 255, 255, 255,
70b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255
71b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom};
72b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom
73b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrombyte* DecodeBase64(const char* src, size_t* dst_size) {
74b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  std::vector<byte> tmp;
75a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  uint32_t t = 0, y = 0;
76b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  int g = 3;
77b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  for (size_t i = 0; src[i] != '\0'; ++i) {
78b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    byte c = kBase64Map[src[i] & 0xFF];
79b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (c == 255) continue;
80b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    // the final = symbols are read and used to trim the remaining bytes
81b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (c == 254) {
82b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      c = 0;
83b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      // prevent g < 0 which would potentially allow an overflow later
84b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (--g < 0) {
855147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom        *dst_size = 0;
86b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        return NULL;
87b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
88b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    } else if (g != 3) {
89b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      // we only allow = to be at the end
905147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom      *dst_size = 0;
91b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      return NULL;
92b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    }
93b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    t = (t << 6) | c;
94b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (++y == 4) {
95b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      tmp.push_back((t >> 16) & 255);
96b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (g > 1) {
97b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        tmp.push_back((t >> 8) & 255);
98b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
99b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (g > 2) {
100b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        tmp.push_back(t & 255);
101b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
102b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      y = t = 0;
103b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    }
104b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
105b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  if (y != 0) {
1065147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom    *dst_size = 0;
107b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    return NULL;
108b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
109b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  UniquePtr<byte[]> dst(new byte[tmp.size()]);
110b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  if (dst_size != NULL) {
111b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    *dst_size = tmp.size();
1125147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom  } else {
1135147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom    *dst_size = 0;
114b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
115b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  std::copy(tmp.begin(), tmp.end(), dst.get());
116b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  return dst.release();
117b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom}
118b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom
119db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile {
120db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public:
121db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ScratchFile() {
12234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ = getenv("ANDROID_DATA");
12334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ += "/TmpFile-XXXXXX";
124761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    int fd = mkstemp(&filename_[0]);
125761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    CHECK_NE(-1, fd);
126761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    file_.reset(new File(fd, GetFilename()));
127db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
128db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
129db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ~ScratchFile() {
13034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int unlink_result = unlink(filename_.c_str());
131db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, unlink_result);
132db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
133db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
134a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const std::string& GetFilename() const {
135a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    return filename_;
136db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
137db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
138234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  File* GetFile() const {
139234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    return file_.get();
140234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
141234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes
142db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int GetFd() const {
143761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return file_->Fd();
144db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
145db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
146db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private:
14734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string filename_;
148234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  UniquePtr<File> file_;
149db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom};
150db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
151f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test {
1529baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public:
1532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static void MakeExecutable(const mirror::ByteArray* code_array) {
1543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_array != NULL);
1553320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(code_array->GetData(), code_array->GetLength());
1563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1581cb0ae742072b5ea2c7f677e6ad220ba01255daeShih-wei Liao  static void MakeExecutable(const std::vector<uint8_t>& code) {
1593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code.size(), 0U);
1603320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(&code[0], code.size());
1613320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
163ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Create an OatMethod based on pointers (for unit tests)
164ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  OatFile::OatMethod CreateOatMethod(const void* code,
165ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const size_t frame_size_in_bytes,
166ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t core_spill_mask,
167ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t fp_spill_mask,
168ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t* mapping_table,
169ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint16_t* vmap_table,
17074180cad94848107cf297d37e72437c5a6eecf1bJeff Hao                                     const uint8_t* gc_map) {
171ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return OatFile::OatMethod(NULL,
172ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(code),
173ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                frame_size_in_bytes,
174ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                core_spill_mask,
175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                fp_spill_mask,
176ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(mapping_table),
177ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(vmap_table),
17874180cad94848107cf297d37e72437c5a6eecf1bJeff Hao                                reinterpret_cast<uint32_t>(gc_map)
1790c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien                                );
180ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
181ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(method != NULL);
18474180cad94848107cf297d37e72437c5a6eecf1bJeff Hao    LOG(INFO) << "MakeExecutable " << PrettyMethod(method);
1853320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
186f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers    const CompiledMethod* compiled_method = NULL;
1873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    if (!method->IsAbstract()) {
1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
1894445a7e3398a6143939168097a3aa275b734504dIan Rogers      const DexFile& dex_file = *dex_cache->GetDexFile();
190f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers      compiled_method =
1911212a022fa5f8ef9585d765b1809521812af882cIan Rogers          compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(&dex_file,
1921212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                              method->GetDexMethodIndex()));
193f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
194c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum#ifndef ART_LIGHT_MODE
195f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers      CHECK(compiled_method != NULL) << PrettyMethod(method);
196f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers#endif
197f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers    }
198f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers    if (compiled_method != NULL) {
199971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      const std::vector<uint8_t>& code = compiled_method->GetCode();
200971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      MakeExecutable(code);
201971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      const void* method_code = CompiledMethod::CodePointer(&code[0],
202971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien                                                            compiled_method->GetInstructionSet());
2033320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
204ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
205ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFrameSizeInBytes(),
206ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetCoreSpillMask(),
207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFpSpillMask(),
208ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetMappingTable()[0],
209ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetVmapTable()[0],
21074180cad94848107cf297d37e72437c5a6eecf1bJeff Hao                                                      NULL);
211265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_method.LinkMethod(method);
2123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    } else {
213f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers      const void* method_code;
214f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers      if (method->IsAbstract()) {
21579fe539587d4c09244172d0168eeed0ec9770466Jeff Hao        method_code = GetAbstractMethodErrorStub();
216f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers      } else {
217f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers        // No code? You must mean to go into the interpreter.
218f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers        method_code = GetInterpreterEntryPoint();
219f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers      }
2203320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
221ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
222ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      kStackAlignment,
223ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
224ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
225ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
226ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
22774180cad94848107cf297d37e72437c5a6eecf1bJeff Hao                                                      NULL);
228265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_method.LinkMethod(method);
2293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    }
2303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
2313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const void* code_start, size_t code_length) {
2333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_start != NULL);
2343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code_length, 0U);
2353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
2369baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t base = RoundDown(data, kPageSize);
2373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t limit = RoundUp(data + code_length, kPageSize);
2389baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t len = limit - base;
2399baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
2407a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom    CHECK_EQ(result, 0);
24124782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao
2421634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    // Flush instruction cache
24324782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Only uses __builtin___clear_cache if GCC >= 4.3.3
24424782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303
2451634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
2467a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else
24733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers   LOG(FATAL) << "UNIMPLEMENTED: cache flush";
24824782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif
2499baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
2509baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
251761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  static void SetEnvironmentVariables(std::string& android_data) {
252761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
2530af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // $ANDROID_ROOT is set on the device, but not on the host.
2540af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // We need to set this so that icu4c can find its locale data.
2550af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      std::string root;
2560af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += getenv("ANDROID_BUILD_TOP");
257a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__)
2580af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += "/out/host/linux-x86";
259a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__)
260a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes      root += "/out/host/darwin-x86";
261a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else
262a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS
263a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif
2640af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      setenv("ANDROID_ROOT", root.c_str(), 1);
2652fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
2660af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    }
2670af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
26869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
269761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
270761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (mkdtemp(&android_data[0]) == NULL) {
271761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes      PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
2720f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    }
273761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    setenv("ANDROID_DATA", android_data.c_str(), 1);
274761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
275761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
276761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes protected:
277761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  static bool IsHost() {
278761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return (getenv("ANDROID_BUILD_TOP") != NULL);
279761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
280761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
281761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  virtual void SetUp() {
282761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    SetEnvironmentVariables(android_data_);
28334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    art_cache_.append(android_data_.c_str());
284b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    art_cache_.append("/art-cache");
285b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int mkdir_result = mkdir(art_cache_.c_str(), 0700);
286b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(mkdir_result, 0);
287b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
288a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
28933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    if (java_lang_dex_file_ == NULL) {
29033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers      LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "'\n";
29133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    }
292654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom    conscrypt_file_ = DexFile::Open(GetConscryptFileName(), GetConscryptFileName());
29333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    if (conscrypt_file_  == NULL) {
29433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers      LOG(FATAL) << "Could not open .dex file '" << GetConscryptFileName() << "'\n";
29533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    }
296a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    boot_class_path_.push_back(java_lang_dex_file_);
297654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom    boot_class_path_.push_back(conscrypt_file_);
298578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2990051be6d118c511308ed7764ef41e0d594292c49Mathieu Chartier    std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
3000051be6d118c511308ed7764ef41e0d594292c49Mathieu Chartier    std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
30130fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers
30269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    Runtime::Options options;
303a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom    options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
304a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
30569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
30630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
30730fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
30800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if(!Runtime::Create(options, false)) {
30900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      LOG(FATAL) << "Failed to create runtime";
31000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return;
31100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
31200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_.reset(Runtime::Current());
31300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
31400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // give it away now and then switch to a more managable ScopedObjectAccess.
31500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread::Current()->TransitionFromRunnableToSuspended(kNative);
31600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Whilst we're in native take the opportunity to initialize well known classes.
31700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
31800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
31990a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes    ASSERT_TRUE(runtime_.get() != NULL);
3207a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro    class_linker_ = runtime_->GetClassLinker();
3210cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3224f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    InstructionSet instruction_set = kNone;
323c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#if defined(__arm__)
3244f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kThumb2;
325c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#elif defined(__mips__)
326c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao    instruction_set = kMips;
327c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#elif defined(__i386__)
328c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao    instruction_set = kX86;
3292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif
330c531cefbfb5394413122e9f57d211ba436cff012buzbee
331c531cefbfb5394413122e9f57d211ba436cff012buzbee    // TODO: make selectable
332c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER)
333c531cefbfb5394413122e9f57d211ba436cff012buzbee    CompilerBackend compiler_backend = kPortable;
334c531cefbfb5394413122e9f57d211ba436cff012buzbee#else
335c531cefbfb5394413122e9f57d211ba436cff012buzbee    CompilerBackend compiler_backend = kQuick;
336c531cefbfb5394413122e9f57d211ba436cff012buzbee#endif
337c531cefbfb5394413122e9f57d211ba436cff012buzbee
3381984651929744dd603fd082e23eacd877b9bc177Ian Rogers    if (!runtime_->HasResolutionMethod()) {
3391984651929744dd603fd082e23eacd877b9bc177Ian Rogers      runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
3401984651929744dd603fd082e23eacd877b9bc177Ian Rogers    }
341362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
3424f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
3434f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      if (!runtime_->HasCalleeSaveMethod(type)) {
3444f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetCalleeSaveMethod(
3454f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
3464f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      }
3474f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
3481984651929744dd603fd082e23eacd877b9bc177Ian Rogers    class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
349e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset(new std::set<std::string>);
3508447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false,
351c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum                                              image_classes_.get(), true, true));
3522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
35302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
35402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    // pool is created by the runtime.
35502b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    runtime_->GetHeap()->CreateThreadPool();
35602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
35700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
358578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  }
359578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
360b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  virtual void TearDown() {
361b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    const char* android_data = getenv("ANDROID_DATA");
362b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(android_data != NULL);
363b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    DIR* dir = opendir(art_cache_.c_str());
364b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(dir != NULL);
3654696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes    dirent* e;
3664696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes    while ((e = readdir(dir)) != NULL) {
3674696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes      if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
368b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        continue;
369b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
370b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      std::string filename(art_cache_);
371b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.push_back('/');
3724696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes      filename.append(e->d_name);
373b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int unlink_result = unlink(filename.c_str());
374b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, unlink_result);
375b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    }
376b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    closedir(dir);
377b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int rmdir_cache_result = rmdir(art_cache_.c_str());
378b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_cache_result);
37934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int rmdir_data_result = rmdir(android_data_.c_str());
380b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_data_result);
3810af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
3820af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // icu4c has a fixed 10-element array "gCommonICUDataArray".
3830af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // If we run > 10 tests, we fill that array and u_setCommonData fails.
3840af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // There's a function to clear the array, but it's not public...
3850af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    typedef void (*IcuCleanupFn)();
3860af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
3870af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    CHECK(sym != NULL);
3880af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
3890af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    (*icu_cleanup_fn)();
3900cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3911212a022fa5f8ef9585d765b1809521812af882cIan Rogers    compiler_driver_.reset();
392e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset();
3934d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    STLDeleteElements(&opened_dex_files_);
3942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
395b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
396b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
397b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
398b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string GetLibCoreDexFileName() {
399265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return GetDexFileName("core");
400265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
401265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
402654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom  std::string GetConscryptFileName() {
403654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom    return GetDexFileName("conscrypt");
404654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom  }
405654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom
406265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string GetDexFileName(const std::string& jar_prefix) {
407761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
408b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
409b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      CHECK(host_dir != NULL);
410265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
411ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson    }
412265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
413b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
414ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
4153f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  std::string GetTestAndroidRoot() {
4163f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    if (IsHost()) {
4173f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
4183f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      CHECK(host_dir != NULL);
4193f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      return host_dir;
4203f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    }
4213f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    return GetAndroidRoot();
4223f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  }
4233f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom
42433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4259f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    CHECK(name != NULL);
4269f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    std::string filename;
427761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    if (IsHost()) {
428b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += getenv("ANDROID_HOST_OUT");
429b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/framework/";
430b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    } else {
431b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/data/nativetest/art/";
4329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    }
433b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    filename += "art-test-dex-";
4349f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += name;
4359f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += ".jar";
436a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const DexFile* dex_file = DexFile::Open(filename, filename);
43769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    CHECK(dex_file != NULL) << "Failed to open " << filename;
4384d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    opened_dex_files_.push_back(dex_file);
4399f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    return dex_file;
4409f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  }
4419f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
44233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4439baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    const DexFile* dex_file = OpenTestDexFile(dex_name);
4449baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(dex_file != NULL);
4459baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_linker_->RegisterDexFile(*dex_file);
4469baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    std::vector<const DexFile*> class_path;
4479baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_path.push_back(dex_file);
44800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccessUnchecked soa(Thread::Current());
44900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedLocalRef<jobject> class_loader_local(soa.Env(),
45000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
45100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
4522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
45300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
45400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return class_loader;
4559baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4569baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
45733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
45833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
459955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
4602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
461aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
462aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
463aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetDirectMethod(i));
464aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
465aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
466aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetVirtualMethod(i));
467aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
468aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
469aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
4702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4719baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(method != NULL);
4721212a022fa5f8ef9585d765b1809521812af882cIan Rogers    compiler_driver_->CompileOne(method);
4733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(method);
4749baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4759baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileDirectMethod(mirror::ClassLoader* class_loader,
4779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* class_name,
4789baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* method_name,
47900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                           const char* signature)
480b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
481955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
4822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
4839baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
4842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
4850f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Direct method not found: "
4860f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
4879baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
4889baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4899baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void CompileVirtualMethod(mirror::ClassLoader* class_loader,
4919baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* class_name,
4929baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* method_name,
49300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            const char* signature)
494b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
495955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
4962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
4979baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
4982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
4990f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Virtual method not found: "
5000f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
5019baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5029baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5039baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
504700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  void ReserveImageSpace() {
505700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    // Reserve where the image will be loaded up front so that other parts of test set up don't
506700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    // accidentally end up colliding with the fixed memory address when we need to load the image.
507a40307e8562c20d9b9ce46e773864d07d95512a1Ian Rogers    image_reservation_.reset(MemMap::MapAnonymous("image reservation", (byte*)ART_BASE_ADDRESS,
508700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                                  (size_t)100 * 1024 * 1024,  // 100MB
509700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                                  PROT_NONE));
510700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
511700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
512700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  void UnreserveImageSpace() {
513700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    image_reservation_.reset();
514700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
515700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
51634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string android_data_;
517b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string art_cache_;
518a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const DexFile* java_lang_dex_file_;  // owned by runtime_
519654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom  const DexFile* conscrypt_file_;  // owned by runtime_
5209ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
52190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<Runtime> runtime_;
5220e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  // Owned by the runtime
5237a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro  ClassLinker* class_linker_;
5241212a022fa5f8ef9585d765b1809521812af882cIan Rogers  UniquePtr<CompilerDriver> compiler_driver_;
525e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes  UniquePtr<std::set<std::string> > image_classes_;
5269baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5279baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private:
5284d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  std::vector<const DexFile*> opened_dex_files_;
529700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  UniquePtr<MemMap> image_reservation_;
530578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom};
531578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
532b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
533b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// rather than aborting, so be careful!
534b264f081424642b06b0bbe7102781895d41faa9dElliott Hughesclass CheckJniAbortCatcher {
535b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes public:
536b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
537b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = Hook;
538b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = &actual_;
539b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
540b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
541b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  ~CheckJniAbortCatcher() {
542b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = NULL;
543b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = NULL;
54456ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    EXPECT_TRUE(actual_.empty()) << actual_;
545b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
546b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
547b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  void Check(const char* expected_text) {
548b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
549b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "Expected to find: " << expected_text << "\n"
550b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "In the output   : " << actual_;
5513f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    actual_.clear();
552b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
553b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
554b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes private:
555b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  static void Hook(void* data, const std::string& reason) {
5563f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    // We use += because when we're hooking the aborts like this, multiple problems can be found.
5573f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    *reinterpret_cast<std::string*>(data) += reason;
558b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
559b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
560b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  JavaVMExt* vm_;
561b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  std::string actual_;
562b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
563b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
564b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes};
565b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
566265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// TODO: These tests were disabled for portable when we went to having
567265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// MCLinker link LLVM ELF output because we no longer just have code
568265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// blobs in memory. We'll need to dlopen to load and relocate
569265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// temporary output to resurrect these tests.
570265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER)
571265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
572265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#else
573265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define TEST_DISABLED_FOR_PORTABLE()
574265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif
575265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
576934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom}  // namespace art
57734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
57834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std {
57934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
58034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself?
58134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T>
58234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
58314134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes  os << ::art::ToString(rhs);
58434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  return os;
58534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}
58634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
58734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}  // namespace std
588