common_test.h revision 30fab40ee5a07af6b8c3b6b0e9438071695a57f4
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 "base64.h"
11578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h"
121f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h"
139baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "compiler.h"
142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "constants.h"
15578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h"
1633f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "file.h"
1790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h"
181f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "heap.h"
197a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#include "macros.h"
203320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
2233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "os.h"
231f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
2414134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes#include "stl_util.h"
2590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "stringprintf.h"
2690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h"
270af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uclean.h"
280af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uvernum.h"
290af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
30934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art {
31934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic inline const DexFile* OpenDexFileBase64(const char* base64,
339f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom                                               const std::string& location) {
3433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // decode base64
35578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(base64 != NULL);
36578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  size_t length;
374d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
384d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  CHECK(dex_bytes.get() != NULL);
3933f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
4033f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // write to provided file
4133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
4233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  CHECK(file.get() != NULL);
434d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  if (!file->WriteFully(dex_bytes.get(), length)) {
4433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom    PLOG(FATAL) << "Failed to write base64 as dex file";
4533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  }
4633f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  file.reset();
4733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom
4833f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  // read dex file
4958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  const DexFile* dex_file = DexFile::Open(location, "");
50578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  CHECK(dex_file != NULL);
51f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  return dex_file;
52578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}
53578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
54db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile {
55db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public:
56db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ScratchFile() {
5734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ = getenv("ANDROID_DATA");
5834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    filename_ += "/TmpFile-XXXXXX";
5934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    fd_ = mkstemp(&filename_[0]);
60db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_NE(-1, fd_);
61234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    file_.reset(OS::FileFromFd(GetFilename(), fd_));
62db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
63db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
64db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ~ScratchFile() {
6534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int unlink_result = unlink(filename_.c_str());
66db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, unlink_result);
67db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    int close_result = close(fd_);
68db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    CHECK_EQ(0, close_result);
69db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
70db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
71db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  const char* GetFilename() const {
7234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    return filename_.c_str();
73db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
74db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
75234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  File* GetFile() const {
76234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes    return file_.get();
77234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
78234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes
79db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int GetFd() const {
80db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom    return fd_;
81db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  }
82db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
83db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private:
8434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string filename_;
85db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  int fd_;
86234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  UniquePtr<File> file_;
87db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom};
88db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom
89f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test {
909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public:
913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
923320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const ByteArray* code_array) {
933320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_array != NULL);
943320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(code_array->GetData(), code_array->GetLength());
953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const std::vector<uint8_t>& code) {
983320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code.size(), 0U);
993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(&code[0], code.size());
1003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
102ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Create an OatMethod based on pointers (for unit tests)
103ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  OatFile::OatMethod CreateOatMethod(const void* code,
104ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const size_t frame_size_in_bytes,
105ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t core_spill_mask,
106ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t fp_spill_mask,
107ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint32_t* mapping_table,
108ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const uint16_t* vmap_table,
109e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                     const uint8_t* gc_map,
110ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                     const Method::InvokeStub* invoke_stub) {
111ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return OatFile::OatMethod(NULL,
112ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(code),
113ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                frame_size_in_bytes,
114ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                core_spill_mask,
115ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                fp_spill_mask,
116ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(mapping_table),
117ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(vmap_table),
118e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                reinterpret_cast<uint32_t>(gc_map),
119ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                reinterpret_cast<uint32_t>(invoke_stub));
120ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
121ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
1223320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  void MakeExecutable(Method* method) {
1233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(method != NULL);
1243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1256d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    MethodHelper mh(method);
1260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const CompiledInvokeStub* compiled_invoke_stub =
1276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers        compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
1283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
1293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
1303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(invoke_stub);
1313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    const Method::InvokeStub* method_invoke_stub
1323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom        = reinterpret_cast<const Method::InvokeStub*>(&invoke_stub[0]);
1333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
1343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom              << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
1353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    if (!method->IsAbstract()) {
1370571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
1380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
1390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      const CompiledMethod* compiled_method =
1400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers          compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
1410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                                                                 method->GetDexMethodIndex()));
1423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      CHECK(compiled_method != NULL) << PrettyMethod(method);
1433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const std::vector<uint8_t>& code = compiled_method->GetCode();
1443320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      MakeExecutable(code);
1453320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const void* method_code
1463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom          = CompiledMethod::CodePointer(&code[0], compiled_method->GetInstructionSet());
1473320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
148ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
149ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFrameSizeInBytes(),
150ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetCoreSpillMask(),
151ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      compiled_method->GetFpSpillMask(),
152ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetMappingTable()[0],
153ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      &compiled_method->GetVmapTable()[0],
154e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
155ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
156ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(method);
1573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    } else {
1583320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
1593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
1603320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
161ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
162ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      kStackAlignment,
163ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
164ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      0,
165ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
166ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      NULL,
167e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                      NULL,
168ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                                      method_invoke_stub);
169ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      oat_method.LinkMethodPointers(method);
1703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    }
1713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
1723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  static void MakeExecutable(const void* code_start, size_t code_length) {
1743320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(code_start != NULL);
1753320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK_NE(code_length, 0U);
1763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
1779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t base = RoundDown(data, kPageSize);
1783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    uintptr_t limit = RoundUp(data + code_length, kPageSize);
1799baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    uintptr_t len = limit - base;
1809baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
1817a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom    CHECK_EQ(result, 0);
18224782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao
1831634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    // Flush instruction cache
18424782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Only uses __builtin___clear_cache if GCC >= 4.3.3
18524782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303
1861634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
1877a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#elif defined(__APPLE__)
18824782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
18924782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    // need to generate clear_cache on x86.
1907a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else
1917a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#error unsupported
19224782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif
1939baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
1949baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
195578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom protected:
196578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  virtual void SetUp() {
1974a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom    is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
1984a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom
1990af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    if (is_host_) {
2000af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // $ANDROID_ROOT is set on the device, but not on the host.
2010af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      // We need to set this so that icu4c can find its locale data.
2020af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      std::string root;
2030af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += getenv("ANDROID_BUILD_TOP");
204a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__)
2050af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      root += "/out/host/linux-x86";
206a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__)
207a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes      root += "/out/host/darwin-x86";
208a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else
209a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS
210a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif
2110af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes      setenv("ANDROID_ROOT", root.c_str(), 1);
2120af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    }
2130af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
21469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
21569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
2160f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    if (mkdtemp(&android_data_[0]) == NULL) {
2170f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes      PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
2180f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    }
21934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    setenv("ANDROID_DATA", android_data_.c_str(), 1);
22034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    art_cache_.append(android_data_.c_str());
221b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    art_cache_.append("/art-cache");
222b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int mkdir_result = mkdir(art_cache_.c_str(), 0700);
223b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(mkdir_result, 0);
224b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
225a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes    java_lang_dex_file_.reset(GetLibCoreDex());
226578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
22758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    std::string boot_class_path;
22858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    boot_class_path += "-Xbootclasspath:";
22958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    boot_class_path += GetLibCoreDexFileName();
230578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
23130fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    std::string min_heap_string = StringPrintf("-Xms%dm",Heap::kInitialSize / MB);
23230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    std::string max_heap_string = StringPrintf("-Xmx%dm",Heap::kMaximumSize / MB);
23330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers
23469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    Runtime::Options options;
235a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom    options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
23658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    options.push_back(std::make_pair(boot_class_path.c_str(), reinterpret_cast<void*>(NULL)));
23769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
23830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
23930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
24069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    runtime_.reset(Runtime::Create(options, false));
24190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes    ASSERT_TRUE(runtime_.get() != NULL);
2427a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro    class_linker_ = runtime_->GetClassLinker();
2430cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2444f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    InstructionSet instruction_set = kNone;
2452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#if defined(__i386__)
2464f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kX86;
2472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#elif defined(__arm__)
2484f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    instruction_set = kThumb2;
2492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif
2508add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes    runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
2514f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
252362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
2531cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      Runtime::TrampolineType type = Runtime::TrampolineType(i);
2541cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      if (!runtime_->HasResolutionStubArray(type)) {
2554f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetResolutionStubArray(
2564f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            Compiler::CreateResolutionStub(instruction_set, type), type);
2571cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers      }
2581cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    }
259362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
2604f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
2614f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      if (!runtime_->HasCalleeSaveMethod(type)) {
2624f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        runtime_->SetCalleeSaveMethod(
2634f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
2644f0d07c783afef89703dce32c94440fc8621a29bIan Rogers      }
2654f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
266ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    compiler_.reset(new Compiler(instruction_set, false, NULL));
2672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
2680cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Heap::VerifyHeap();  // Check for heap corruption before the test
269578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  }
270578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
271b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  virtual void TearDown() {
272b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    const char* android_data = getenv("ANDROID_DATA");
273b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(android_data != NULL);
274b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    DIR* dir = opendir(art_cache_.c_str());
275b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_TRUE(dir != NULL);
276b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    while (true) {
277b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      struct dirent entry;
278b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      struct dirent* entry_ptr;
279b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int readdir_result = readdir_r(dir, &entry, &entry_ptr);
280b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, readdir_result);
281b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      if (entry_ptr == NULL) {
282b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        break;
283b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
284b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
285b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom        continue;
286b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      }
287b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      std::string filename(art_cache_);
288b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.push_back('/');
289b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      filename.append(entry_ptr->d_name);
290b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      int unlink_result = unlink(filename.c_str());
291b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      ASSERT_EQ(0, unlink_result);
292b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    }
293b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    closedir(dir);
294b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    int rmdir_cache_result = rmdir(art_cache_.c_str());
295b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_cache_result);
29634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes    int rmdir_data_result = rmdir(android_data_.c_str());
297b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    ASSERT_EQ(0, rmdir_data_result);
2980af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
2990af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // icu4c has a fixed 10-element array "gCommonICUDataArray".
3000af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // If we run > 10 tests, we fill that array and u_setCommonData fails.
3010af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    // There's a function to clear the array, but it's not public...
3020af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    typedef void (*IcuCleanupFn)();
3030af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
3040af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    CHECK(sym != NULL);
3050af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
3060af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes    (*icu_cleanup_fn)();
3070cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3080e073f7b9386a461b470d30415a96480ab1b76afIan Rogers    compiler_.reset();
3094d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    STLDeleteElements(&opened_dex_files_);
3102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
3110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Heap::VerifyHeap();  // Check for heap corruption after the test
312b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
313b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
314b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string GetLibCoreDexFileName() {
315b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    if (is_host_) {
316b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      const char* host_dir = getenv("ANDROID_HOST_OUT");
317b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      CHECK(host_dir != NULL);
318b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom      return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
319ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson    }
320b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    return std::string("/system/framework/core.jar");
321b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
322ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
3239f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  const DexFile* GetLibCoreDex() {
324955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string libcore_dex_file_name(GetLibCoreDexFileName());
32558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    return DexFile::Open(libcore_dex_file_name, "");
326ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson  }
327ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson
3289f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  const DexFile* OpenTestDexFile(const char* name) {
3299f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    CHECK(name != NULL);
3309f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    std::string filename;
3319f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    if (is_host_) {
3329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom      // on the host, just read target dex file
3339f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom      filename += getenv("ANDROID_PRODUCT_OUT");
3349f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    }
33547a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom    filename += "/data/art-test/art-test-dex-";
3369f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += name;
3379f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    filename += ".jar";
33858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    const DexFile* dex_file = DexFile::Open(filename, "");
33969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    CHECK(dex_file != NULL) << "Failed to open " << filename;
3404d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes    opened_dex_files_.push_back(dex_file);
3419f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom    return dex_file;
3429f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  }
3439f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
34440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  ClassLoader* LoadDex(const char* dex_name) {
3459baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    const DexFile* dex_file = OpenTestDexFile(dex_name);
3469baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(dex_file != NULL);
3479baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_linker_->RegisterDexFile(*dex_file);
3489baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    std::vector<const DexFile*> class_path;
3499baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    class_path.push_back(dex_file);
35040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path));
35140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    CHECK(class_loader.get() != NULL);
35240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    Thread::Current()->SetClassLoaderOverride(class_loader.get());
35340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    return class_loader.get();
3549baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
3559baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
356aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  void CompileClass(const ClassLoader* class_loader, const char* class_name) {
357955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
358c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
359aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
360aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
361aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetDirectMethod(i));
362aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
363aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
364aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      CompileMethod(klass->GetVirtualMethod(i));
365aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
366aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
367aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
3689baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  void CompileMethod(Method* method) {
3699baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(method != NULL);
3702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    compiler_->CompileOne(method);
3713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    MakeExecutable(method);
3723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
373169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    MakeExecutable(runtime_->GetJniDlsymLookupStub());
3749baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
3759baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
37640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CompileDirectMethod(ClassLoader* class_loader,
3779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* class_name,
3789baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* method_name,
3799baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                           const char* signature) {
380955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
381c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
3829baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
3839baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    Method* method = klass->FindDirectMethod(method_name, signature);
3840f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Direct method not found: "
3850f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
3869baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
3879baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
3889baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
38940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CompileVirtualMethod(ClassLoader* class_loader,
3909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* class_name,
3919baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* method_name,
3929baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom                            const char* signature) {
393955724179c6c739524f610023287f56b24dc31deElliott Hughes    std::string class_descriptor(DotToDescriptor(class_name));
394c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes    Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
3959baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CHECK(klass != NULL) << "Class not found " << class_name;
3969baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    Method* method = klass->FindVirtualMethod(method_name, signature);
3970f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes    CHECK(method != NULL) << "Virtual method not found: "
3980f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes                          << class_name << "." << method_name << signature;
3999baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom    CompileMethod(method);
4009baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom  }
4019baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4024a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  bool is_host_;
40334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  std::string android_data_;
404b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  std::string art_cache_;
40590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<const DexFile> java_lang_dex_file_;
4069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
40790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes  UniquePtr<Runtime> runtime_;
4080e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  // Owned by the runtime
4097a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro  ClassLinker* class_linker_;
4100e073f7b9386a461b470d30415a96480ab1b76afIan Rogers  UniquePtr<Compiler> compiler_;
4119baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
4129baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private:
4134d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  std::vector<const DexFile*> opened_dex_files_;
414578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom};
415578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
416934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom}  // namespace art
41734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
41834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std {
41934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
42034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself?
42134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T>
42234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
42314134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes  os << ::art::ToString(rhs);
42434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes  return os;
42534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}
42634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes
42734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes}  // namespace std
428