blob: cdcac240ada8c64b3e37c2f3f2ff5b696b9b04b4 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian Carlstrom934486c2011-07-12 23:42:50 -070016
Brian Carlstromb0460ea2011-07-29 10:08:05 -070017#include <dirent.h>
Elliott Hughes0af55432011-08-17 18:37:28 -070018#include <dlfcn.h>
Brian Carlstrom27ec9612011-09-19 20:20:38 -070019#include <sys/mman.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070020#include <sys/stat.h>
21#include <sys/types.h>
22
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070023#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070024#include "class_loader.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070025#include "compiler.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070026#include "dex_file.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070027#include "file.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070028#include "gtest/gtest.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070029#include "heap.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070030#include "instruction_set.h"
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -080031#include "macros.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070032#include "oat_file.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080033#include "object_utils.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070034#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070035#include "runtime.h"
Elliott Hughes14134a12011-09-30 16:55:51 -070036#include "stl_util.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070037#include "stringprintf.h"
38#include "thread.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070039#include "unicode/uclean.h"
40#include "unicode/uvernum.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070041#include "UniquePtr.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070042
Brian Carlstrom934486c2011-07-12 23:42:50 -070043namespace art {
44
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080045static const byte kBase64Map[256] = {
46 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
47 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
50 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
51 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Elliott Hughesa21039c2012-06-21 12:09:25 -070052 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
53 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080054 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Elliott Hughesa21039c2012-06-21 12:09:25 -070055 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
56 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080057 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67 255, 255, 255, 255
68};
69
70byte* DecodeBase64(const char* src, size_t* dst_size) {
71 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070072 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080073 int g = 3;
74 for (size_t i = 0; src[i] != '\0'; ++i) {
75 byte c = kBase64Map[src[i] & 0xFF];
76 if (c == 255) continue;
77 // the final = symbols are read and used to trim the remaining bytes
78 if (c == 254) {
79 c = 0;
80 // prevent g < 0 which would potentially allow an overflow later
81 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070082 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080083 return NULL;
84 }
85 } else if (g != 3) {
86 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -070087 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080088 return NULL;
89 }
90 t = (t << 6) | c;
91 if (++y == 4) {
92 tmp.push_back((t >> 16) & 255);
93 if (g > 1) {
94 tmp.push_back((t >> 8) & 255);
95 }
96 if (g > 2) {
97 tmp.push_back(t & 255);
98 }
99 y = t = 0;
100 }
101 }
102 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700103 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800104 return NULL;
105 }
106 UniquePtr<byte[]> dst(new byte[tmp.size()]);
107 if (dst_size != NULL) {
108 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700109 } else {
110 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800111 }
112 std::copy(tmp.begin(), tmp.end(), dst.get());
113 return dst.release();
114}
115
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700116static inline const DexFile* OpenDexFileBase64(const char* base64,
117 const std::string& location) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700118 // decode base64
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700119 CHECK(base64 != NULL);
120 size_t length;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800121 UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
122 CHECK(dex_bytes.get() != NULL);
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700123
124 // write to provided file
125 UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
126 CHECK(file.get() != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800127 if (!file->WriteFully(dex_bytes.get(), length)) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700128 PLOG(FATAL) << "Failed to write base64 as dex file";
129 }
130 file.reset();
131
132 // read dex file
Brian Carlstroma004aa92012-02-08 18:05:09 -0800133 const DexFile* dex_file = DexFile::Open(location, location);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700134 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -0700135 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700136}
137
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700138class ScratchFile {
139 public:
140 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700141 filename_ = getenv("ANDROID_DATA");
142 filename_ += "/TmpFile-XXXXXX";
143 fd_ = mkstemp(&filename_[0]);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700144 CHECK_NE(-1, fd_);
Brian Carlstroma004aa92012-02-08 18:05:09 -0800145 file_.reset(OS::FileFromFd(GetFilename().c_str(), fd_));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700146 }
147
148 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700149 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700150 CHECK_EQ(0, unlink_result);
151 int close_result = close(fd_);
152 CHECK_EQ(0, close_result);
153 }
154
Brian Carlstroma004aa92012-02-08 18:05:09 -0800155 const std::string& GetFilename() const {
156 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700157 }
158
Elliott Hughes234da572011-11-03 22:13:06 -0700159 File* GetFile() const {
160 return file_.get();
161 }
162
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700163 int GetFd() const {
164 return fd_;
165 }
166
167 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700168 std::string filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700169 int fd_;
Elliott Hughes234da572011-11-03 22:13:06 -0700170 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700171};
172
Brian Carlstromf734cf52011-08-17 16:28:14 -0700173class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700174 public:
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700175 static void MakeExecutable(const ByteArray* code_array) {
176 CHECK(code_array != NULL);
177 MakeExecutable(code_array->GetData(), code_array->GetLength());
178 }
179
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -0800180#if !defined(ART_USE_LLVM_COMPILER) // LLVM compilation uses ELF instead
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700181 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700182 CHECK_NE(code.size(), 0U);
183 MakeExecutable(&code[0], code.size());
184 }
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700185#else
186 static void MakeExecutable(const std::vector<uint8_t>&) {}
187#endif
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700188
Brian Carlstromae826982011-11-09 01:33:42 -0800189 // Create an OatMethod based on pointers (for unit tests)
190 OatFile::OatMethod CreateOatMethod(const void* code,
191 const size_t frame_size_in_bytes,
192 const uint32_t core_spill_mask,
193 const uint32_t fp_spill_mask,
194 const uint32_t* mapping_table,
195 const uint16_t* vmap_table,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800196 const uint8_t* gc_map,
Brian Carlstromae826982011-11-09 01:33:42 -0800197 const Method::InvokeStub* invoke_stub) {
198 return OatFile::OatMethod(NULL,
199 reinterpret_cast<uint32_t>(code),
200 frame_size_in_bytes,
201 core_spill_mask,
202 fp_spill_mask,
203 reinterpret_cast<uint32_t>(mapping_table),
204 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800205 reinterpret_cast<uint32_t>(gc_map),
Logan Chien0c717dd2012-03-28 18:31:07 +0800206 reinterpret_cast<uint32_t>(invoke_stub)
207#if defined(ART_USE_LLVM_COMPILER)
208 , NULL,
Logan Chien937105a2012-04-02 02:37:37 +0800209 static_cast<uint16_t>(-1u),
210 static_cast<uint16_t>(-1u),
211 static_cast<uint16_t>(-1u),
TDYa127eead4ac2012-06-03 07:15:25 -0700212 static_cast<uint16_t>(-1u),
Logan Chien7a2a23a2012-06-06 11:01:00 +0800213 static_cast<uint16_t>(-1u),
Logan Chien937105a2012-04-02 02:37:37 +0800214 static_cast<uint16_t>(-1u)
Logan Chien0c717dd2012-03-28 18:31:07 +0800215#endif
216 );
Brian Carlstromae826982011-11-09 01:33:42 -0800217 }
218
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700219 void MakeExecutable(Method* method) {
220 CHECK(method != NULL);
221
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800222 MethodHelper mh(method);
Ian Rogers0571d352011-11-03 19:51:38 -0700223 const CompiledInvokeStub* compiled_invoke_stub =
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800224 compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700225 CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800226
227 const Method::InvokeStub* method_invoke_stub = NULL;
228 if (compiled_invoke_stub->IsExecutableInElf()) {
229 method_invoke_stub =
230 compiler_->GetMethodInvokeStubAddr(compiled_invoke_stub, method);
231 } else {
232 const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
233 MakeExecutable(invoke_stub);
Logan Chien4284bb92012-06-06 15:30:44 +0800234 method_invoke_stub = reinterpret_cast<const Method::InvokeStub*>(
235 CompiledCode::CodePointer(&invoke_stub[0],
236 compiled_invoke_stub->GetInstructionSet()));
Logan Chienf7015fd2012-03-18 01:19:37 +0800237 }
238
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700239 LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
240 << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
241
242 if (!method->IsAbstract()) {
Ian Rogers0571d352011-11-03 19:51:38 -0700243 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
244 const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
245 const CompiledMethod* compiled_method =
246 compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
247 method->GetDexMethodIndex()));
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700248 CHECK(compiled_method != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800249
250 const void* method_code = NULL;
251 if (compiled_method->IsExecutableInElf()) {
252 method_code = compiler_->GetMethodCodeAddr(compiled_method, method);
253 } else {
254 const std::vector<uint8_t>& code = compiled_method->GetCode();
255 MakeExecutable(code);
256 method_code = CompiledMethod::CodePointer(&code[0], compiled_method->GetInstructionSet());
257 }
258
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700259 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Logan Chienf7015fd2012-03-18 01:19:37 +0800260
Brian Carlstromae826982011-11-09 01:33:42 -0800261 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
262 compiled_method->GetFrameSizeInBytes(),
263 compiled_method->GetCoreSpillMask(),
264 compiled_method->GetFpSpillMask(),
265 &compiled_method->GetMappingTable()[0],
266 &compiled_method->GetVmapTable()[0],
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800267 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800268 method_invoke_stub);
269 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700270 } else {
271 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
272 const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
273 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800274 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
275 kStackAlignment,
276 0,
277 0,
278 NULL,
279 NULL,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800280 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800281 method_invoke_stub);
282 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700283 }
284 }
285
286 static void MakeExecutable(const void* code_start, size_t code_length) {
287 CHECK(code_start != NULL);
288 CHECK_NE(code_length, 0U);
289 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700290 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700291 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700292 uintptr_t len = limit - base;
293 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800294 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800295
Ian Rogers16341552011-10-10 11:33:06 -0700296 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800297 // Only uses __builtin___clear_cache if GCC >= 4.3.3
298#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700299 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800300#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800301 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
302 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800303#else
304#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800305#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700306 }
307
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700308 protected:
309 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700310 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
311
Elliott Hughes0af55432011-08-17 18:37:28 -0700312 if (is_host_) {
313 // $ANDROID_ROOT is set on the device, but not on the host.
314 // We need to set this so that icu4c can find its locale data.
315 std::string root;
316 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800317#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700318 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800319#elif defined(__APPLE__)
320 root += "/out/host/darwin-x86";
321#else
322#error unsupported OS
323#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700324 setenv("ANDROID_ROOT", root.c_str(), 1);
325 }
326
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700327 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
328 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700329 if (mkdtemp(&android_data_[0]) == NULL) {
330 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
331 }
Elliott Hughes34023802011-08-30 12:06:17 -0700332 setenv("ANDROID_DATA", android_data_.c_str(), 1);
333 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700334 art_cache_.append("/art-cache");
335 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
336 ASSERT_EQ(mkdir_result, 0);
337
Brian Carlstroma004aa92012-02-08 18:05:09 -0800338 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
339 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700340
Elliott Hughes699f9f42012-01-27 13:04:16 -0800341 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB));
342 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800343
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700344 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700345 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800346 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700347 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800348 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
349 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700350 runtime_.reset(Runtime::Create(options, false));
Elliott Hughes90a33692011-08-30 13:27:07 -0700351 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700352 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700353
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700354 InstructionSet instruction_set = kNone;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700355#if defined(__i386__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700356 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700357#elif defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700358 instruction_set = kThumb2;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700359#endif
Elliott Hughes8add92d2012-01-18 18:18:43 -0800360 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700361 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700362 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700363 Runtime::TrampolineType type = Runtime::TrampolineType(i);
364 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700365 runtime_->SetResolutionStubArray(
366 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700367 }
368 }
Ian Rogers19846512012-02-24 11:42:47 -0800369 if (!runtime_->HasResolutionMethod()) {
370 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
371 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700372 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700373 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
374 if (!runtime_->HasCalleeSaveMethod(type)) {
375 runtime_->SetCalleeSaveMethod(
376 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
377 }
378 }
Ian Rogers19846512012-02-24 11:42:47 -0800379 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700380 image_classes_.reset(new std::set<std::string>);
381 compiler_.reset(new Compiler(instruction_set, true, 2, false, image_classes_.get(),
Brian Carlstromba0668e2012-03-26 13:14:07 -0700382 true, true));
Shih-wei Liaoedbd6ed2012-03-04 22:32:59 -0800383#if defined(ART_USE_LLVM_COMPILER)
Logan Chienf7015fd2012-03-18 01:19:37 +0800384 compiler_->EnableAutoElfLoading();
Shih-wei Liaoedbd6ed2012-03-04 22:32:59 -0800385#endif
Ian Rogers2c8f6532011-09-02 17:16:34 -0700386
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800387 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700388 }
389
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700390 virtual void TearDown() {
391 const char* android_data = getenv("ANDROID_DATA");
392 ASSERT_TRUE(android_data != NULL);
393 DIR* dir = opendir(art_cache_.c_str());
394 ASSERT_TRUE(dir != NULL);
395 while (true) {
Elliott Hughes7b9d9962012-04-20 18:48:18 -0700396 dirent entry;
397 dirent* entry_ptr;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700398 int readdir_result = readdir_r(dir, &entry, &entry_ptr);
399 ASSERT_EQ(0, readdir_result);
400 if (entry_ptr == NULL) {
401 break;
402 }
403 if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
404 continue;
405 }
406 std::string filename(art_cache_);
407 filename.push_back('/');
408 filename.append(entry_ptr->d_name);
409 int unlink_result = unlink(filename.c_str());
410 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400411 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700412 closedir(dir);
413 int rmdir_cache_result = rmdir(art_cache_.c_str());
414 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700415 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700416 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700417
418 // icu4c has a fixed 10-element array "gCommonICUDataArray".
419 // If we run > 10 tests, we fill that array and u_setCommonData fails.
420 // There's a function to clear the array, but it's not public...
421 typedef void (*IcuCleanupFn)();
422 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
423 CHECK(sym != NULL);
424 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
425 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700426
Ian Rogers0e073f72011-09-09 10:45:46 -0700427 compiler_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700428 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800429 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700430
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800431 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700432 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400433
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700434 std::string GetLibCoreDexFileName() {
435 if (is_host_) {
436 const char* host_dir = getenv("ANDROID_HOST_OUT");
437 CHECK(host_dir != NULL);
438 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
439 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800440 return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700441 }
442
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700443 const DexFile* OpenTestDexFile(const char* name) {
444 CHECK(name != NULL);
445 std::string filename;
446 if (is_host_) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700447 filename += getenv("ANDROID_HOST_OUT");
448 filename += "/framework/";
449 } else {
450 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700451 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700452 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700453 filename += name;
454 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800455 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700456 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800457 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700458 return dex_file;
459 }
460
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700461 ClassLoader* LoadDex(const char* dex_name) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700462 const DexFile* dex_file = OpenTestDexFile(dex_name);
463 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700464 class_linker_->RegisterDexFile(*dex_file);
465 std::vector<const DexFile*> class_path;
466 class_path.push_back(dex_file);
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700467 SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path));
468 CHECK(class_loader.get() != NULL);
469 Thread::Current()->SetClassLoaderOverride(class_loader.get());
470 return class_loader.get();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700471 }
472
Ian Rogers365c1022012-06-22 15:05:28 -0700473 void CompileClass(ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800474 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800475 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700476 CHECK(klass != NULL) << "Class not found " << class_name;
477 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
478 CompileMethod(klass->GetDirectMethod(i));
479 }
480 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
481 CompileMethod(klass->GetVirtualMethod(i));
482 }
483 }
484
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700485 void CompileMethod(Method* method) {
486 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700487 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700488 MakeExecutable(method);
489
Ian Rogers169c9a72011-11-13 20:13:17 -0800490 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700491 }
492
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700493 void CompileDirectMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700494 const char* class_name,
495 const char* method_name,
496 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800497 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800498 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700499 CHECK(klass != NULL) << "Class not found " << class_name;
500 Method* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700501 CHECK(method != NULL) << "Direct method not found: "
502 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700503 CompileMethod(method);
504 }
505
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700506 void CompileVirtualMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700507 const char* class_name,
508 const char* method_name,
509 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800510 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800511 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700512 CHECK(klass != NULL) << "Class not found " << class_name;
513 Method* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700514 CHECK(method != NULL) << "Virtual method not found: "
515 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700516 CompileMethod(method);
517 }
518
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700519 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700520 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700521 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800522 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700523 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700524 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700525 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700526 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700527 UniquePtr<Compiler> compiler_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700528 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700529
530 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800531 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700532};
533
Elliott Hughesb264f082012-04-06 17:10:10 -0700534// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
535// rather than aborting, so be careful!
536class CheckJniAbortCatcher {
537 public:
538 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
539 vm_->check_jni_abort_hook = Hook;
540 vm_->check_jni_abort_hook_data = &actual_;
541 }
542
543 ~CheckJniAbortCatcher() {
544 vm_->check_jni_abort_hook = NULL;
545 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700546 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700547 }
548
549 void Check(const char* expected_text) {
550 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
551 << "Expected to find: " << expected_text << "\n"
552 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700553 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700554 }
555
556 private:
557 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700558 // We use += because when we're hooking the aborts like this, multiple problems can be found.
559 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700560 }
561
562 JavaVMExt* vm_;
563 std::string actual_;
564
565 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
566};
567
Brian Carlstrom934486c2011-07-12 23:42:50 -0700568} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700569
570namespace std {
571
572// TODO: isn't gtest supposed to be able to print STL types for itself?
573template <typename T>
574std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700575 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700576 return os;
577}
578
579} // namespace std