blob: 67d2266da10d8003de2ae77268b872d60e6895ee [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"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070036#include "ScopedLocalRef.h"
37#include "scoped_thread_state_change.h"
Elliott Hughes14134a12011-09-30 16:55:51 -070038#include "stl_util.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070039#include "stringprintf.h"
40#include "thread.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070041#include "unicode/uclean.h"
42#include "unicode/uvernum.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070043#include "UniquePtr.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070044#include "well_known_classes.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070045
Brian Carlstrom934486c2011-07-12 23:42:50 -070046namespace art {
47
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080048static const byte kBase64Map[256] = {
49 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
53 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
54 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Elliott Hughesa21039c2012-06-21 12:09:25 -070055 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
56 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080057 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Elliott Hughesa21039c2012-06-21 12:09:25 -070058 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
59 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080060 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, 255, 255, 255, 255, 255, 255, 255, 255,
68 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
69 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
70 255, 255, 255, 255
71};
72
73byte* DecodeBase64(const char* src, size_t* dst_size) {
74 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070075 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080076 int g = 3;
77 for (size_t i = 0; src[i] != '\0'; ++i) {
78 byte c = kBase64Map[src[i] & 0xFF];
79 if (c == 255) continue;
80 // the final = symbols are read and used to trim the remaining bytes
81 if (c == 254) {
82 c = 0;
83 // prevent g < 0 which would potentially allow an overflow later
84 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070085 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080086 return NULL;
87 }
88 } else if (g != 3) {
89 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -070090 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080091 return NULL;
92 }
93 t = (t << 6) | c;
94 if (++y == 4) {
95 tmp.push_back((t >> 16) & 255);
96 if (g > 1) {
97 tmp.push_back((t >> 8) & 255);
98 }
99 if (g > 2) {
100 tmp.push_back(t & 255);
101 }
102 y = t = 0;
103 }
104 }
105 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700106 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800107 return NULL;
108 }
109 UniquePtr<byte[]> dst(new byte[tmp.size()]);
110 if (dst_size != NULL) {
111 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700112 } else {
113 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800114 }
115 std::copy(tmp.begin(), tmp.end(), dst.get());
116 return dst.release();
117}
118
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700119static inline const DexFile* OpenDexFileBase64(const char* base64,
120 const std::string& location) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700121 // decode base64
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700122 CHECK(base64 != NULL);
123 size_t length;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800124 UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
125 CHECK(dex_bytes.get() != NULL);
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700126
127 // write to provided file
128 UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
129 CHECK(file.get() != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800130 if (!file->WriteFully(dex_bytes.get(), length)) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700131 PLOG(FATAL) << "Failed to write base64 as dex file";
132 }
133 file.reset();
134
135 // read dex file
Brian Carlstroma004aa92012-02-08 18:05:09 -0800136 const DexFile* dex_file = DexFile::Open(location, location);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700137 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -0700138 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700139}
140
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700141class ScratchFile {
142 public:
143 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700144 filename_ = getenv("ANDROID_DATA");
145 filename_ += "/TmpFile-XXXXXX";
146 fd_ = mkstemp(&filename_[0]);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700147 CHECK_NE(-1, fd_);
Brian Carlstroma004aa92012-02-08 18:05:09 -0800148 file_.reset(OS::FileFromFd(GetFilename().c_str(), fd_));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700149 }
150
151 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700152 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700153 CHECK_EQ(0, unlink_result);
154 int close_result = close(fd_);
155 CHECK_EQ(0, close_result);
156 }
157
Brian Carlstroma004aa92012-02-08 18:05:09 -0800158 const std::string& GetFilename() const {
159 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700160 }
161
Elliott Hughes234da572011-11-03 22:13:06 -0700162 File* GetFile() const {
163 return file_.get();
164 }
165
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700166 int GetFd() const {
167 return fd_;
168 }
169
170 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700171 std::string filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700172 int fd_;
Elliott Hughes234da572011-11-03 22:13:06 -0700173 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700174};
175
Brian Carlstromf734cf52011-08-17 16:28:14 -0700176class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700177 public:
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700178 static void MakeExecutable(const ByteArray* code_array) {
179 CHECK(code_array != NULL);
180 MakeExecutable(code_array->GetData(), code_array->GetLength());
181 }
182
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700183 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700184 CHECK_NE(code.size(), 0U);
185 MakeExecutable(&code[0], code.size());
186 }
187
Brian Carlstromae826982011-11-09 01:33:42 -0800188 // Create an OatMethod based on pointers (for unit tests)
189 OatFile::OatMethod CreateOatMethod(const void* code,
190 const size_t frame_size_in_bytes,
191 const uint32_t core_spill_mask,
192 const uint32_t fp_spill_mask,
193 const uint32_t* mapping_table,
194 const uint16_t* vmap_table,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800195 const uint8_t* gc_map,
Mathieu Chartier66f19252012-09-18 08:57:04 -0700196 const AbstractMethod::InvokeStub* invoke_stub) {
Brian Carlstromae826982011-11-09 01:33:42 -0800197 return OatFile::OatMethod(NULL,
198 reinterpret_cast<uint32_t>(code),
199 frame_size_in_bytes,
200 core_spill_mask,
201 fp_spill_mask,
202 reinterpret_cast<uint32_t>(mapping_table),
203 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800204 reinterpret_cast<uint32_t>(gc_map),
Logan Chien0c717dd2012-03-28 18:31:07 +0800205 reinterpret_cast<uint32_t>(invoke_stub)
206#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800207 , 0
Logan Chien0c717dd2012-03-28 18:31:07 +0800208#endif
209 );
Brian Carlstromae826982011-11-09 01:33:42 -0800210 }
211
Mathieu Chartier66f19252012-09-18 08:57:04 -0700212 void MakeExecutable(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700213 CHECK(method != NULL);
214
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800215 MethodHelper mh(method);
Ian Rogers0571d352011-11-03 19:51:38 -0700216 const CompiledInvokeStub* compiled_invoke_stub =
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800217 compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700218 CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800219
Logan Chien971bf3f2012-05-01 15:47:55 +0800220 const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
221 MakeExecutable(invoke_stub);
Mathieu Chartier66f19252012-09-18 08:57:04 -0700222 const AbstractMethod::InvokeStub* method_invoke_stub =
223 reinterpret_cast<const AbstractMethod::InvokeStub*>(
Logan Chien4284bb92012-06-06 15:30:44 +0800224 CompiledCode::CodePointer(&invoke_stub[0],
225 compiled_invoke_stub->GetInstructionSet()));
Logan Chienf7015fd2012-03-18 01:19:37 +0800226
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700227 LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
228 << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
229
230 if (!method->IsAbstract()) {
Ian Rogers0571d352011-11-03 19:51:38 -0700231 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700232 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogers0571d352011-11-03 19:51:38 -0700233 const CompiledMethod* compiled_method =
234 compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
235 method->GetDexMethodIndex()));
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700236 CHECK(compiled_method != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800237
Logan Chien971bf3f2012-05-01 15:47:55 +0800238 const std::vector<uint8_t>& code = compiled_method->GetCode();
239 MakeExecutable(code);
240 const void* method_code = CompiledMethod::CodePointer(&code[0],
241 compiled_method->GetInstructionSet());
Logan Chienf7015fd2012-03-18 01:19:37 +0800242
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700243 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Logan Chienf7015fd2012-03-18 01:19:37 +0800244
Brian Carlstromae826982011-11-09 01:33:42 -0800245 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
246 compiled_method->GetFrameSizeInBytes(),
247 compiled_method->GetCoreSpillMask(),
248 compiled_method->GetFpSpillMask(),
249 &compiled_method->GetMappingTable()[0],
250 &compiled_method->GetVmapTable()[0],
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800251 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800252 method_invoke_stub);
253 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700254 } else {
255 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
256 const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
257 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800258 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
259 kStackAlignment,
260 0,
261 0,
262 NULL,
263 NULL,
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 }
268 }
269
270 static void MakeExecutable(const void* code_start, size_t code_length) {
271 CHECK(code_start != NULL);
272 CHECK_NE(code_length, 0U);
273 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700274 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700275 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700276 uintptr_t len = limit - base;
277 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800278 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800279
Ian Rogers16341552011-10-10 11:33:06 -0700280 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800281 // Only uses __builtin___clear_cache if GCC >= 4.3.3
282#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700283 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800284#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800285 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
286 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800287#else
288#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800289#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700290 }
291
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700292 protected:
293 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700294 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
295
Elliott Hughes0af55432011-08-17 18:37:28 -0700296 if (is_host_) {
297 // $ANDROID_ROOT is set on the device, but not on the host.
298 // We need to set this so that icu4c can find its locale data.
299 std::string root;
300 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800301#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700302 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800303#elif defined(__APPLE__)
304 root += "/out/host/darwin-x86";
305#else
306#error unsupported OS
307#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700308 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700309 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700310 }
311
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700312 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
313 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700314 if (mkdtemp(&android_data_[0]) == NULL) {
315 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
316 }
Elliott Hughes34023802011-08-30 12:06:17 -0700317 setenv("ANDROID_DATA", android_data_.c_str(), 1);
318 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700319 art_cache_.append("/art-cache");
320 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
321 ASSERT_EQ(mkdir_result, 0);
322
Brian Carlstroma004aa92012-02-08 18:05:09 -0800323 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
324 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700325
Mathieu Chartier0051be62012-10-12 17:47:11 -0700326 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
327 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800328
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700329 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700330 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800331 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700332 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800333 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
334 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700335 if(!Runtime::Create(options, false)) {
336 LOG(FATAL) << "Failed to create runtime";
337 return;
338 }
339 runtime_.reset(Runtime::Current());
340 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
341 // give it away now and then switch to a more managable ScopedObjectAccess.
342 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
343 // Whilst we're in native take the opportunity to initialize well known classes.
344 WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
345 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes90a33692011-08-30 13:27:07 -0700346 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700347 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700348
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700349 InstructionSet instruction_set = kNone;
jeffhaoc0228b82012-08-29 18:15:05 -0700350#if defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700351 instruction_set = kThumb2;
jeffhaoc0228b82012-08-29 18:15:05 -0700352#elif defined(__mips__)
353 instruction_set = kMips;
354#elif defined(__i386__)
355 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700356#endif
buzbeec531cef2012-10-18 07:09:20 -0700357
358 // TODO: make selectable
359#if defined(ART_USE_PORTABLE_COMPILER)
360 CompilerBackend compiler_backend = kPortable;
361#elif defined(ART_USE_LLVM_COMPILER)
362 CompilerBackend compiler_backend = kIceland; // TODO: remove
363#else
364 CompilerBackend compiler_backend = kQuick;
365#endif
366
Elliott Hughes8add92d2012-01-18 18:18:43 -0800367 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700368 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700369 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700370 Runtime::TrampolineType type = Runtime::TrampolineType(i);
371 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700372 runtime_->SetResolutionStubArray(
373 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700374 }
375 }
Ian Rogers19846512012-02-24 11:42:47 -0800376 if (!runtime_->HasResolutionMethod()) {
377 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
378 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700379 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700380 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
381 if (!runtime_->HasCalleeSaveMethod(type)) {
382 runtime_->SetCalleeSaveMethod(
383 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
384 }
385 }
Ian Rogers19846512012-02-24 11:42:47 -0800386 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700387 image_classes_.reset(new std::set<std::string>);
buzbeec531cef2012-10-18 07:09:20 -0700388 compiler_.reset(new Compiler(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
Brian Carlstromba0668e2012-03-26 13:14:07 -0700389 true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700390
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700391 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700392 }
393
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700394 virtual void TearDown() {
395 const char* android_data = getenv("ANDROID_DATA");
396 ASSERT_TRUE(android_data != NULL);
397 DIR* dir = opendir(art_cache_.c_str());
398 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700399 dirent* e;
400 while ((e = readdir(dir)) != NULL) {
401 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700402 continue;
403 }
404 std::string filename(art_cache_);
405 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700406 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700407 int unlink_result = unlink(filename.c_str());
408 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400409 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700410 closedir(dir);
411 int rmdir_cache_result = rmdir(art_cache_.c_str());
412 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700413 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700414 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700415
416 // icu4c has a fixed 10-element array "gCommonICUDataArray".
417 // If we run > 10 tests, we fill that array and u_setCommonData fails.
418 // There's a function to clear the array, but it's not public...
419 typedef void (*IcuCleanupFn)();
420 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
421 CHECK(sym != NULL);
422 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
423 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700424
Ian Rogers0e073f72011-09-09 10:45:46 -0700425 compiler_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700426 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800427 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700428
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800429 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700430 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400431
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700432 std::string GetLibCoreDexFileName() {
433 if (is_host_) {
434 const char* host_dir = getenv("ANDROID_HOST_OUT");
435 CHECK(host_dir != NULL);
436 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
437 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800438 return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700439 }
440
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700441 const DexFile* OpenTestDexFile(const char* name) {
442 CHECK(name != NULL);
443 std::string filename;
444 if (is_host_) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700445 filename += getenv("ANDROID_HOST_OUT");
446 filename += "/framework/";
447 } else {
448 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700449 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700450 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700451 filename += name;
452 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800453 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700454 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800455 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700456 return dex_file;
457 }
458
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700459 jobject LoadDex(const char* dex_name)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700460 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700461 const DexFile* dex_file = OpenTestDexFile(dex_name);
462 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700463 class_linker_->RegisterDexFile(*dex_file);
464 std::vector<const DexFile*> class_path;
465 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700466 ScopedObjectAccessUnchecked soa(Thread::Current());
467 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
468 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
469 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
470 soa.Self()->SetClassLoaderOverride(soa.Decode<ClassLoader*>(class_loader_local.get()));
471 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
472 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700473 }
474
Ian Rogers365c1022012-06-22 15:05:28 -0700475 void CompileClass(ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800476 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800477 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700478 CHECK(klass != NULL) << "Class not found " << class_name;
479 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
480 CompileMethod(klass->GetDirectMethod(i));
481 }
482 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
483 CompileMethod(klass->GetVirtualMethod(i));
484 }
485 }
486
Mathieu Chartier66f19252012-09-18 08:57:04 -0700487 void CompileMethod(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700488 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700489 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700490 MakeExecutable(method);
491
Ian Rogers169c9a72011-11-13 20:13:17 -0800492 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700493 }
494
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700495 void CompileDirectMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700496 const char* class_name,
497 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700498 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700499 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800500 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800501 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700502 CHECK(klass != NULL) << "Class not found " << class_name;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700503 AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700504 CHECK(method != NULL) << "Direct method not found: "
505 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700506 CompileMethod(method);
507 }
508
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700509 void CompileVirtualMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700510 const char* class_name,
511 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700512 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700513 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800514 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800515 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700516 CHECK(klass != NULL) << "Class not found " << class_name;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700517 AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700518 CHECK(method != NULL) << "Virtual method not found: "
519 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700520 CompileMethod(method);
521 }
522
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700523 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700524 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700525 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800526 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700527 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700528 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700529 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700530 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700531 UniquePtr<Compiler> compiler_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700532 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700533
534 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800535 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700536};
537
Elliott Hughesb264f082012-04-06 17:10:10 -0700538// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
539// rather than aborting, so be careful!
540class CheckJniAbortCatcher {
541 public:
542 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
543 vm_->check_jni_abort_hook = Hook;
544 vm_->check_jni_abort_hook_data = &actual_;
545 }
546
547 ~CheckJniAbortCatcher() {
548 vm_->check_jni_abort_hook = NULL;
549 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700550 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700551 }
552
553 void Check(const char* expected_text) {
554 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
555 << "Expected to find: " << expected_text << "\n"
556 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700557 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700558 }
559
560 private:
561 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700562 // We use += because when we're hooking the aborts like this, multiple problems can be found.
563 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700564 }
565
566 JavaVMExt* vm_;
567 std::string actual_;
568
569 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
570};
571
Brian Carlstrom934486c2011-07-12 23:42:50 -0700572} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700573
574namespace std {
575
576// TODO: isn't gtest supposed to be able to print STL types for itself?
577template <typename T>
578std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700579 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700580 return os;
581}
582
583} // namespace std