blob: 9dbdbfc09d96122b8b6179abd4769e6ad1eb52af [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
Elliott Hughes76160052012-12-12 16:31:20 -080023#include "base/macros.h"
24#include "base/unix_file/fd_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070025#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070026#include "class_loader.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070027#include "compiler.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070028#include "dex_file.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070029#include "gtest/gtest.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070030#include "heap.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070031#include "instruction_set.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";
Elliott Hughes76160052012-12-12 16:31:20 -0800146 int fd = mkstemp(&filename_[0]);
147 CHECK_NE(-1, fd);
148 file_.reset(new File(fd, GetFilename()));
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);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700154 }
155
Brian Carlstroma004aa92012-02-08 18:05:09 -0800156 const std::string& GetFilename() const {
157 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700158 }
159
Elliott Hughes234da572011-11-03 22:13:06 -0700160 File* GetFile() const {
161 return file_.get();
162 }
163
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700164 int GetFd() const {
Elliott Hughes76160052012-12-12 16:31:20 -0800165 return file_->Fd();
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700166 }
167
168 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700169 std::string filename_;
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,
Mathieu Chartier66f19252012-09-18 08:57:04 -0700193 const AbstractMethod::InvokeStub* invoke_stub) {
Brian Carlstromae826982011-11-09 01:33:42 -0800194 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
Mathieu Chartier66f19252012-09-18 08:57:04 -0700209 void MakeExecutable(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700210 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);
Mathieu Chartier66f19252012-09-18 08:57:04 -0700219 const AbstractMethod::InvokeStub* method_invoke_stub =
220 reinterpret_cast<const AbstractMethod::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();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700229 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogers0571d352011-11-03 19:51:38 -0700230 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
Elliott Hughes76160052012-12-12 16:31:20 -0800289 static void SetEnvironmentVariables(std::string& android_data) {
290 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700291 // $ANDROID_ROOT is set on the device, but not on the host.
292 // We need to set this so that icu4c can find its locale data.
293 std::string root;
294 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800295#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700296 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800297#elif defined(__APPLE__)
298 root += "/out/host/darwin-x86";
299#else
300#error unsupported OS
301#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700302 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700303 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700304 }
305
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700306 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
Elliott Hughes76160052012-12-12 16:31:20 -0800307 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
308 if (mkdtemp(&android_data[0]) == NULL) {
309 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700310 }
Elliott Hughes76160052012-12-12 16:31:20 -0800311 setenv("ANDROID_DATA", android_data.c_str(), 1);
312 }
313
314 protected:
315 static bool IsHost() {
316 return (getenv("ANDROID_BUILD_TOP") != NULL);
317 }
318
319 virtual void SetUp() {
320 SetEnvironmentVariables(android_data_);
Elliott Hughes34023802011-08-30 12:06:17 -0700321 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700322 art_cache_.append("/art-cache");
323 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
324 ASSERT_EQ(mkdir_result, 0);
325
Brian Carlstroma004aa92012-02-08 18:05:09 -0800326 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
327 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700328
Mathieu Chartier0051be62012-10-12 17:47:11 -0700329 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
330 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800331
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700332 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700333 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800334 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700335 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800336 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
337 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700338 if(!Runtime::Create(options, false)) {
339 LOG(FATAL) << "Failed to create runtime";
340 return;
341 }
342 runtime_.reset(Runtime::Current());
343 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
344 // give it away now and then switch to a more managable ScopedObjectAccess.
345 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
346 // Whilst we're in native take the opportunity to initialize well known classes.
347 WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
348 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes90a33692011-08-30 13:27:07 -0700349 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700350 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700351
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700352 InstructionSet instruction_set = kNone;
jeffhaoc0228b82012-08-29 18:15:05 -0700353#if defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700354 instruction_set = kThumb2;
jeffhaoc0228b82012-08-29 18:15:05 -0700355#elif defined(__mips__)
356 instruction_set = kMips;
357#elif defined(__i386__)
358 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700359#endif
buzbeec531cef2012-10-18 07:09:20 -0700360
361 // TODO: make selectable
362#if defined(ART_USE_PORTABLE_COMPILER)
363 CompilerBackend compiler_backend = kPortable;
364#elif defined(ART_USE_LLVM_COMPILER)
365 CompilerBackend compiler_backend = kIceland; // TODO: remove
366#else
367 CompilerBackend compiler_backend = kQuick;
368#endif
369
Elliott Hughes8add92d2012-01-18 18:18:43 -0800370 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700371 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700372 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700373 Runtime::TrampolineType type = Runtime::TrampolineType(i);
374 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700375 runtime_->SetResolutionStubArray(
376 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700377 }
378 }
Ian Rogers19846512012-02-24 11:42:47 -0800379 if (!runtime_->HasResolutionMethod()) {
380 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
381 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700382 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700383 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
384 if (!runtime_->HasCalleeSaveMethod(type)) {
385 runtime_->SetCalleeSaveMethod(
386 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
387 }
388 }
Ian Rogers19846512012-02-24 11:42:47 -0800389 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700390 image_classes_.reset(new std::set<std::string>);
buzbeec531cef2012-10-18 07:09:20 -0700391 compiler_.reset(new Compiler(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
Brian Carlstromba0668e2012-03-26 13:14:07 -0700392 true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700393
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700394 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
395 // pool is created by the runtime.
396 runtime_->GetHeap()->CreateThreadPool();
397
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700398 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700399 }
400
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700401 virtual void TearDown() {
402 const char* android_data = getenv("ANDROID_DATA");
403 ASSERT_TRUE(android_data != NULL);
404 DIR* dir = opendir(art_cache_.c_str());
405 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700406 dirent* e;
407 while ((e = readdir(dir)) != NULL) {
408 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700409 continue;
410 }
411 std::string filename(art_cache_);
412 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700413 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700414 int unlink_result = unlink(filename.c_str());
415 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400416 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700417 closedir(dir);
418 int rmdir_cache_result = rmdir(art_cache_.c_str());
419 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700420 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700421 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700422
423 // icu4c has a fixed 10-element array "gCommonICUDataArray".
424 // If we run > 10 tests, we fill that array and u_setCommonData fails.
425 // There's a function to clear the array, but it's not public...
426 typedef void (*IcuCleanupFn)();
427 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
428 CHECK(sym != NULL);
429 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
430 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700431
Ian Rogers0e073f72011-09-09 10:45:46 -0700432 compiler_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700433 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800434 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700435
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800436 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700437 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400438
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700439 std::string GetLibCoreDexFileName() {
Elliott Hughes76160052012-12-12 16:31:20 -0800440 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700441 const char* host_dir = getenv("ANDROID_HOST_OUT");
442 CHECK(host_dir != NULL);
443 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
444 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800445 return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700446 }
447
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700448 const DexFile* OpenTestDexFile(const char* name) {
449 CHECK(name != NULL);
450 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800451 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700452 filename += getenv("ANDROID_HOST_OUT");
453 filename += "/framework/";
454 } else {
455 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700456 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700457 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700458 filename += name;
459 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800460 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700461 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800462 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700463 return dex_file;
464 }
465
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700466 jobject LoadDex(const char* dex_name)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700467 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700468 const DexFile* dex_file = OpenTestDexFile(dex_name);
469 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700470 class_linker_->RegisterDexFile(*dex_file);
471 std::vector<const DexFile*> class_path;
472 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700473 ScopedObjectAccessUnchecked soa(Thread::Current());
474 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
475 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
476 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
477 soa.Self()->SetClassLoaderOverride(soa.Decode<ClassLoader*>(class_loader_local.get()));
478 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
479 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700480 }
481
Ian Rogers365c1022012-06-22 15:05:28 -0700482 void CompileClass(ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800483 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800484 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700485 CHECK(klass != NULL) << "Class not found " << class_name;
486 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
487 CompileMethod(klass->GetDirectMethod(i));
488 }
489 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
490 CompileMethod(klass->GetVirtualMethod(i));
491 }
492 }
493
Mathieu Chartier66f19252012-09-18 08:57:04 -0700494 void CompileMethod(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700495 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700496 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700497 MakeExecutable(method);
498
Ian Rogers169c9a72011-11-13 20:13:17 -0800499 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700500 }
501
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700502 void CompileDirectMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700503 const char* class_name,
504 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700505 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700506 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
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;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700510 AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700511 CHECK(method != NULL) << "Direct method not found: "
512 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700513 CompileMethod(method);
514 }
515
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700516 void CompileVirtualMethod(ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700517 const char* class_name,
518 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700519 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700520 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800521 std::string class_descriptor(DotToDescriptor(class_name));
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800522 Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700523 CHECK(klass != NULL) << "Class not found " << class_name;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700524 AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700525 CHECK(method != NULL) << "Virtual method not found: "
526 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700527 CompileMethod(method);
528 }
529
Elliott Hughes34023802011-08-30 12:06:17 -0700530 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700531 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800532 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700533 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700534 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700535 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700536 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700537 UniquePtr<Compiler> compiler_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700538 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700539
540 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800541 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700542};
543
Elliott Hughesb264f082012-04-06 17:10:10 -0700544// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
545// rather than aborting, so be careful!
546class CheckJniAbortCatcher {
547 public:
548 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
549 vm_->check_jni_abort_hook = Hook;
550 vm_->check_jni_abort_hook_data = &actual_;
551 }
552
553 ~CheckJniAbortCatcher() {
554 vm_->check_jni_abort_hook = NULL;
555 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700556 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700557 }
558
559 void Check(const char* expected_text) {
560 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
561 << "Expected to find: " << expected_text << "\n"
562 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700563 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700564 }
565
566 private:
567 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700568 // We use += because when we're hooking the aborts like this, multiple problems can be found.
569 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700570 }
571
572 JavaVMExt* vm_;
573 std::string actual_;
574
575 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
576};
577
Brian Carlstrom934486c2011-07-12 23:42:50 -0700578} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700579
580namespace std {
581
582// TODO: isn't gtest supposed to be able to print STL types for itself?
583template <typename T>
584std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700585 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700586 return os;
587}
588
589} // namespace std