common_test.h revision b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0
1934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom// Copyright 2011 Google Inc. All Rights Reserved.
2934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
3b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <dirent.h>
40af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h>
527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h>
6b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/stat.h>
7b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/types.h>
8b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
990a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "UniquePtr.h"
10578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h"
111f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h"
129baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "compiler.h"
132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "constants.h"
14578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h"
1533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "file.h"
1690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h"
171f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "heap.h"
187a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#include "macros.h"
193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
2133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "os.h"
221f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
2314134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes#include "stl_util.h"
2490a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "stringprintf.h"
2590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h"
260af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uclean.h"
270af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uvernum.h"
280af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
29934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art {
30934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
31b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstromstatic const byte kBase64Map[256] = {
32b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
34b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
36b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
37b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
38b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
39b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom   19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
40b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
41b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom   37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
42b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom   49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
44b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
45b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
46b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
47b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
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, 255, 255, 255, 255, 255,
52b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  255, 255, 255, 255
54b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom};
55b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom
56b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrombyte* DecodeBase64(const char* src, size_t* dst_size) {
57b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  std::vector<byte> tmp;
58b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  unsigned long t = 0, y = 0;
59b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  int g = 3;
60b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  for (size_t i = 0; src[i] != '\0'; ++i) {
61b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    byte c = kBase64Map[src[i] & 0xFF];
62b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (c == 255) continue;
63b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    // the final = symbols are read and used to trim the remaining bytes
64b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (c == 254) {
65b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      c = 0;
66b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      // prevent g < 0 which would potentially allow an overflow later
67b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (--g < 0) {
68b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        return NULL;
69b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
70b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    } else if (g != 3) {
71b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      // we only allow = to be at the end
72b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      return NULL;
73b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    }
74b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    t = (t << 6) | c;
75b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    if (++y == 4) {
76b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      tmp.push_back((t >> 16) & 255);
77b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (g > 1) {
78b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        tmp.push_back((t >> 8) & 255);
79b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
80b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      if (g > 2) {
81b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom        tmp.push_back(t & 255);
82b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      }
83b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom      y = t = 0;
84b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    }
85b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
86b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  if (y != 0) {
87b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    return NULL;
88b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
89b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  UniquePtr<byte[]> dst(new byte[tmp.size()]);
90b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  if (dst_size != NULL) {
91b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom    *dst_size = tmp.size();
92b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  }
93b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  std::copy(tmp.begin(), tmp.end(), dst.get());
94b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom  return dst.release();
95b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom}
96b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom
979f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic inline const DexFile* OpenDexFileBase64(const char* base64,
989f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom                                               const std::string& location) {
9933f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // decode base64
100578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(base64 != NULL);
101578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  size_t length;
1024d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
1034d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  CHECK(dex_bytes.get() != NULL);
10433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
10533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // write to provided file
10633f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
10733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  CHECK(file.get() != NULL);
1084d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  if (!file->WriteFully(dex_bytes.get(), length)) {
10933f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom    PLOG(FATAL) << "Failed to write base64 as dex file";
11033f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  }
11133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  file.reset();
11233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
11333f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // read dex file
11458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  const DexFile* dex_file = DexFile::Open(location, "");
115578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(dex_file != NULL);
116f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  return dex_file;
117578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}
118578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
119db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile {
120db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public:
121db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ScratchFile() {
12234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ = getenv("ANDROID_DATA");
12334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ += "/TmpFile-XXXXXX";
12434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    fd_ = mkstemp(&filename_[0]);
125db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_NE(-1, fd_);
126234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    file_.reset(OS::FileFromFd(GetFilename(), fd_));
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    int close_result = close(fd_);
133db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, close_result);
134db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
135db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
136db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  const char* GetFilename() const {
13734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    return filename_.c_str();
138db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
139db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
140234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  File* GetFile() const {
141234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    return file_.get();
142234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
143234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes
144db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int GetFd() const {
145db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    return fd_;
146db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
147db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
148db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private:
14934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string filename_;
150db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int fd_;
151234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  UniquePtr<File> file_;
152db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom};
153db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
154f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test {
1559baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public:
1563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const ByteArray* code_array) {
1583320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_array != NULL);
1593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(code_array->GetData(), code_array->GetLength());
1603320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1613320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const std::vector<uint8_t>& code) {
1633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code.size(), 0U);
1643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(&code[0], code.size());
1653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
167ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Create an OatMethod based on pointers (for unit tests)
168ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  OatFile::OatMethod CreateOatMethod(const void* code,
169ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const size_t frame_size_in_bytes,
170ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t core_spill_mask,
171ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t fp_spill_mask,
172ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t* mapping_table,
173ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint16_t* vmap_table,
174e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                     const uint8_t* gc_map,
175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const Method::InvokeStub* invoke_stub) {
176ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return OatFile::OatMethod(NULL,
177ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(code),
178ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                frame_size_in_bytes,
179ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                core_spill_mask,
180ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                fp_spill_mask,
181ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(mapping_table),
182ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(vmap_table),
183e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                reinterpret_cast<uint32_t>(gc_map),
184ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(invoke_stub));
185ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
1873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  void MakeExecutable(Method* method) {
1883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(method != NULL);
1893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1906d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    MethodHelper mh(method);
1910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const CompiledInvokeStub* compiled_invoke_stub =
1926d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers        compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
1933320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
1943320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
1953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(invoke_stub);
1963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    const Method::InvokeStub* method_invoke_stub
1973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom        = reinterpret_cast<const Method::InvokeStub*>(&invoke_stub[0]);
1983320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
1993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom              << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
2003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    if (!method->IsAbstract()) {
2020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
2030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
2040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const CompiledMethod* compiled_method =
2050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers          compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
2060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                                                                 method->GetDexMethodIndex()));
2073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      CHECK(compiled_method != NULL) << PrettyMethod(method);
2083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const std::vector<uint8_t>& code = compiled_method->GetCode();
2093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      MakeExecutable(code);
2103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const void* method_code
2113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom          = CompiledMethod::CodePointer(&code[0], compiled_method->GetInstructionSet());
2123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
213ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
214ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFrameSizeInBytes(),
215ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetCoreSpillMask(),
216ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFpSpillMask(),
217ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetMappingTable()[0],
218ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetVmapTable()[0],
219e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
220ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
221ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(method);
2223320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    } else {
2233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
2243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
2253320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
226ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
227ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      kStackAlignment,
228ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
229ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
230ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
231ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
232e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
233ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
234ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(method);
2353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    }
2363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
2373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const void* code_start, size_t code_length) {
2393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_start != NULL);
2403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code_length, 0U);
2413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
2429baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t base = RoundDown(data, kPageSize);
2433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t limit = RoundUp(data + code_length, kPageSize);
2449baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t len = limit - base;
2459baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
2467a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom    CHECK_EQ(result, 0);
24724782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao
2481634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    // Flush instruction cache
24924782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Only uses __builtin___clear_cache if GCC >= 4.3.3
25024782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303
2511634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
2527a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#elif defined(__APPLE__)
25324782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
25424782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // need to generate clear_cache on x86.
2557a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else
2567a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#error unsupported
25724782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif
2589baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
2599baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
260578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom protected:
261578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  virtual void SetUp() {
2624a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom    is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
2634a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom
2640af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    if (is_host_) {
2650af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // $ANDROID_ROOT is set on the device, but not on the host.
2660af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // We need to set this so that icu4c can find its locale data.
2670af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      std::string root;
2680af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += getenv("ANDROID_BUILD_TOP");
269a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__)
2700af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += "/out/host/linux-x86";
271a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__)
272a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes      root += "/out/host/darwin-x86";
273a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else
274a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS
275a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif
2760af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      setenv("ANDROID_ROOT", root.c_str(), 1);
2770af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    }
2780af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
27969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
28069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
2810f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    if (mkdtemp(&android_data_[0]) == NULL) {
2820f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes      PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
2830f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    }
28434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    setenv("ANDROID_DATA", android_data_.c_str(), 1);
28534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    art_cache_.append(android_data_.c_str());
286b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    art_cache_.append("/art-cache");
287b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int mkdir_result = mkdir(art_cache_.c_str(), 0700);
288b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(mkdir_result, 0);
289b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
2909b06a0d87757d76b05e5f310ce2b9a5a8c746bdfElliott Hughes    java_lang_dex_file_.reset(DexFile::Open(GetLibCoreDexFileName(), ""));
291578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
29258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    std::string boot_class_path;
29358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    boot_class_path += "-Xbootclasspath:";
29458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    boot_class_path += GetLibCoreDexFileName();
295578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
296699f9f42058ce438930ee0a5a9ae6451e3d8a2feElliott Hughes    std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB));
297699f9f42058ce438930ee0a5a9ae6451e3d8a2feElliott Hughes    std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB));
29830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers
29969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    Runtime::Options options;
300a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom    options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
30158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    options.push_back(std::make_pair(boot_class_path.c_str(), reinterpret_cast<void*>(NULL)));
30269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
30330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
30430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
30569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    runtime_.reset(Runtime::Create(options, false));
30690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes    ASSERT_TRUE(runtime_.get() != NULL);
3077a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro    class_linker_ = runtime_->GetClassLinker();
3080cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3094f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    InstructionSet instruction_set = kNone;
3102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#if defined(__i386__)
3114f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kX86;
3122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#elif defined(__arm__)
3134f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kThumb2;
3142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif
3158add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes    runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
3164f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
317362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
3181cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      Runtime::TrampolineType type = Runtime::TrampolineType(i);
3191cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      if (!runtime_->HasResolutionStubArray(type)) {
3204f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetResolutionStubArray(
3214f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            Compiler::CreateResolutionStub(instruction_set, type), type);
3221cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      }
3231cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    }
324362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
3254f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
3264f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      if (!runtime_->HasCalleeSaveMethod(type)) {
3274f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetCalleeSaveMethod(
3284f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
3294f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      }
3304f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
331ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    compiler_.reset(new Compiler(instruction_set, false, NULL));
3322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
3330cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Heap::VerifyHeap();  // Check for heap corruption before the test
334578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  }
335578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
336b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  virtual void TearDown() {
337b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    const char* android_data = getenv("ANDROID_DATA");
338b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(android_data != NULL);
339b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    DIR* dir = opendir(art_cache_.c_str());
340b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(dir != NULL);
341b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    while (true) {
342b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      struct dirent entry;
343b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      struct dirent* entry_ptr;
344b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int readdir_result = readdir_r(dir, &entry, &entry_ptr);
345b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, readdir_result);
346b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      if (entry_ptr == NULL) {
347b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        break;
348b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
349b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
350b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        continue;
351b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
352b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      std::string filename(art_cache_);
353b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.push_back('/');
354b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.append(entry_ptr->d_name);
355b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int unlink_result = unlink(filename.c_str());
356b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, unlink_result);
357b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    }
358b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    closedir(dir);
359b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int rmdir_cache_result = rmdir(art_cache_.c_str());
360b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_cache_result);
36134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int rmdir_data_result = rmdir(android_data_.c_str());
362b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_data_result);
3630af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
3640af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // icu4c has a fixed 10-element array "gCommonICUDataArray".
3650af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // If we run > 10 tests, we fill that array and u_setCommonData fails.
3660af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // There's a function to clear the array, but it's not public...
3670af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    typedef void (*IcuCleanupFn)();
3680af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
3690af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    CHECK(sym != NULL);
3700af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
3710af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    (*icu_cleanup_fn)();
3720cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3730e073f7b9386a461b470d30415a96480ab1b76afIan Rogers    compiler_.reset();
3744d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    STLDeleteElements(&opened_dex_files_);
3752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
3760cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Heap::VerifyHeap();  // Check for heap corruption after the test
377b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
378b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
379b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string GetLibCoreDexFileName() {
380b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    if (is_host_) {
381b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
382b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      CHECK(host_dir != NULL);
383b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
384ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson    }
385b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    return std::string("/system/framework/core.jar");
386b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
387ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
3889f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  const DexFile* OpenTestDexFile(const char* name) {
3899f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    CHECK(name != NULL);
3909f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    std::string filename;
3919f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    if (is_host_) {
3929f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom      // on the host, just read target dex file
3939f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom      filename += getenv("ANDROID_PRODUCT_OUT");
3949f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    }
39547a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom    filename += "/data/art-test/art-test-dex-";
3969f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += name;
3979f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += ".jar";
39858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    const DexFile* dex_file = DexFile::Open(filename, "");
39969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    CHECK(dex_file != NULL) << "Failed to open " << filename;
4004d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    opened_dex_files_.push_back(dex_file);
4019f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    return dex_file;
4029f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  }
4039f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
40440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  ClassLoader* LoadDex(const char* dex_name) {
4059baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    const DexFile* dex_file = OpenTestDexFile(dex_name);
4069baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(dex_file != NULL);
4079baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_linker_->RegisterDexFile(*dex_file);
4089baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    std::vector<const DexFile*> class_path;
4099baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_path.push_back(dex_file);
41040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path));
41140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    CHECK(class_loader.get() != NULL);
41240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    Thread::Current()->SetClassLoaderOverride(class_loader.get());
41340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    return class_loader.get();
4149baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4159baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
416aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  void CompileClass(const ClassLoader* class_loader, const char* class_name) {
417955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
418c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
419aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
420aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
421aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetDirectMethod(i));
422aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
423aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
424aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetVirtualMethod(i));
425aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
426aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
427aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
4289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  void CompileMethod(Method* method) {
4299baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(method != NULL);
4302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    compiler_->CompileOne(method);
4313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(method);
4323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
433169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    MakeExecutable(runtime_->GetJniDlsymLookupStub());
4349baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4359baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
43640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CompileDirectMethod(ClassLoader* class_loader,
4379baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* class_name,
4389baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* method_name,
4399baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* signature) {
440955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
441c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
4429baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
4439baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    Method* method = klass->FindDirectMethod(method_name, signature);
4440f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Direct method not found: "
4450f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
4469baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
4479baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4489baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
44940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CompileVirtualMethod(ClassLoader* class_loader,
4509baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* class_name,
4519baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* method_name,
4529baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* signature) {
453955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
454c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
4559baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
4569baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    Method* method = klass->FindVirtualMethod(method_name, signature);
4570f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Virtual method not found: "
4580f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
4599baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
4609baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4619baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4624a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  bool is_host_;
46334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string android_data_;
464b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string art_cache_;
46590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<const DexFile> java_lang_dex_file_;
4669ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
46790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<Runtime> runtime_;
4680e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  // Owned by the runtime
4697a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro  ClassLinker* class_linker_;
4700e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  UniquePtr<Compiler> compiler_;
4719baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4729baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private:
4734d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  std::vector<const DexFile*> opened_dex_files_;
474578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom};
475578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
476934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom}  // namespace art
47734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
47834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std {
47934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
48034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself?
48134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T>
48234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
48314134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes  os << ::art::ToString(rhs);
48434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  return os;
48534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}
48634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
48734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}  // namespace std
488