blob: 58d0219643172550070daee58727498939453ada [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 Liao1cb0ae72012-03-16 15:30:19 -0700180 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700181 CHECK_NE(code.size(), 0U);
182 MakeExecutable(&code[0], code.size());
183 }
184
Brian Carlstromae826982011-11-09 01:33:42 -0800185 // Create an OatMethod based on pointers (for unit tests)
186 OatFile::OatMethod CreateOatMethod(const void* code,
187 const size_t frame_size_in_bytes,
188 const uint32_t core_spill_mask,
189 const uint32_t fp_spill_mask,
190 const uint32_t* mapping_table,
191 const uint16_t* vmap_table,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800192 const uint8_t* gc_map,
Brian Carlstromae826982011-11-09 01:33:42 -0800193 const Method::InvokeStub* invoke_stub) {
194 return OatFile::OatMethod(NULL,
195 reinterpret_cast<uint32_t>(code),
196 frame_size_in_bytes,
197 core_spill_mask,
198 fp_spill_mask,
199 reinterpret_cast<uint32_t>(mapping_table),
200 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800201 reinterpret_cast<uint32_t>(gc_map),
Logan Chien0c717dd2012-03-28 18:31:07 +0800202 reinterpret_cast<uint32_t>(invoke_stub)
203#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800204 , 0
Logan Chien0c717dd2012-03-28 18:31:07 +0800205#endif
206 );
Brian Carlstromae826982011-11-09 01:33:42 -0800207 }
208
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700209 void MakeExecutable(Method* method) {
210 CHECK(method != NULL);
211
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800212 MethodHelper mh(method);
Ian Rogers0571d352011-11-03 19:51:38 -0700213 const CompiledInvokeStub* compiled_invoke_stub =
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800214 compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700215 CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800216
Logan Chien971bf3f2012-05-01 15:47:55 +0800217 const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
218 MakeExecutable(invoke_stub);
219 const Method::InvokeStub* method_invoke_stub =
220 reinterpret_cast<const Method::InvokeStub*>(
Logan Chien4284bb92012-06-06 15:30:44 +0800221 CompiledCode::CodePointer(&invoke_stub[0],
222 compiled_invoke_stub->GetInstructionSet()));
Logan Chienf7015fd2012-03-18 01:19:37 +0800223
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700224 LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
225 << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
226
227 if (!method->IsAbstract()) {
Ian Rogers0571d352011-11-03 19:51:38 -0700228 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
229 const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
230 const CompiledMethod* compiled_method =
231 compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
232 method->GetDexMethodIndex()));
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700233 CHECK(compiled_method != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800234
Logan Chien971bf3f2012-05-01 15:47:55 +0800235 const std::vector<uint8_t>& code = compiled_method->GetCode();
236 MakeExecutable(code);
237 const void* method_code = CompiledMethod::CodePointer(&code[0],
238 compiled_method->GetInstructionSet());
Logan Chienf7015fd2012-03-18 01:19:37 +0800239
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700240 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Logan Chienf7015fd2012-03-18 01:19:37 +0800241
Brian Carlstromae826982011-11-09 01:33:42 -0800242 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
243 compiled_method->GetFrameSizeInBytes(),
244 compiled_method->GetCoreSpillMask(),
245 compiled_method->GetFpSpillMask(),
246 &compiled_method->GetMappingTable()[0],
247 &compiled_method->GetVmapTable()[0],
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800248 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800249 method_invoke_stub);
250 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700251 } else {
252 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
253 const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
254 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800255 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
256 kStackAlignment,
257 0,
258 0,
259 NULL,
260 NULL,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800261 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800262 method_invoke_stub);
263 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700264 }
265 }
266
267 static void MakeExecutable(const void* code_start, size_t code_length) {
268 CHECK(code_start != NULL);
269 CHECK_NE(code_length, 0U);
270 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700271 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700272 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700273 uintptr_t len = limit - base;
274 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800275 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800276
Ian Rogers16341552011-10-10 11:33:06 -0700277 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800278 // Only uses __builtin___clear_cache if GCC >= 4.3.3
279#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700280 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800281#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800282 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
283 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800284#else
285#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800286#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700287 }
288
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700289 protected:
290 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700291 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
292
Elliott Hughes0af55432011-08-17 18:37:28 -0700293 if (is_host_) {
294 // $ANDROID_ROOT is set on the device, but not on the host.
295 // We need to set this so that icu4c can find its locale data.
296 std::string root;
297 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800298#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700299 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800300#elif defined(__APPLE__)
301 root += "/out/host/darwin-x86";
302#else
303#error unsupported OS
304#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700305 setenv("ANDROID_ROOT", root.c_str(), 1);
306 }
307
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700308 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
309 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700310 if (mkdtemp(&android_data_[0]) == NULL) {
311 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
312 }
Elliott Hughes34023802011-08-30 12:06:17 -0700313 setenv("ANDROID_DATA", android_data_.c_str(), 1);
314 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700315 art_cache_.append("/art-cache");
316 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
317 ASSERT_EQ(mkdir_result, 0);
318
Brian Carlstroma004aa92012-02-08 18:05:09 -0800319 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
320 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700321
Elliott Hughes699f9f42012-01-27 13:04:16 -0800322 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB));
323 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800324
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700325 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700326 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800327 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700328 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800329 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
330 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700331 runtime_.reset(Runtime::Create(options, false));
Elliott Hughes90a33692011-08-30 13:27:07 -0700332 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700333 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700334
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700335 InstructionSet instruction_set = kNone;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700336#if defined(__i386__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700337 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700338#elif defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700339 instruction_set = kThumb2;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700340#endif
Elliott Hughes8add92d2012-01-18 18:18:43 -0800341 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700342 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700343 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700344 Runtime::TrampolineType type = Runtime::TrampolineType(i);
345 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700346 runtime_->SetResolutionStubArray(
347 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700348 }
349 }
Ian Rogers19846512012-02-24 11:42:47 -0800350 if (!runtime_->HasResolutionMethod()) {
351 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
352 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700353 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700354 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
355 if (!runtime_->HasCalleeSaveMethod(type)) {
356 runtime_->SetCalleeSaveMethod(
357 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
358 }
359 }
Ian Rogers19846512012-02-24 11:42:47 -0800360 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700361 image_classes_.reset(new std::set<std::string>);
362 compiler_.reset(new Compiler(instruction_set, true, 2, false, image_classes_.get(),
Brian Carlstromba0668e2012-03-26 13:14:07 -0700363 true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700364
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800365 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700366 }
367
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700368 virtual void TearDown() {
369 const char* android_data = getenv("ANDROID_DATA");
370 ASSERT_TRUE(android_data != NULL);
371 DIR* dir = opendir(art_cache_.c_str());
372 ASSERT_TRUE(dir != NULL);
373 while (true) {
Elliott Hughes7b9d9962012-04-20 18:48:18 -0700374 dirent entry;
375 dirent* entry_ptr;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700376 int readdir_result = readdir_r(dir, &entry, &entry_ptr);
377 ASSERT_EQ(0, readdir_result);
378 if (entry_ptr == NULL) {
379 break;
380 }
381 if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
382 continue;
383 }
384 std::string filename(art_cache_);
385 filename.push_back('/');
386 filename.append(entry_ptr->d_name);
387 int unlink_result = unlink(filename.c_str());
388 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400389 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700390 closedir(dir);
391 int rmdir_cache_result = rmdir(art_cache_.c_str());
392 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700393 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700394 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700395
396 // icu4c has a fixed 10-element array "gCommonICUDataArray".
397 // If we run > 10 tests, we fill that array and u_setCommonData fails.
398 // There's a function to clear the array, but it's not public...
399 typedef void (*IcuCleanupFn)();
400 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
401 CHECK(sym != NULL);
402 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
403 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700404
Ian Rogers0e073f72011-09-09 10:45:46 -0700405 compiler_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700406 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800407 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700408
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800409 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700410 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400411
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700412 std::string GetLibCoreDexFileName() {
413 if (is_host_) {
414 const char* host_dir = getenv("ANDROID_HOST_OUT");
415 CHECK(host_dir != NULL);
416 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
417 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800418 return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700419 }
420
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700421 const DexFile* OpenTestDexFile(const char* name) {
422 CHECK(name != NULL);
423 std::string filename;
424 if (is_host_) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700425 filename += getenv("ANDROID_HOST_OUT");
426 filename += "/framework/";
427 } else {
428 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700429 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700430 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700431 filename += name;
432 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800433 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700434 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800435 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700436 return dex_file;
437 }
438
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700439 ClassLoader* LoadDex(const char* dex_name) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700440 const DexFile* dex_file = OpenTestDexFile(dex_name);
441 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700442 class_linker_->RegisterDexFile(*dex_file);
443 std::vector<const DexFile*> class_path;
444 class_path.push_back(dex_file);
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700445 SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path));
446 CHECK(class_loader.get() != NULL);
447 Thread::Current()->SetClassLoaderOverride(class_loader.get());
448 return class_loader.get();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700449 }
450
Ian Rogers365c1022012-06-22 15:05:28 -0700451 void CompileClass(ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800452 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800453 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700454 CHECK(klass != NULL) << "Class not found " << class_name;
455 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
456 CompileMethod(klass->GetDirectMethod(i));
457 }
458 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
459 CompileMethod(klass->GetVirtualMethod(i));
460 }
461 }
462
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700463 void CompileMethod(Method* method) {
464 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700465 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700466 MakeExecutable(method);
467
Ian Rogers169c9a72011-11-13 20:13:17 -0800468 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700469 }
470
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700471 void CompileDirectMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700472 const char* class_name,
473 const char* method_name,
474 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800475 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800476 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700477 CHECK(klass != NULL) << "Class not found " << class_name;
478 Method* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700479 CHECK(method != NULL) << "Direct method not found: "
480 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700481 CompileMethod(method);
482 }
483
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700484 void CompileVirtualMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700485 const char* class_name,
486 const char* method_name,
487 const char* signature) {
Elliott Hughes95572412011-12-13 18:14:20 -0800488 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800489 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700490 CHECK(klass != NULL) << "Class not found " << class_name;
491 Method* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700492 CHECK(method != NULL) << "Virtual method not found: "
493 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700494 CompileMethod(method);
495 }
496
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700497 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700498 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700499 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800500 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700501 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700502 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700503 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700504 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700505 UniquePtr<Compiler> compiler_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700506 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700507
508 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800509 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700510};
511
Elliott Hughesb264f082012-04-06 17:10:10 -0700512// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
513// rather than aborting, so be careful!
514class CheckJniAbortCatcher {
515 public:
516 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
517 vm_->check_jni_abort_hook = Hook;
518 vm_->check_jni_abort_hook_data = &actual_;
519 }
520
521 ~CheckJniAbortCatcher() {
522 vm_->check_jni_abort_hook = NULL;
523 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700524 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700525 }
526
527 void Check(const char* expected_text) {
528 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
529 << "Expected to find: " << expected_text << "\n"
530 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700531 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700532 }
533
534 private:
535 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700536 // We use += because when we're hooking the aborts like this, multiple problems can be found.
537 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700538 }
539
540 JavaVMExt* vm_;
541 std::string actual_;
542
543 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
544};
545
Brian Carlstrom934486c2011-07-12 23:42:50 -0700546} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700547
548namespace std {
549
550// TODO: isn't gtest supposed to be able to print STL types for itself?
551template <typename T>
552std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700553 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700554 return os;
555}
556
557} // namespace std