blob: 15893b2b031305303e1c66b5e07c5abaca86b89a [file] [log] [blame]
Brian Carlstrom934486c2011-07-12 23:42:50 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Brian Carlstromb0460ea2011-07-29 10:08:05 -07003#include <dirent.h>
Elliott Hughes0af55432011-08-17 18:37:28 -07004#include <dlfcn.h>
Brian Carlstrom27ec9612011-09-19 20:20:38 -07005#include <sys/mman.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -07006#include <sys/stat.h>
7#include <sys/types.h>
8
Elliott Hughes90a33692011-08-30 13:27:07 -07009#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070010#include "base64.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070011#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070012#include "class_loader.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070013#include "compiler.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -070014#include "constants.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070015#include "dex_file.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070016#include "file.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070017#include "gtest/gtest.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070018#include "heap.h"
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -080019#include "macros.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070020#include "oat_file.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080021#include "object_utils.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070022#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070023#include "runtime.h"
Elliott Hughes14134a12011-09-30 16:55:51 -070024#include "stl_util.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070025#include "stringprintf.h"
26#include "thread.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070027#include "unicode/uclean.h"
28#include "unicode/uvernum.h"
29
Brian Carlstrom934486c2011-07-12 23:42:50 -070030namespace art {
31
Brian Carlstrom9f30b382011-08-28 22:41:38 -070032static inline const DexFile* OpenDexFileBase64(const char* base64,
33 const std::string& location) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -070034 // decode base64
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070035 CHECK(base64 != NULL);
36 size_t length;
Elliott Hughes4d6850c2012-01-18 15:55:06 -080037 UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
38 CHECK(dex_bytes.get() != NULL);
Brian Carlstrom33f741e2011-10-03 11:24:05 -070039
40 // write to provided file
41 UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
42 CHECK(file.get() != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -080043 if (!file->WriteFully(dex_bytes.get(), length)) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -070044 PLOG(FATAL) << "Failed to write base64 as dex file";
45 }
46 file.reset();
47
48 // read dex file
Brian Carlstrom58ae9412011-10-04 00:56:06 -070049 const DexFile* dex_file = DexFile::Open(location, "");
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070050 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -070051 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070052}
53
Brian Carlstromdb4d5402011-08-09 12:18:28 -070054class ScratchFile {
55 public:
56 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -070057 filename_ = getenv("ANDROID_DATA");
58 filename_ += "/TmpFile-XXXXXX";
59 fd_ = mkstemp(&filename_[0]);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070060 CHECK_NE(-1, fd_);
Elliott Hughes234da572011-11-03 22:13:06 -070061 file_.reset(OS::FileFromFd(GetFilename(), fd_));
Brian Carlstromdb4d5402011-08-09 12:18:28 -070062 }
63
64 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -070065 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070066 CHECK_EQ(0, unlink_result);
67 int close_result = close(fd_);
68 CHECK_EQ(0, close_result);
69 }
70
71 const char* GetFilename() const {
Elliott Hughes34023802011-08-30 12:06:17 -070072 return filename_.c_str();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070073 }
74
Elliott Hughes234da572011-11-03 22:13:06 -070075 File* GetFile() const {
76 return file_.get();
77 }
78
Brian Carlstromdb4d5402011-08-09 12:18:28 -070079 int GetFd() const {
80 return fd_;
81 }
82
83 private:
Elliott Hughes34023802011-08-30 12:06:17 -070084 std::string filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070085 int fd_;
Elliott Hughes234da572011-11-03 22:13:06 -070086 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070087};
88
Brian Carlstromf734cf52011-08-17 16:28:14 -070089class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070090 public:
Brian Carlstrom3320cf42011-10-04 14:58:28 -070091
92 static void MakeExecutable(const ByteArray* code_array) {
93 CHECK(code_array != NULL);
94 MakeExecutable(code_array->GetData(), code_array->GetLength());
95 }
96
97 static void MakeExecutable(const std::vector<uint8_t>& code) {
98 CHECK_NE(code.size(), 0U);
99 MakeExecutable(&code[0], code.size());
100 }
101
Brian Carlstromae826982011-11-09 01:33:42 -0800102 // Create an OatMethod based on pointers (for unit tests)
103 OatFile::OatMethod CreateOatMethod(const void* code,
104 const size_t frame_size_in_bytes,
105 const uint32_t core_spill_mask,
106 const uint32_t fp_spill_mask,
107 const uint32_t* mapping_table,
108 const uint16_t* vmap_table,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800109 const uint8_t* gc_map,
Brian Carlstromae826982011-11-09 01:33:42 -0800110 const Method::InvokeStub* invoke_stub) {
111 return OatFile::OatMethod(NULL,
112 reinterpret_cast<uint32_t>(code),
113 frame_size_in_bytes,
114 core_spill_mask,
115 fp_spill_mask,
116 reinterpret_cast<uint32_t>(mapping_table),
117 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800118 reinterpret_cast<uint32_t>(gc_map),
Brian Carlstromae826982011-11-09 01:33:42 -0800119 reinterpret_cast<uint32_t>(invoke_stub));
120 }
121
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700122 void MakeExecutable(Method* method) {
123 CHECK(method != NULL);
124
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800125 MethodHelper mh(method);
Ian Rogers0571d352011-11-03 19:51:38 -0700126 const CompiledInvokeStub* compiled_invoke_stub =
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800127 compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700128 CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
129 const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
130 MakeExecutable(invoke_stub);
131 const Method::InvokeStub* method_invoke_stub
132 = reinterpret_cast<const Method::InvokeStub*>(&invoke_stub[0]);
133 LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
134 << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
135
136 if (!method->IsAbstract()) {
Ian Rogers0571d352011-11-03 19:51:38 -0700137 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
138 const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
139 const CompiledMethod* compiled_method =
140 compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
141 method->GetDexMethodIndex()));
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700142 CHECK(compiled_method != NULL) << PrettyMethod(method);
143 const std::vector<uint8_t>& code = compiled_method->GetCode();
144 MakeExecutable(code);
145 const void* method_code
146 = CompiledMethod::CodePointer(&code[0], compiled_method->GetInstructionSet());
147 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800148 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
149 compiled_method->GetFrameSizeInBytes(),
150 compiled_method->GetCoreSpillMask(),
151 compiled_method->GetFpSpillMask(),
152 &compiled_method->GetMappingTable()[0],
153 &compiled_method->GetVmapTable()[0],
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800154 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800155 method_invoke_stub);
156 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700157 } else {
158 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
159 const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
160 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800161 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
162 kStackAlignment,
163 0,
164 0,
165 NULL,
166 NULL,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800167 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800168 method_invoke_stub);
169 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700170 }
171 }
172
173 static void MakeExecutable(const void* code_start, size_t code_length) {
174 CHECK(code_start != NULL);
175 CHECK_NE(code_length, 0U);
176 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700177 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700178 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700179 uintptr_t len = limit - base;
180 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800181 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800182
Ian Rogers16341552011-10-10 11:33:06 -0700183 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800184 // Only uses __builtin___clear_cache if GCC >= 4.3.3
185#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700186 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800187#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800188 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
189 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800190#else
191#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800192#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700193 }
194
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700195 protected:
196 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700197 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
198
Elliott Hughes0af55432011-08-17 18:37:28 -0700199 if (is_host_) {
200 // $ANDROID_ROOT is set on the device, but not on the host.
201 // We need to set this so that icu4c can find its locale data.
202 std::string root;
203 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800204#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700205 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800206#elif defined(__APPLE__)
207 root += "/out/host/darwin-x86";
208#else
209#error unsupported OS
210#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700211 setenv("ANDROID_ROOT", root.c_str(), 1);
212 }
213
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700214 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
215 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700216 if (mkdtemp(&android_data_[0]) == NULL) {
217 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
218 }
Elliott Hughes34023802011-08-30 12:06:17 -0700219 setenv("ANDROID_DATA", android_data_.c_str(), 1);
220 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700221 art_cache_.append("/art-cache");
222 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
223 ASSERT_EQ(mkdir_result, 0);
224
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700225 java_lang_dex_file_.reset(GetLibCoreDex());
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700226
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700227 std::string boot_class_path;
228 boot_class_path += "-Xbootclasspath:";
229 boot_class_path += GetLibCoreDexFileName();
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700230
Ian Rogers30fab402012-01-23 15:43:46 -0800231 std::string min_heap_string = StringPrintf("-Xms%dm",Heap::kInitialSize / MB);
232 std::string max_heap_string = StringPrintf("-Xmx%dm",Heap::kMaximumSize / MB);
233
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700234 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700235 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700236 options.push_back(std::make_pair(boot_class_path.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700237 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800238 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
239 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700240 runtime_.reset(Runtime::Create(options, false));
Elliott Hughes90a33692011-08-30 13:27:07 -0700241 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700242 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700243
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700244 InstructionSet instruction_set = kNone;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700245#if defined(__i386__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700246 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700247#elif defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700248 instruction_set = kThumb2;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700249#endif
Elliott Hughes8add92d2012-01-18 18:18:43 -0800250 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700251 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700252 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700253 Runtime::TrampolineType type = Runtime::TrampolineType(i);
254 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700255 runtime_->SetResolutionStubArray(
256 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700257 }
258 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700259 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700260 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
261 if (!runtime_->HasCalleeSaveMethod(type)) {
262 runtime_->SetCalleeSaveMethod(
263 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
264 }
265 }
Brian Carlstromae826982011-11-09 01:33:42 -0800266 compiler_.reset(new Compiler(instruction_set, false, NULL));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700267
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700268 Heap::VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700269 }
270
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700271 virtual void TearDown() {
272 const char* android_data = getenv("ANDROID_DATA");
273 ASSERT_TRUE(android_data != NULL);
274 DIR* dir = opendir(art_cache_.c_str());
275 ASSERT_TRUE(dir != NULL);
276 while (true) {
277 struct dirent entry;
278 struct dirent* entry_ptr;
279 int readdir_result = readdir_r(dir, &entry, &entry_ptr);
280 ASSERT_EQ(0, readdir_result);
281 if (entry_ptr == NULL) {
282 break;
283 }
284 if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
285 continue;
286 }
287 std::string filename(art_cache_);
288 filename.push_back('/');
289 filename.append(entry_ptr->d_name);
290 int unlink_result = unlink(filename.c_str());
291 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400292 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700293 closedir(dir);
294 int rmdir_cache_result = rmdir(art_cache_.c_str());
295 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700296 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700297 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700298
299 // icu4c has a fixed 10-element array "gCommonICUDataArray".
300 // If we run > 10 tests, we fill that array and u_setCommonData fails.
301 // There's a function to clear the array, but it's not public...
302 typedef void (*IcuCleanupFn)();
303 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
304 CHECK(sym != NULL);
305 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
306 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700307
Ian Rogers0e073f72011-09-09 10:45:46 -0700308 compiler_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800309 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700310
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700311 Heap::VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700312 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400313
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700314 std::string GetLibCoreDexFileName() {
315 if (is_host_) {
316 const char* host_dir = getenv("ANDROID_HOST_OUT");
317 CHECK(host_dir != NULL);
318 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
319 }
320 return std::string("/system/framework/core.jar");
321 }
322
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700323 const DexFile* GetLibCoreDex() {
Elliott Hughes95572412011-12-13 18:14:20 -0800324 std::string libcore_dex_file_name(GetLibCoreDexFileName());
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700325 return DexFile::Open(libcore_dex_file_name, "");
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400326 }
327
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700328 const DexFile* OpenTestDexFile(const char* name) {
329 CHECK(name != NULL);
330 std::string filename;
331 if (is_host_) {
332 // on the host, just read target dex file
333 filename += getenv("ANDROID_PRODUCT_OUT");
334 }
Brian Carlstrom47a0d5a2011-10-12 21:20:05 -0700335 filename += "/data/art-test/art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700336 filename += name;
337 filename += ".jar";
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700338 const DexFile* dex_file = DexFile::Open(filename, "");
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700339 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800340 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700341 return dex_file;
342 }
343
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700344 ClassLoader* LoadDex(const char* dex_name) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700345 const DexFile* dex_file = OpenTestDexFile(dex_name);
346 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700347 class_linker_->RegisterDexFile(*dex_file);
348 std::vector<const DexFile*> class_path;
349 class_path.push_back(dex_file);
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700350 SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path));
351 CHECK(class_loader.get() != NULL);
352 Thread::Current()->SetClassLoaderOverride(class_loader.get());
353 return class_loader.get();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700354 }
355
Brian Carlstromaded5f72011-10-07 17:15:04 -0700356 void CompileClass(const ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800357 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800358 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700359 CHECK(klass != NULL) << "Class not found " << class_name;
360 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
361 CompileMethod(klass->GetDirectMethod(i));
362 }
363 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
364 CompileMethod(klass->GetVirtualMethod(i));
365 }
366 }
367
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700368 void CompileMethod(Method* method) {
369 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700370 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700371 MakeExecutable(method);
372
Ian Rogers169c9a72011-11-13 20:13:17 -0800373 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700374 }
375
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700376 void CompileDirectMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700377 const char* class_name,
378 const char* method_name,
379 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800380 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800381 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700382 CHECK(klass != NULL) << "Class not found " << class_name;
383 Method* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700384 CHECK(method != NULL) << "Direct method not found: "
385 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700386 CompileMethod(method);
387 }
388
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700389 void CompileVirtualMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700390 const char* class_name,
391 const char* method_name,
392 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800393 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800394 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700395 CHECK(klass != NULL) << "Class not found " << class_name;
396 Method* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700397 CHECK(method != NULL) << "Virtual method not found: "
398 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700399 CompileMethod(method);
400 }
401
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700402 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700403 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700404 std::string art_cache_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700405 UniquePtr<const DexFile> java_lang_dex_file_;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700406 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700407 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700408 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700409 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700410 UniquePtr<Compiler> compiler_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700411
412 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800413 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700414};
415
Brian Carlstrom934486c2011-07-12 23:42:50 -0700416} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700417
418namespace std {
419
420// TODO: isn't gtest supposed to be able to print STL types for itself?
421template <typename T>
422std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700423 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700424 return os;
425}
426
427} // namespace std