blob: 68e30196140ce88b879aeb6c2b14cf47e43b42a6 [file] [log] [blame]
Brian Carlstrom934486c2011-07-12 23:42:50 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Brian Carlstromb0460ea2011-07-29 10:08:05 -07003#include <dirent.h>
Elliott Hughes0af55432011-08-17 18:37:28 -07004#include <dlfcn.h>
Brian Carlstrom27ec9612011-09-19 20:20:38 -07005#include <sys/mman.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -07006#include <sys/stat.h>
7#include <sys/types.h>
8
Elliott Hughes90a33692011-08-30 13:27:07 -07009#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070010#include "base64.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070011#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070012#include "class_loader.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070013#include "compiler.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -070014#include "constants.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070015#include "dex_file.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070016#include "file.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070017#include "gtest/gtest.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070018#include "heap.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070019#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070020#include "runtime.h"
Elliott Hughes14134a12011-09-30 16:55:51 -070021#include "stl_util.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070022#include "stringprintf.h"
23#include "thread.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070024#include "unicode/uclean.h"
25#include "unicode/uvernum.h"
26
Brian Carlstrom934486c2011-07-12 23:42:50 -070027namespace art {
28
Brian Carlstrom9f30b382011-08-28 22:41:38 -070029static inline const DexFile* OpenDexFileBase64(const char* base64,
30 const std::string& location) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -070031 // decode base64
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070032 CHECK(base64 != NULL);
33 size_t length;
Brian Carlstromf615a612011-07-23 12:50:34 -070034 byte* dex_bytes = DecodeBase64(base64, &length);
35 CHECK(dex_bytes != NULL);
Brian Carlstrom33f741e2011-10-03 11:24:05 -070036
37 // write to provided file
38 UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
39 CHECK(file.get() != NULL);
40 if (!file->WriteFully(dex_bytes, length)) {
41 PLOG(FATAL) << "Failed to write base64 as dex file";
42 }
43 file.reset();
44
45 // read dex file
Brian Carlstrom58ae9412011-10-04 00:56:06 -070046 const DexFile* dex_file = DexFile::Open(location, "");
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070047 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -070048 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070049}
50
Brian Carlstromdb4d5402011-08-09 12:18:28 -070051class ScratchFile {
52 public:
53 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -070054 filename_ = getenv("ANDROID_DATA");
55 filename_ += "/TmpFile-XXXXXX";
56 fd_ = mkstemp(&filename_[0]);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070057 CHECK_NE(-1, fd_);
58 }
59
60 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -070061 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070062 CHECK_EQ(0, unlink_result);
63 int close_result = close(fd_);
64 CHECK_EQ(0, close_result);
65 }
66
67 const char* GetFilename() const {
Elliott Hughes34023802011-08-30 12:06:17 -070068 return filename_.c_str();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070069 }
70
71 int GetFd() const {
72 return fd_;
73 }
74
75 private:
Elliott Hughes34023802011-08-30 12:06:17 -070076 std::string filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070077 int fd_;
78};
79
Brian Carlstromf734cf52011-08-17 16:28:14 -070080class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070081 public:
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070082 static void MakeExecutable(const ByteArray* byte_array) {
83 uintptr_t data = reinterpret_cast<uintptr_t>(byte_array->GetData());
84 uintptr_t base = RoundDown(data, kPageSize);
85 uintptr_t limit = RoundUp(data + byte_array->GetLength(), kPageSize);
86 uintptr_t len = limit - base;
87 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
88 CHECK_EQ(result, 0);
89 }
90
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070091 protected:
92 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -070093 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
94
Elliott Hughes0af55432011-08-17 18:37:28 -070095 if (is_host_) {
96 // $ANDROID_ROOT is set on the device, but not on the host.
97 // We need to set this so that icu4c can find its locale data.
98 std::string root;
99 root += getenv("ANDROID_BUILD_TOP");
100 root += "/out/host/linux-x86";
101 setenv("ANDROID_ROOT", root.c_str(), 1);
102 }
103
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700104 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
105 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700106 if (mkdtemp(&android_data_[0]) == NULL) {
107 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
108 }
Elliott Hughes34023802011-08-30 12:06:17 -0700109 setenv("ANDROID_DATA", android_data_.c_str(), 1);
110 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700111 art_cache_.append("/art-cache");
112 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
113 ASSERT_EQ(mkdir_result, 0);
114
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700115 java_lang_dex_file_.reset(GetLibCoreDex());
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700116
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700117 std::string boot_class_path;
118 boot_class_path += "-Xbootclasspath:";
119 boot_class_path += GetLibCoreDexFileName();
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700120
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700121 Runtime::Options options;
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700122 options.push_back(std::make_pair(boot_class_path.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700123 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700124 options.push_back(std::make_pair("-Xms64m", reinterpret_cast<void*>(NULL)));
125 options.push_back(std::make_pair("-Xmx64m", reinterpret_cast<void*>(NULL)));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700126 runtime_.reset(Runtime::Create(options, false));
Elliott Hughes90a33692011-08-30 13:27:07 -0700127 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700128 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700129
Ian Rogers2c8f6532011-09-02 17:16:34 -0700130#if defined(__i386__)
Brian Carlstrom16192862011-09-12 17:50:06 -0700131 runtime_->SetJniStubArray(JniCompiler::CreateJniStub(kX86));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700132 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(kX86));
Ian Rogersad25ac52011-10-04 19:13:33 -0700133 runtime_->SetResolutionStubArray(Compiler::CreateResolutionStub(kX86, false), false);
134 runtime_->SetResolutionStubArray(Compiler::CreateResolutionStub(kX86, true), true);
Ian Rogersff1ed472011-09-20 13:46:24 -0700135 runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(kX86));
Ian Rogers0e073f72011-09-09 10:45:46 -0700136 compiler_.reset(new Compiler(kX86));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700137#elif defined(__arm__)
Brian Carlstrom16192862011-09-12 17:50:06 -0700138 runtime_->SetJniStubArray(JniCompiler::CreateJniStub(kThumb2));
Ian Rogersff1ed472011-09-20 13:46:24 -0700139 runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(kThumb2));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700140 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(kThumb2));
Ian Rogersad25ac52011-10-04 19:13:33 -0700141 runtime_->SetResolutionStubArray(Compiler::CreateResolutionStub(kThumb2, false), false);
142 runtime_->SetResolutionStubArray(Compiler::CreateResolutionStub(kThumb2, true), true);
Ian Rogers0e073f72011-09-09 10:45:46 -0700143 compiler_.reset(new Compiler(kThumb2));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700144#endif
145
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700146 Heap::VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700147 }
148
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700149 virtual void TearDown() {
150 const char* android_data = getenv("ANDROID_DATA");
151 ASSERT_TRUE(android_data != NULL);
152 DIR* dir = opendir(art_cache_.c_str());
153 ASSERT_TRUE(dir != NULL);
154 while (true) {
155 struct dirent entry;
156 struct dirent* entry_ptr;
157 int readdir_result = readdir_r(dir, &entry, &entry_ptr);
158 ASSERT_EQ(0, readdir_result);
159 if (entry_ptr == NULL) {
160 break;
161 }
162 if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
163 continue;
164 }
165 std::string filename(art_cache_);
166 filename.push_back('/');
167 filename.append(entry_ptr->d_name);
168 int unlink_result = unlink(filename.c_str());
169 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400170 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700171 closedir(dir);
172 int rmdir_cache_result = rmdir(art_cache_.c_str());
173 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700174 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700175 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700176
177 // icu4c has a fixed 10-element array "gCommonICUDataArray".
178 // If we run > 10 tests, we fill that array and u_setCommonData fails.
179 // There's a function to clear the array, but it's not public...
180 typedef void (*IcuCleanupFn)();
181 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
182 CHECK(sym != NULL);
183 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
184 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700185
Ian Rogers0e073f72011-09-09 10:45:46 -0700186 compiler_.reset();
Ian Rogers2c8f6532011-09-02 17:16:34 -0700187
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700188 Heap::VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700189 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400190
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700191 std::string GetLibCoreDexFileName() {
192 if (is_host_) {
193 const char* host_dir = getenv("ANDROID_HOST_OUT");
194 CHECK(host_dir != NULL);
195 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
196 }
197 return std::string("/system/framework/core.jar");
198 }
199
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700200 const DexFile* GetLibCoreDex() {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700201 std::string libcore_dex_file_name = GetLibCoreDexFileName();
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700202 return DexFile::Open(libcore_dex_file_name, "");
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400203 }
204
Brian Carlstrom848a4b32011-09-04 11:29:27 -0700205 uint32_t FindTypeIdxByDescriptor(const DexFile& dex_file, const StringPiece& descriptor) {
206 for (size_t i = 0; i < dex_file.NumTypeIds(); i++) {
207 const DexFile::TypeId& type_id = dex_file.GetTypeId(i);
208 if (descriptor == dex_file.GetTypeDescriptor(type_id)) {
209 return i;
210 }
211 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700212 CHECK(false) << "Failed to find type index for " << descriptor;
Brian Carlstrom848a4b32011-09-04 11:29:27 -0700213 return 0;
214 }
215
216 uint32_t FindFieldIdxByDescriptorAndName(const DexFile& dex_file,
217 const StringPiece& class_descriptor,
218 const StringPiece& field_name) {
219 for (size_t i = 0; i < dex_file.NumFieldIds(); i++) {
220 const DexFile::FieldId& field_id = dex_file.GetFieldId(i);
221 if (class_descriptor == dex_file.GetFieldClassDescriptor(field_id)
222 && field_name == dex_file.GetFieldName(field_id)) {
223 return i;
224 }
225 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700226 CHECK(false) << "Failed to find field index for " << class_descriptor << " " << field_name;
Brian Carlstrom848a4b32011-09-04 11:29:27 -0700227 return 0;
228 }
229
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700230 const ClassLoader* AllocPathClassLoader(const DexFile* dex_file) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700231 CHECK(dex_file != NULL);
232 class_linker_->RegisterDexFile(*dex_file);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700233 std::vector<const DexFile*> dex_files;
234 dex_files.push_back(dex_file);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700235 return PathClassLoader::Alloc(dex_files);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700236 }
237
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700238 const DexFile* OpenTestDexFile(const char* name) {
239 CHECK(name != NULL);
240 std::string filename;
241 if (is_host_) {
242 // on the host, just read target dex file
243 filename += getenv("ANDROID_PRODUCT_OUT");
244 }
245 filename += "/system/framework/art-test-dex-";
246 filename += name;
247 filename += ".jar";
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700248 const DexFile* dex_file = DexFile::Open(filename, "");
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700249 CHECK(dex_file != NULL) << "Failed to open " << filename;
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700250 return dex_file;
251 }
252
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700253 const ClassLoader* LoadDex(const char* dex_name) {
254 const DexFile* dex_file = OpenTestDexFile(dex_name);
255 CHECK(dex_file != NULL);
256 loaded_dex_files_.push_back(dex_file);
257 class_linker_->RegisterDexFile(*dex_file);
258 std::vector<const DexFile*> class_path;
259 class_path.push_back(dex_file);
260 const ClassLoader* class_loader = PathClassLoader::Alloc(class_path);
261 CHECK(class_loader != NULL);
262 Thread::Current()->SetClassLoaderOverride(class_loader);
263 return class_loader;
264 }
265
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700266 void CompileMethod(Method* method) {
267 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700268 compiler_->CompileOne(method);
Brian Carlstrom16192862011-09-12 17:50:06 -0700269 MakeExecutable(runtime_->GetJniStubArray());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700270 MakeExecutable(method->GetCodeArray());
271 MakeExecutable(method->GetInvokeStubArray());
272 }
273
274 void CompileDirectMethod(const ClassLoader* class_loader,
275 const char* class_name,
276 const char* method_name,
277 const char* signature) {
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700278 std::string class_descriptor = DotToDescriptor(class_name);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700279 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
280 CHECK(klass != NULL) << "Class not found " << class_name;
281 Method* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700282 CHECK(method != NULL) << "Direct method not found: "
283 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700284 CompileMethod(method);
285 }
286
287 void CompileVirtualMethod(const ClassLoader* class_loader,
288 const char* class_name,
289 const char* method_name,
290 const char* signature) {
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700291 std::string class_descriptor = DotToDescriptor(class_name);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700292 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
293 CHECK(klass != NULL) << "Class not found " << class_name;
294 Method* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700295 CHECK(method != NULL) << "Virtual method not found: "
296 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700297 CompileMethod(method);
298 }
299
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700300 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700301 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700302 std::string art_cache_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700303 UniquePtr<const DexFile> java_lang_dex_file_;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700304 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700305 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700306 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700307 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700308 UniquePtr<Compiler> compiler_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700309
310 private:
311 std::vector<const DexFile*> loaded_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700312};
313
Brian Carlstrom934486c2011-07-12 23:42:50 -0700314} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700315
316namespace std {
317
318// TODO: isn't gtest supposed to be able to print STL types for itself?
319template <typename T>
320std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700321 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700322 return os;
323}
324
325} // namespace std