blob: 1f3f06331880474cfa92f7d2f6fb02a68fbb7a78 [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 Carlstromb0460ea2011-07-29 10:08:05 -07005#include <sys/stat.h>
6#include <sys/types.h>
7
Elliott Hughes90a33692011-08-30 13:27:07 -07008#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07009#include "base64.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070010#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070011#include "class_loader.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070012#include "compiler.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -070013#include "constants.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070014#include "dex_file.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070015#include "gtest/gtest.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070016#include "heap.h"
17#include "runtime.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070018#include "stringprintf.h"
19#include "thread.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070020#include "unicode/uclean.h"
21#include "unicode/uvernum.h"
22
Brian Carlstrom934486c2011-07-12 23:42:50 -070023namespace art {
24
Brian Carlstrom9f30b382011-08-28 22:41:38 -070025static inline const DexFile* OpenDexFileBase64(const char* base64,
26 const std::string& location) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070027 CHECK(base64 != NULL);
28 size_t length;
Brian Carlstromf615a612011-07-23 12:50:34 -070029 byte* dex_bytes = DecodeBase64(base64, &length);
30 CHECK(dex_bytes != NULL);
Brian Carlstrom9f30b382011-08-28 22:41:38 -070031 const DexFile* dex_file = DexFile::OpenPtr(dex_bytes, length, location);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070032 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -070033 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070034}
35
Brian Carlstromdb4d5402011-08-09 12:18:28 -070036class ScratchFile {
37 public:
38 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -070039 filename_ = getenv("ANDROID_DATA");
40 filename_ += "/TmpFile-XXXXXX";
41 fd_ = mkstemp(&filename_[0]);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070042 CHECK_NE(-1, fd_);
43 }
44
45 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -070046 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070047 CHECK_EQ(0, unlink_result);
48 int close_result = close(fd_);
49 CHECK_EQ(0, close_result);
50 }
51
52 const char* GetFilename() const {
Elliott Hughes34023802011-08-30 12:06:17 -070053 return filename_.c_str();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070054 }
55
56 int GetFd() const {
57 return fd_;
58 }
59
60 private:
Elliott Hughes34023802011-08-30 12:06:17 -070061 std::string filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070062 int fd_;
63};
64
Brian Carlstromf734cf52011-08-17 16:28:14 -070065class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070066 public:
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070067 static void MakeExecutable(const ByteArray* byte_array) {
68 uintptr_t data = reinterpret_cast<uintptr_t>(byte_array->GetData());
69 uintptr_t base = RoundDown(data, kPageSize);
70 uintptr_t limit = RoundUp(data + byte_array->GetLength(), kPageSize);
71 uintptr_t len = limit - base;
72 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
73 CHECK_EQ(result, 0);
74 }
75
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070076 protected:
77 virtual void SetUp() {
Brian Carlstrom4a96b602011-07-26 16:40:23 -070078 is_host_ = getenv("ANDROID_BUILD_TOP") != NULL;
79
Elliott Hughes0af55432011-08-17 18:37:28 -070080 if (is_host_) {
81 // $ANDROID_ROOT is set on the device, but not on the host.
82 // We need to set this so that icu4c can find its locale data.
83 std::string root;
84 root += getenv("ANDROID_BUILD_TOP");
85 root += "/out/host/linux-x86";
86 setenv("ANDROID_ROOT", root.c_str(), 1);
87 }
88
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070089 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
90 android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
Elliott Hughes0f4c41d2011-09-04 14:58:03 -070091 if (mkdtemp(&android_data_[0]) == NULL) {
92 PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed";
93 }
Elliott Hughes34023802011-08-30 12:06:17 -070094 setenv("ANDROID_DATA", android_data_.c_str(), 1);
95 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -070096 art_cache_.append("/art-cache");
97 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
98 ASSERT_EQ(mkdir_result, 0);
99
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700100 java_lang_dex_file_.reset(GetLibCoreDex());
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700101
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700102 boot_class_path_.push_back(java_lang_dex_file_.get());
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700103
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700104 Runtime::Options options;
105 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
106 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
107 runtime_.reset(Runtime::Create(options, false));
Elliott Hughes90a33692011-08-30 13:27:07 -0700108 ASSERT_TRUE(runtime_.get() != NULL);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700109 runtime_->Start();
Carl Shapiro7a909592011-07-24 19:21:59 -0700110 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700111
Ian Rogers2c8f6532011-09-02 17:16:34 -0700112#if defined(__i386__)
113 compiler_ = new Compiler(kX86);
114#elif defined(__arm__)
115 compiler_ = new Compiler(kThumb2);
116#else
117 compiler_ = new Compiler(kNone);
118#endif
119
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700120 Heap::VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700121 }
122
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700123 virtual void TearDown() {
124 const char* android_data = getenv("ANDROID_DATA");
125 ASSERT_TRUE(android_data != NULL);
126 DIR* dir = opendir(art_cache_.c_str());
127 ASSERT_TRUE(dir != NULL);
128 while (true) {
129 struct dirent entry;
130 struct dirent* entry_ptr;
131 int readdir_result = readdir_r(dir, &entry, &entry_ptr);
132 ASSERT_EQ(0, readdir_result);
133 if (entry_ptr == NULL) {
134 break;
135 }
136 if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) {
137 continue;
138 }
139 std::string filename(art_cache_);
140 filename.push_back('/');
141 filename.append(entry_ptr->d_name);
142 int unlink_result = unlink(filename.c_str());
143 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400144 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700145 closedir(dir);
146 int rmdir_cache_result = rmdir(art_cache_.c_str());
147 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700148 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700149 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700150
151 // icu4c has a fixed 10-element array "gCommonICUDataArray".
152 // If we run > 10 tests, we fill that array and u_setCommonData fails.
153 // There's a function to clear the array, but it's not public...
154 typedef void (*IcuCleanupFn)();
155 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
156 CHECK(sym != NULL);
157 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
158 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700159
Ian Rogers2c8f6532011-09-02 17:16:34 -0700160 delete compiler_;
161
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700162 Heap::VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700163 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400164
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700165 std::string GetLibCoreDexFileName() {
166 if (is_host_) {
167 const char* host_dir = getenv("ANDROID_HOST_OUT");
168 CHECK(host_dir != NULL);
169 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
170 }
171 return std::string("/system/framework/core.jar");
172 }
173
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700174 const DexFile* GetLibCoreDex() {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700175 std::string libcore_dex_file_name = GetLibCoreDexFileName();
Elliott Hughes40ef99e2011-08-11 17:44:34 -0700176 return DexFile::OpenZip(libcore_dex_file_name);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400177 }
178
Brian Carlstrom848a4b32011-09-04 11:29:27 -0700179 uint32_t FindTypeIdxByDescriptor(const DexFile& dex_file, const StringPiece& descriptor) {
180 for (size_t i = 0; i < dex_file.NumTypeIds(); i++) {
181 const DexFile::TypeId& type_id = dex_file.GetTypeId(i);
182 if (descriptor == dex_file.GetTypeDescriptor(type_id)) {
183 return i;
184 }
185 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700186 CHECK(false) << "Failed to find type index for " << descriptor;
Brian Carlstrom848a4b32011-09-04 11:29:27 -0700187 return 0;
188 }
189
190 uint32_t FindFieldIdxByDescriptorAndName(const DexFile& dex_file,
191 const StringPiece& class_descriptor,
192 const StringPiece& field_name) {
193 for (size_t i = 0; i < dex_file.NumFieldIds(); i++) {
194 const DexFile::FieldId& field_id = dex_file.GetFieldId(i);
195 if (class_descriptor == dex_file.GetFieldClassDescriptor(field_id)
196 && field_name == dex_file.GetFieldName(field_id)) {
197 return i;
198 }
199 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700200 CHECK(false) << "Failed to find field index for " << class_descriptor << " " << field_name;
Brian Carlstrom848a4b32011-09-04 11:29:27 -0700201 return 0;
202 }
203
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700204 const ClassLoader* AllocPathClassLoader(const DexFile* dex_file) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700205 CHECK(dex_file != NULL);
206 class_linker_->RegisterDexFile(*dex_file);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700207 std::vector<const DexFile*> dex_files;
208 dex_files.push_back(dex_file);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700209 return PathClassLoader::Alloc(dex_files);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700210 }
211
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700212 const DexFile* OpenTestDexFile(const char* name) {
213 CHECK(name != NULL);
214 std::string filename;
215 if (is_host_) {
216 // on the host, just read target dex file
217 filename += getenv("ANDROID_PRODUCT_OUT");
218 }
219 filename += "/system/framework/art-test-dex-";
220 filename += name;
221 filename += ".jar";
222 const DexFile* dex_file = DexFile::OpenZip(filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700223 CHECK(dex_file != NULL) << "Failed to open " << filename;
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700224 return dex_file;
225 }
226
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700227 const ClassLoader* LoadDex(const char* dex_name) {
228 const DexFile* dex_file = OpenTestDexFile(dex_name);
229 CHECK(dex_file != NULL);
230 loaded_dex_files_.push_back(dex_file);
231 class_linker_->RegisterDexFile(*dex_file);
232 std::vector<const DexFile*> class_path;
233 class_path.push_back(dex_file);
234 const ClassLoader* class_loader = PathClassLoader::Alloc(class_path);
235 CHECK(class_loader != NULL);
236 Thread::Current()->SetClassLoaderOverride(class_loader);
237 return class_loader;
238 }
239
240 std::string ConvertClassNameToClassDescriptor(const char* class_name) {
241 std::string desc;
242 desc += "L";
243 desc += class_name;
244 desc += ";";
245 std::replace(desc.begin(), desc.end(), '.', '/');
246 return desc;
247 }
248
249 void CompileMethod(Method* method) {
250 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700251 compiler_->CompileOne(method);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700252 MakeExecutable(method->GetCodeArray());
253 MakeExecutable(method->GetInvokeStubArray());
254 }
255
256 void CompileDirectMethod(const ClassLoader* class_loader,
257 const char* class_name,
258 const char* method_name,
259 const char* signature) {
260 std::string class_descriptor = ConvertClassNameToClassDescriptor(class_name);
261 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
262 CHECK(klass != NULL) << "Class not found " << class_name;
263 Method* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700264 CHECK(method != NULL) << "Direct method not found: "
265 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700266 CompileMethod(method);
267 }
268
269 void CompileVirtualMethod(const ClassLoader* class_loader,
270 const char* class_name,
271 const char* method_name,
272 const char* signature) {
273 std::string class_descriptor = ConvertClassNameToClassDescriptor(class_name);
274 Class* klass = class_linker_->FindClass(class_descriptor, class_loader);
275 CHECK(klass != NULL) << "Class not found " << class_name;
276 Method* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700277 CHECK(method != NULL) << "Virtual method not found: "
278 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700279 CompileMethod(method);
280 }
281
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700282 bool is_host_;
Elliott Hughes34023802011-08-30 12:06:17 -0700283 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700284 std::string art_cache_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700285 UniquePtr<const DexFile> java_lang_dex_file_;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700286 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700287 UniquePtr<Runtime> runtime_;
Carl Shapiro7a909592011-07-24 19:21:59 -0700288 ClassLinker* class_linker_;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700289 Compiler* compiler_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700290
291 private:
292 std::vector<const DexFile*> loaded_dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700293};
294
Brian Carlstrom934486c2011-07-12 23:42:50 -0700295} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700296
297namespace std {
298
299// TODO: isn't gtest supposed to be able to print STL types for itself?
300template <typename T>
301std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
302 os << "[";
303 for (size_t i = 0; i < rhs.size(); ++i) {
304 os << rhs[i];
305 if (i < rhs.size() - 1) {
306 os << ", ";
307 }
308 }
309 os << "]";
310 return os;
311}
312
313} // namespace std