common_test.h revision 00f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abac
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
23578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h"
241f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h"
259baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "compiler.h"
26578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h"
2733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "file.h"
2890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h"
291f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "heap.h"
300f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "instruction_set.h"
317a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#include "macros.h"
323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
3433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "os.h"
351f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
3600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h"
3700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
3814134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes#include "stl_util.h"
3990a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "stringprintf.h"
4090a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h"
410af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uclean.h"
420af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uvernum.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
1199f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic inline const DexFile* OpenDexFileBase64(const char* base64,
1209f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom                                               const std::string& location) {
12133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // decode base64
122578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(base64 != NULL);
123578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  size_t length;
1244d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
1254d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  CHECK(dex_bytes.get() != NULL);
12633f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
12733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // write to provided file
12833f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
12933f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  CHECK(file.get() != NULL);
1304d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  if (!file->WriteFully(dex_bytes.get(), length)) {
13133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom    PLOG(FATAL) << "Failed to write base64 as dex file";
13233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  }
13333f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  file.reset();
13433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
13533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // read dex file
136a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const DexFile* dex_file = DexFile::Open(location, location);
137578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(dex_file != NULL);
138f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  return dex_file;
139578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}
140578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
141db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile {
142db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public:
143db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ScratchFile() {
14434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ = getenv("ANDROID_DATA");
14534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ += "/TmpFile-XXXXXX";
14634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    fd_ = mkstemp(&filename_[0]);
147db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_NE(-1, fd_);
148a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    file_.reset(OS::FileFromFd(GetFilename().c_str(), fd_));
149db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
150db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
151db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ~ScratchFile() {
15234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int unlink_result = unlink(filename_.c_str());
153db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, unlink_result);
154db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    int close_result = close(fd_);
155db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, close_result);
156db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
157db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
158a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const std::string& GetFilename() const {
159a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    return filename_;
160db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
161db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
162234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  File* GetFile() const {
163234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    return file_.get();
164234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
165234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes
166db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int GetFd() const {
167db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    return fd_;
168db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
169db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
170db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private:
17134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string filename_;
172db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int fd_;
173234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  UniquePtr<File> file_;
174db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom};
175db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
176f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test {
1779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public:
1783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const ByteArray* code_array) {
1793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_array != NULL);
1803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(code_array->GetData(), code_array->GetLength());
1813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1831cb0ae742072b5ea2c7f677e6ad220ba01255daeShih-wei Liao  static void MakeExecutable(const std::vector<uint8_t>& code) {
1843320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code.size(), 0U);
1853320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(&code[0], code.size());
1863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Create an OatMethod based on pointers (for unit tests)
189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  OatFile::OatMethod CreateOatMethod(const void* code,
190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const size_t frame_size_in_bytes,
191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t core_spill_mask,
192ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t fp_spill_mask,
193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t* mapping_table,
194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint16_t* vmap_table,
195e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                     const uint8_t* gc_map,
196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const Method::InvokeStub* invoke_stub) {
197ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return OatFile::OatMethod(NULL,
198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(code),
199ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                frame_size_in_bytes,
200ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                core_spill_mask,
201ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                fp_spill_mask,
202ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(mapping_table),
203ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(vmap_table),
204e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                reinterpret_cast<uint32_t>(gc_map),
2050c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien                                reinterpret_cast<uint32_t>(invoke_stub)
2060c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien#if defined(ART_USE_LLVM_COMPILER)
207971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien                              , 0
2080c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien#endif
2090c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien                                );
210ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
211ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
21200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void MakeExecutable(Method* method) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
2133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(method != NULL);
2143320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    MethodHelper mh(method);
2160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const CompiledInvokeStub* compiled_invoke_stub =
2176d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers        compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
2183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
219f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
220971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien    const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
221971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien    MakeExecutable(invoke_stub);
222971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien    const Method::InvokeStub* method_invoke_stub =
223971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien        reinterpret_cast<const Method::InvokeStub*>(
2244284bb9e8b79add46e61da897fa02df3625888f7Logan Chien          CompiledCode::CodePointer(&invoke_stub[0],
2254284bb9e8b79add46e61da897fa02df3625888f7Logan Chien                                    compiled_invoke_stub->GetInstructionSet()));
226f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
2273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
2283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom              << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
2293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    if (!method->IsAbstract()) {
2310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
2320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
2330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const CompiledMethod* compiled_method =
2340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers          compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
2350571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                                                                 method->GetDexMethodIndex()));
2363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      CHECK(compiled_method != NULL) << PrettyMethod(method);
237f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
238971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      const std::vector<uint8_t>& code = compiled_method->GetCode();
239971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      MakeExecutable(code);
240971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien      const void* method_code = CompiledMethod::CodePointer(&code[0],
241971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien                                                            compiled_method->GetInstructionSet());
242f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
2433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
244f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
245ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
246ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFrameSizeInBytes(),
247ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetCoreSpillMask(),
248ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFpSpillMask(),
249ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetMappingTable()[0],
250ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetVmapTable()[0],
251e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
252ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
253ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(method);
2543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    } else {
2553320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
2563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
2573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
258ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
259ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      kStackAlignment,
260ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
261ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
263ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
264e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
265ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
266ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(method);
2673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    }
2683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
2693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const void* code_start, size_t code_length) {
2713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_start != NULL);
2723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code_length, 0U);
2733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
2749baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t base = RoundDown(data, kPageSize);
2753320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t limit = RoundUp(data + code_length, kPageSize);
2769baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t len = limit - base;
2779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
2787a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom    CHECK_EQ(result, 0);
27924782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao
2801634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    // Flush instruction cache
28124782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Only uses __builtin___clear_cache if GCC >= 4.3.3
28224782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303
2831634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
2847a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#elif defined(__APPLE__)
28524782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
28624782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // need to generate clear_cache on x86.
2877a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else
2887a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#error unsupported
28924782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif
2909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
2919baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
292578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom protected:
293578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  virtual void SetUp() {
2944a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom    is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
2954a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom
2960af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    if (is_host_) {
2970af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // $ANDROID_ROOT is set on the device, but not on the host.
2980af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // We need to set this so that icu4c can find its locale data.
2990af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      std::string root;
3000af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += getenv("ANDROID_BUILD_TOP");
301a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__)
3020af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += "/out/host/linux-x86";
303a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__)
304a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes      root += "/out/host/darwin-x86";
305a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else
306a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS
307a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif
3080af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      setenv("ANDROID_ROOT", root.c_str(), 1);
3090af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    }
3100af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
31169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
31269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
3130f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    if (mkdtemp(&android_data_[0]) == NULL) {
3140f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes      PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
3150f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    }
31634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    setenv("ANDROID_DATA", android_data_.c_str(), 1);
31734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    art_cache_.append(android_data_.c_str());
318b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    art_cache_.append("/art-cache");
319b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int mkdir_result = mkdir(art_cache_.c_str(), 0700);
320b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(mkdir_result, 0);
321b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
322a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
323a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    boot_class_path_.push_back(java_lang_dex_file_);
324578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
325699f9f42058ce438930ee0a5a9ae6451e3d8a2feElliott Hughes    std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB));
326699f9f42058ce438930ee0a5a9ae6451e3d8a2feElliott Hughes    std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB));
32730fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers
32869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    Runtime::Options options;
329a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom    options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
330a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
33169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
33230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
33330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
33400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if(!Runtime::Create(options, false)) {
33500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      LOG(FATAL) << "Failed to create runtime";
33600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return;
33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
33800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_.reset(Runtime::Current());
33900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
34000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // give it away now and then switch to a more managable ScopedObjectAccess.
34100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread::Current()->TransitionFromRunnableToSuspended(kNative);
34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Whilst we're in native take the opportunity to initialize well known classes.
34300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
34400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
34590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes    ASSERT_TRUE(runtime_.get() != NULL);
3467a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro    class_linker_ = runtime_->GetClassLinker();
3470cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3484f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    InstructionSet instruction_set = kNone;
3492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#if defined(__i386__)
3504f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kX86;
3512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#elif defined(__arm__)
3524f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kThumb2;
3532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif
3548add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes    runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
3554f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
356362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
3571cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      Runtime::TrampolineType type = Runtime::TrampolineType(i);
3581cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      if (!runtime_->HasResolutionStubArray(type)) {
3594f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetResolutionStubArray(
3604f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            Compiler::CreateResolutionStub(instruction_set, type), type);
3611cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      }
3621cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    }
3631984651929744dd603fd082e23eacd877b9bc177Ian Rogers    if (!runtime_->HasResolutionMethod()) {
3641984651929744dd603fd082e23eacd877b9bc177Ian Rogers      runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
3651984651929744dd603fd082e23eacd877b9bc177Ian Rogers    }
366362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
3674f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
3684f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      if (!runtime_->HasCalleeSaveMethod(type)) {
3694f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetCalleeSaveMethod(
3704f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
3714f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      }
3724f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
3731984651929744dd603fd082e23eacd877b9bc177Ian Rogers    class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
374e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset(new std::set<std::string>);
375e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    compiler_.reset(new Compiler(instruction_set, true, 2, false, image_classes_.get(),
376ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                 true, true));
3772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
37800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
379578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  }
380578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
381b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  virtual void TearDown() {
382b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    const char* android_data = getenv("ANDROID_DATA");
383b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(android_data != NULL);
384b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    DIR* dir = opendir(art_cache_.c_str());
385b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(dir != NULL);
386b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    while (true) {
3877b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes      dirent entry;
3887b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes      dirent* entry_ptr;
389b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int readdir_result = readdir_r(dir, &entry, &entry_ptr);
390b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, readdir_result);
391b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      if (entry_ptr == NULL) {
392b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        break;
393b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
394b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
395b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        continue;
396b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
397b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      std::string filename(art_cache_);
398b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.push_back('/');
399b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.append(entry_ptr->d_name);
400b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int unlink_result = unlink(filename.c_str());
401b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, unlink_result);
402b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    }
403b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    closedir(dir);
404b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int rmdir_cache_result = rmdir(art_cache_.c_str());
405b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_cache_result);
40634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int rmdir_data_result = rmdir(android_data_.c_str());
407b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_data_result);
4080af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
4090af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // icu4c has a fixed 10-element array "gCommonICUDataArray".
4100af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // If we run > 10 tests, we fill that array and u_setCommonData fails.
4110af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // There's a function to clear the array, but it's not public...
4120af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    typedef void (*IcuCleanupFn)();
4130af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
4140af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    CHECK(sym != NULL);
4150af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
4160af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    (*icu_cleanup_fn)();
4170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
4180e073f7b9386a461b470d30415a96480ab1b76afIan Rogers    compiler_.reset();
419e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes    image_classes_.reset();
4204d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    STLDeleteElements(&opened_dex_files_);
4212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
422b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
423b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
424b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
425b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string GetLibCoreDexFileName() {
426b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    if (is_host_) {
427b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
428b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      CHECK(host_dir != NULL);
429b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
430ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson    }
431a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom    return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
432b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
433ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
4349f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  const DexFile* OpenTestDexFile(const char* name) {
4359f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    CHECK(name != NULL);
4369f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    std::string filename;
4379f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    if (is_host_) {
438b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += getenv("ANDROID_HOST_OUT");
439b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/framework/";
440b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    } else {
441b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom      filename += "/data/nativetest/art/";
4429f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    }
443b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom    filename += "art-test-dex-";
4449f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += name;
4459f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += ".jar";
446a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const DexFile* dex_file = DexFile::Open(filename, filename);
44769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    CHECK(dex_file != NULL) << "Failed to open " << filename;
4484d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    opened_dex_files_.push_back(dex_file);
4499f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    return dex_file;
4509f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  }
4519f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
45200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject LoadDex(const char* dex_name)
45300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
4549baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    const DexFile* dex_file = OpenTestDexFile(dex_name);
4559baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(dex_file != NULL);
4569baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_linker_->RegisterDexFile(*dex_file);
4579baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    std::vector<const DexFile*> class_path;
4589baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_path.push_back(dex_file);
45900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccessUnchecked soa(Thread::Current());
46000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedLocalRef<jobject> class_loader_local(soa.Env(),
46100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
46200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
46300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->SetClassLoaderOverride(soa.Decode<ClassLoader*>(class_loader_local.get()));
46400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
46500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return class_loader;
4669baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4679baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
468365c10235438607541fa2259a5fec48061b90bd8Ian Rogers  void CompileClass(ClassLoader* class_loader, const char* class_name) {
469955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
470c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
471aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
472aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
473aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetDirectMethod(i));
474aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
475aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
476aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetVirtualMethod(i));
477aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
478aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
479aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
48000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void CompileMethod(Method* method) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
4819baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(method != NULL);
4822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    compiler_->CompileOne(method);
4833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(method);
4843320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
485169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    MakeExecutable(runtime_->GetJniDlsymLookupStub());
4869baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4879baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
48840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CompileDirectMethod(ClassLoader* class_loader,
4899baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* class_name,
4909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* method_name,
49100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                           const char* signature)
49200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
493955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
494c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
4959baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
4969baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    Method* method = klass->FindDirectMethod(method_name, signature);
4970f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Direct method not found: "
4980f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
4999baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5009baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5019baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
50240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CompileVirtualMethod(ClassLoader* class_loader,
5039baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* class_name,
5049baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* method_name,
50500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            const char* signature)
50600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
507955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
508c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
5099baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
5109baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    Method* method = klass->FindVirtualMethod(method_name, signature);
5110f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Virtual method not found: "
5120f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
5139baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
5149baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
5159baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5164a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  bool is_host_;
51734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string android_data_;
518b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string art_cache_;
519a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  const DexFile* java_lang_dex_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_;
5240e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  UniquePtr<Compiler> compiler_;
525e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes  UniquePtr<std::set<std::string> > image_classes_;
5269baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
5279baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private:
5284d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  std::vector<const DexFile*> opened_dex_files_;
529578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom};
530578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
531b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
532b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// rather than aborting, so be careful!
533b264f081424642b06b0bbe7102781895d41faa9dElliott Hughesclass CheckJniAbortCatcher {
534b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes public:
535b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
536b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = Hook;
537b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = &actual_;
538b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
539b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
540b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  ~CheckJniAbortCatcher() {
541b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook = NULL;
542b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    vm_->check_jni_abort_hook_data = NULL;
54356ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    EXPECT_TRUE(actual_.empty()) << actual_;
544b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
545b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
546b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  void Check(const char* expected_text) {
547b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
548b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "Expected to find: " << expected_text << "\n"
549b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes        << "In the output   : " << actual_;
5503f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    actual_.clear();
551b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
552b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
553b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes private:
554b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  static void Hook(void* data, const std::string& reason) {
5553f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    // We use += because when we're hooking the aborts like this, multiple problems can be found.
5563f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    *reinterpret_cast<std::string*>(data) += reason;
557b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
558b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
559b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  JavaVMExt* vm_;
560b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  std::string actual_;
561b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
562b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
563b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes};
564b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
565934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom}  // namespace art
56634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
56734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std {
56834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
56934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself?
57034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T>
57134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
57214134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes  os << ::art::ToString(rhs);
57334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  return os;
57434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}
57534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
57634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}  // namespace std
577