blob: 3b31bd440a944d288f2c74d9bca4f5fb7a868998 [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,
52 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
53 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
54 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
55 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
56 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 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;
72 unsigned long t = 0, y = 0;
73 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
176 static void MakeExecutable(const ByteArray* code_array) {
177 CHECK(code_array != NULL);
178 MakeExecutable(code_array->GetData(), code_array->GetLength());
179 }
180
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -0800181#if !defined(ART_USE_LLVM_COMPILER) // LLVM compilation uses ELF instead
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700182 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700183 CHECK_NE(code.size(), 0U);
184 MakeExecutable(&code[0], code.size());
185 }
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700186#else
187 static void MakeExecutable(const std::vector<uint8_t>&) {}
188#endif
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700189
Brian Carlstromae826982011-11-09 01:33:42 -0800190 // Create an OatMethod based on pointers (for unit tests)
191 OatFile::OatMethod CreateOatMethod(const void* code,
192 const size_t frame_size_in_bytes,
193 const uint32_t core_spill_mask,
194 const uint32_t fp_spill_mask,
195 const uint32_t* mapping_table,
196 const uint16_t* vmap_table,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800197 const uint8_t* gc_map,
Brian Carlstromae826982011-11-09 01:33:42 -0800198 const Method::InvokeStub* invoke_stub) {
199 return OatFile::OatMethod(NULL,
200 reinterpret_cast<uint32_t>(code),
201 frame_size_in_bytes,
202 core_spill_mask,
203 fp_spill_mask,
204 reinterpret_cast<uint32_t>(mapping_table),
205 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800206 reinterpret_cast<uint32_t>(gc_map),
Logan Chien0c717dd2012-03-28 18:31:07 +0800207 reinterpret_cast<uint32_t>(invoke_stub)
208#if defined(ART_USE_LLVM_COMPILER)
209 , NULL,
Logan Chien937105a2012-04-02 02:37:37 +0800210 static_cast<uint16_t>(-1u),
211 static_cast<uint16_t>(-1u),
212 static_cast<uint16_t>(-1u),
213 static_cast<uint16_t>(-1u)
Logan Chien0c717dd2012-03-28 18:31:07 +0800214#endif
215 );
Brian Carlstromae826982011-11-09 01:33:42 -0800216 }
217
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700218 void MakeExecutable(Method* method) {
219 CHECK(method != NULL);
220
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800221 MethodHelper mh(method);
Ian Rogers0571d352011-11-03 19:51:38 -0700222 const CompiledInvokeStub* compiled_invoke_stub =
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800223 compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700224 CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800225
226 const Method::InvokeStub* method_invoke_stub = NULL;
227 if (compiled_invoke_stub->IsExecutableInElf()) {
228 method_invoke_stub =
229 compiler_->GetMethodInvokeStubAddr(compiled_invoke_stub, method);
230 } else {
231 const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
232 MakeExecutable(invoke_stub);
233 method_invoke_stub = reinterpret_cast<const Method::InvokeStub*>(&invoke_stub[0]);
234 }
235
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700236 LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
237 << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
238
239 if (!method->IsAbstract()) {
Ian Rogers0571d352011-11-03 19:51:38 -0700240 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
241 const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
242 const CompiledMethod* compiled_method =
243 compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
244 method->GetDexMethodIndex()));
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700245 CHECK(compiled_method != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800246
247 const void* method_code = NULL;
248 if (compiled_method->IsExecutableInElf()) {
249 method_code = compiler_->GetMethodCodeAddr(compiled_method, method);
250 } else {
251 const std::vector<uint8_t>& code = compiled_method->GetCode();
252 MakeExecutable(code);
253 method_code = CompiledMethod::CodePointer(&code[0], compiled_method->GetInstructionSet());
254 }
255
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700256 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Logan Chienf7015fd2012-03-18 01:19:37 +0800257
Brian Carlstromae826982011-11-09 01:33:42 -0800258 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
259 compiled_method->GetFrameSizeInBytes(),
260 compiled_method->GetCoreSpillMask(),
261 compiled_method->GetFpSpillMask(),
262 &compiled_method->GetMappingTable()[0],
263 &compiled_method->GetVmapTable()[0],
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800264 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800265 method_invoke_stub);
266 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700267 } else {
268 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
269 const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
270 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800271 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
272 kStackAlignment,
273 0,
274 0,
275 NULL,
276 NULL,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800277 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800278 method_invoke_stub);
279 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700280 }
281 }
282
283 static void MakeExecutable(const void* code_start, size_t code_length) {
284 CHECK(code_start != NULL);
285 CHECK_NE(code_length, 0U);
286 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700287 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700288 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700289 uintptr_t len = limit - base;
290 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800291 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800292
Ian Rogers16341552011-10-10 11:33:06 -0700293 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800294 // Only uses __builtin___clear_cache if GCC >= 4.3.3
295#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700296 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800297#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800298 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
299 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800300#else
301#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800302#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700303 }
304
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700305 protected:
306 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700307 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
308
Elliott Hughes0af55432011-08-17 18:37:28 -0700309 if (is_host_) {
310 // $ANDROID_ROOT is set on the device, but not on the host.
311 // We need to set this so that icu4c can find its locale data.
312 std::string root;
313 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800314#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700315 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800316#elif defined(__APPLE__)
317 root += "/out/host/darwin-x86";
318#else
319#error unsupported OS
320#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700321 setenv("ANDROID_ROOT", root.c_str(), 1);
322 }
323
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700324 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
325 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700326 if (mkdtemp(&android_data_[0]) == NULL) {
327 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
328 }
Elliott Hughes34023802011-08-30 12:06:17 -0700329 setenv("ANDROID_DATA", android_data_.c_str(), 1);
330 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700331 art_cache_.append("/art-cache");
332 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
333 ASSERT_EQ(mkdir_result, 0);
334
Brian Carlstroma004aa92012-02-08 18:05:09 -0800335 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
336 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700337
Elliott Hughes699f9f42012-01-27 13:04:16 -0800338 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB));
339 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800340
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700341 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700342 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800343 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700344 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800345 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
346 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700347 runtime_.reset(Runtime::Create(options, false));
Elliott Hughes90a33692011-08-30 13:27:07 -0700348 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700349 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700350
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700351 InstructionSet instruction_set = kNone;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700352#if defined(__i386__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700353 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700354#elif defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700355 instruction_set = kThumb2;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700356#endif
Elliott Hughes8add92d2012-01-18 18:18:43 -0800357 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700358 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700359 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700360 Runtime::TrampolineType type = Runtime::TrampolineType(i);
361 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700362 runtime_->SetResolutionStubArray(
363 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700364 }
365 }
Ian Rogers19846512012-02-24 11:42:47 -0800366 if (!runtime_->HasResolutionMethod()) {
367 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
368 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700369 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700370 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
371 if (!runtime_->HasCalleeSaveMethod(type)) {
372 runtime_->SetCalleeSaveMethod(
373 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
374 }
375 }
Ian Rogers19846512012-02-24 11:42:47 -0800376 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700377 image_classes_.reset(new std::set<std::string>);
378 compiler_.reset(new Compiler(instruction_set, true, 2, false, image_classes_.get(),
Brian Carlstromba0668e2012-03-26 13:14:07 -0700379 true, true));
Shih-wei Liaoedbd6ed2012-03-04 22:32:59 -0800380#if defined(ART_USE_LLVM_COMPILER)
Logan Chienf7015fd2012-03-18 01:19:37 +0800381 compiler_->EnableAutoElfLoading();
Shih-wei Liaoedbd6ed2012-03-04 22:32:59 -0800382#endif
Ian Rogers2c8f6532011-09-02 17:16:34 -0700383
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800384 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700385 }
386
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700387 virtual void TearDown() {
388 const char* android_data = getenv("ANDROID_DATA");
389 ASSERT_TRUE(android_data != NULL);
390 DIR* dir = opendir(art_cache_.c_str());
391 ASSERT_TRUE(dir != NULL);
392 while (true) {
Elliott Hughes7b9d9962012-04-20 18:48:18 -0700393 dirent entry;
394 dirent* entry_ptr;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700395 int readdir_result = readdir_r(dir, &entry, &entry_ptr);
396 ASSERT_EQ(0, readdir_result);
397 if (entry_ptr == NULL) {
398 break;
399 }
400 if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
401 continue;
402 }
403 std::string filename(art_cache_);
404 filename.push_back('/');
405 filename.append(entry_ptr->d_name);
406 int unlink_result = unlink(filename.c_str());
407 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400408 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700409 closedir(dir);
410 int rmdir_cache_result = rmdir(art_cache_.c_str());
411 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700412 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700413 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700414
415 // icu4c has a fixed 10-element array "gCommonICUDataArray".
416 // If we run > 10 tests, we fill that array and u_setCommonData fails.
417 // There's a function to clear the array, but it's not public...
418 typedef void (*IcuCleanupFn)();
419 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
420 CHECK(sym != NULL);
421 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
422 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700423
Ian Rogers0e073f72011-09-09 10:45:46 -0700424 compiler_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700425 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800426 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700427
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800428 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700429 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400430
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700431 std::string GetLibCoreDexFileName() {
432 if (is_host_) {
433 const char* host_dir = getenv("ANDROID_HOST_OUT");
434 CHECK(host_dir != NULL);
435 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
436 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800437 return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700438 }
439
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700440 const DexFile* OpenTestDexFile(const char* name) {
441 CHECK(name != NULL);
442 std::string filename;
443 if (is_host_) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700444 filename += getenv("ANDROID_HOST_OUT");
445 filename += "/framework/";
446 } else {
447 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700448 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700449 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700450 filename += name;
451 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800452 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700453 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800454 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700455 return dex_file;
456 }
457
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700458 ClassLoader* LoadDex(const char* dex_name) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700459 const DexFile* dex_file = OpenTestDexFile(dex_name);
460 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700461 class_linker_->RegisterDexFile(*dex_file);
462 std::vector<const DexFile*> class_path;
463 class_path.push_back(dex_file);
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700464 SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path));
465 CHECK(class_loader.get() != NULL);
466 Thread::Current()->SetClassLoaderOverride(class_loader.get());
467 return class_loader.get();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700468 }
469
Brian Carlstromaded5f72011-10-07 17:15:04 -0700470 void CompileClass(const ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800471 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800472 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700473 CHECK(klass != NULL) << "Class not found " << class_name;
474 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
475 CompileMethod(klass->GetDirectMethod(i));
476 }
477 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
478 CompileMethod(klass->GetVirtualMethod(i));
479 }
480 }
481
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700482 void CompileMethod(Method* method) {
483 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700484 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700485 MakeExecutable(method);
486
Ian Rogers169c9a72011-11-13 20:13:17 -0800487 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700488 }
489
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700490 void CompileDirectMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700491 const char* class_name,
492 const char* method_name,
493 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800494 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800495 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700496 CHECK(klass != NULL) << "Class not found " << class_name;
497 Method* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700498 CHECK(method != NULL) << "Direct method not found: "
499 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700500 CompileMethod(method);
501 }
502
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700503 void CompileVirtualMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700504 const char* class_name,
505 const char* method_name,
506 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800507 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800508 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700509 CHECK(klass != NULL) << "Class not found " << class_name;
510 Method* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700511 CHECK(method != NULL) << "Virtual method not found: "
512 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700513 CompileMethod(method);
514 }
515
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700516 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700517 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700518 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800519 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700520 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700521 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700522 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700523 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700524 UniquePtr<Compiler> compiler_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700525 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700526
527 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800528 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700529};
530
Elliott Hughesb264f082012-04-06 17:10:10 -0700531// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
532// rather than aborting, so be careful!
533class CheckJniAbortCatcher {
534 public:
535 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
536 vm_->check_jni_abort_hook = Hook;
537 vm_->check_jni_abort_hook_data = &actual_;
538 }
539
540 ~CheckJniAbortCatcher() {
541 vm_->check_jni_abort_hook = NULL;
542 vm_->check_jni_abort_hook_data = NULL;
543 }
544
545 void Check(const char* expected_text) {
546 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
547 << "Expected to find: " << expected_text << "\n"
548 << "In the output : " << actual_;
549 }
550
551 private:
552 static void Hook(void* data, const std::string& reason) {
553 *reinterpret_cast<std::string*>(data) = reason;
554 }
555
556 JavaVMExt* vm_;
557 std::string actual_;
558
559 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
560};
561
Brian Carlstrom934486c2011-07-12 23:42:50 -0700562} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700563
564namespace std {
565
566// TODO: isn't gtest supposed to be able to print STL types for itself?
567template <typename T>
568std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700569 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700570 return os;
571}
572
573} // namespace std