blob: 96d660fd644b9d023b463c46a0e6054243946215 [file] [log] [blame]
Elliott Hugheseb02a122012-06-12 11:35:40 -07001/*
2 * Copyright (C) 2012 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 */
16
Ian Rogerse63db272014-07-15 15:36:11 -070017#include "common_runtime_test.h"
18
19#include <dirent.h>
20#include <dlfcn.h>
21#include <fcntl.h>
Andreas Gampe369810a2015-01-14 19:53:31 -080022#include <stdlib.h>
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070023#include <cstdio>
Andreas Gampe373a9b52017-10-18 09:01:57 -070024#include "nativehelper/scoped_local_ref.h"
Ian Rogerse63db272014-07-15 15:36:11 -070025
Andreas Gampe46ee31b2016-12-14 10:11:49 -080026#include "android-base/stringprintf.h"
Andreas Gampefdb7a612017-11-01 15:11:13 -070027#include <unicode/uvernum.h>
Andreas Gampe46ee31b2016-12-14 10:11:49 -080028
Mathieu Chartiere401d142015-04-22 13:56:20 -070029#include "art_field-inl.h"
David Sehr891a50e2017-10-27 17:01:07 -070030#include "base/file_utils.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031#include "base/logging.h"
Steven Morelande431e272017-07-18 16:53:49 -070032#include "base/macros.h"
Andreas Gampedcc528d2017-12-07 13:37:10 -080033#include "base/runtime_debug.h"
Ian Rogerse63db272014-07-15 15:36:11 -070034#include "base/stl_util.h"
Ian Rogerse63db272014-07-15 15:36:11 -070035#include "base/unix_file/fd_file.h"
36#include "class_linker.h"
37#include "compiler_callbacks.h"
David Sehr9e734c72018-01-04 17:56:19 -080038#include "dex/dex_file-inl.h"
39#include "dex/dex_file_loader.h"
Ian Rogerse63db272014-07-15 15:36:11 -070040#include "gc/heap.h"
Steven Morelande431e272017-07-18 16:53:49 -070041#include "gc_root-inl.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070042#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070043#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070044#include "interpreter/unstarted_runtime.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070045#include "java_vm_ext.h"
Ian Rogerse63db272014-07-15 15:36:11 -070046#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070047#include "mem_map.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070048#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070049#include "mirror/class_loader.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070050#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070051#include "noop_compiler_callbacks.h"
52#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070053#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070054#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070055#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070056#include "thread.h"
57#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070058
59int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080060 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
61 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
62 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000063 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080064
Andreas Gampe51d80cc2017-06-21 21:05:13 -070065 art::InitLogging(argv, art::Runtime::Abort);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070066 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070067 testing::InitGoogleTest(&argc, argv);
68 return RUN_ALL_TESTS();
69}
Ian Rogerse63db272014-07-15 15:36:11 -070070
71namespace art {
72
Andreas Gampe46ee31b2016-12-14 10:11:49 -080073using android::base::StringPrintf;
74
Alex Lighta01b5242017-03-27 10:15:27 -070075static const uint8_t kBase64Map[256] = {
76 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
78 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
79 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
80 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
81 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Igor Murashkin5573c372017-11-16 13:34:30 -080082 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
83 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
Alex Lighta01b5242017-03-27 10:15:27 -070084 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Igor Murashkin5573c372017-11-16 13:34:30 -080085 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
86 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
Alex Lighta01b5242017-03-27 10:15:27 -070087 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
93 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
94 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
95 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
96 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
97 255, 255, 255, 255
98};
99
100uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
101 CHECK(dst_size != nullptr);
102 std::vector<uint8_t> tmp;
103 uint32_t t = 0, y = 0;
104 int g = 3;
105 for (size_t i = 0; src[i] != '\0'; ++i) {
106 uint8_t c = kBase64Map[src[i] & 0xFF];
107 if (c == 255) continue;
108 // the final = symbols are read and used to trim the remaining bytes
109 if (c == 254) {
110 c = 0;
111 // prevent g < 0 which would potentially allow an overflow later
112 if (--g < 0) {
113 *dst_size = 0;
114 return nullptr;
115 }
116 } else if (g != 3) {
117 // we only allow = to be at the end
118 *dst_size = 0;
119 return nullptr;
120 }
121 t = (t << 6) | c;
122 if (++y == 4) {
123 tmp.push_back((t >> 16) & 255);
124 if (g > 1) {
125 tmp.push_back((t >> 8) & 255);
126 }
127 if (g > 2) {
128 tmp.push_back(t & 255);
129 }
130 y = t = 0;
131 }
132 }
133 if (y != 0) {
134 *dst_size = 0;
135 return nullptr;
136 }
137 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
138 *dst_size = tmp.size();
139 std::copy(tmp.begin(), tmp.end(), dst.get());
140 return dst.release();
141}
142
Ian Rogerse63db272014-07-15 15:36:11 -0700143ScratchFile::ScratchFile() {
144 // ANDROID_DATA needs to be set
145 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
146 "Are you subclassing RuntimeTest?";
147 filename_ = getenv("ANDROID_DATA");
148 filename_ += "/TmpFile-XXXXXX";
149 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000150 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800151 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700152}
153
Mathieu Chartier866d8742016-09-21 15:24:18 -0700154ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
155 : ScratchFile(other.GetFilename() + suffix) {}
156
157ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700158 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
159 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800160 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700161}
162
163ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700164 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700165 filename_ = file->GetPath();
166 file_.reset(file);
167}
168
Mathieu Chartier866d8742016-09-21 15:24:18 -0700169ScratchFile::ScratchFile(ScratchFile&& other) {
170 *this = std::move(other);
171}
172
173ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
174 if (GetFile() != other.GetFile()) {
175 std::swap(filename_, other.filename_);
176 std::swap(file_, other.file_);
177 }
178 return *this;
179}
180
Ian Rogerse63db272014-07-15 15:36:11 -0700181ScratchFile::~ScratchFile() {
182 Unlink();
183}
184
185int ScratchFile::GetFd() const {
186 return file_->Fd();
187}
188
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800189void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800190 if (file_.get() != nullptr) {
191 if (file_->FlushCloseOrErase() != 0) {
192 PLOG(WARNING) << "Error closing scratch file.";
193 }
194 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800195}
196
197void ScratchFile::Unlink() {
198 if (!OS::FileExists(filename_.c_str())) {
199 return;
200 }
201 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700202 int unlink_result = unlink(filename_.c_str());
203 CHECK_EQ(0, unlink_result);
204}
205
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700206static bool unstarted_initialized_ = false;
207
Andreas Gampe48864112017-01-19 17:23:17 -0800208CommonRuntimeTestImpl::CommonRuntimeTestImpl()
209 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
210}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800211
212CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800213 // Ensure the dex files are cleaned up before the runtime.
214 loaded_dex_files_.clear();
215 runtime_.reset();
216}
Ian Rogerse63db272014-07-15 15:36:11 -0700217
Mathieu Chartier91c91162016-01-15 09:48:15 -0800218void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700219 if (IsHost()) {
220 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
221 // But it needs to be set so that icu4c can find its locale data.
222 const char* android_root_from_env = getenv("ANDROID_ROOT");
223 if (android_root_from_env == nullptr) {
224 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
225 const char* android_host_out = getenv("ANDROID_HOST_OUT");
226 if (android_host_out != nullptr) {
227 setenv("ANDROID_ROOT", android_host_out, 1);
228 } else {
229 // Build it from ANDROID_BUILD_TOP or cwd
230 std::string root;
231 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
232 if (android_build_top != nullptr) {
233 root += android_build_top;
234 } else {
235 // Not set by build server, so default to current directory
236 char* cwd = getcwd(nullptr, 0);
237 setenv("ANDROID_BUILD_TOP", cwd, 1);
238 root += cwd;
239 free(cwd);
240 }
241#if defined(__linux__)
242 root += "/out/host/linux-x86";
243#elif defined(__APPLE__)
244 root += "/out/host/darwin-x86";
245#else
246#error unsupported OS
247#endif
248 setenv("ANDROID_ROOT", root.c_str(), 1);
249 }
250 }
251 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
252
253 // Not set by build server, so default
254 if (getenv("ANDROID_HOST_OUT") == nullptr) {
255 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
256 }
257 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700258}
Ian Rogerse63db272014-07-15 15:36:11 -0700259
Mathieu Chartier91c91162016-01-15 09:48:15 -0800260void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700261 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700262 if (IsHost()) {
263 const char* tmpdir = getenv("TMPDIR");
264 if (tmpdir != nullptr && tmpdir[0] != 0) {
265 android_data = tmpdir;
266 } else {
267 android_data = "/tmp";
268 }
269 } else {
270 android_data = "/data/dalvik-cache";
271 }
272 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700273 if (mkdtemp(&android_data[0]) == nullptr) {
274 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
275 }
276 setenv("ANDROID_DATA", android_data.c_str(), 1);
277}
278
Mathieu Chartier91c91162016-01-15 09:48:15 -0800279void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
280 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700281 if (fail_on_error) {
282 ASSERT_EQ(rmdir(android_data.c_str()), 0);
283 } else {
284 rmdir(android_data.c_str());
285 }
286}
287
David Srbecky3e52aa42015-04-12 07:45:18 +0100288// Helper - find directory with the following format:
289// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
290static std::string GetAndroidToolsDir(const std::string& subdir1,
291 const std::string& subdir2,
292 const std::string& subdir3) {
293 std::string root;
294 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
295 if (android_build_top != nullptr) {
296 root = android_build_top;
297 } else {
298 // Not set by build server, so default to current directory
299 char* cwd = getcwd(nullptr, 0);
300 setenv("ANDROID_BUILD_TOP", cwd, 1);
301 root = cwd;
302 free(cwd);
303 }
304
305 std::string toolsdir = root + "/" + subdir1;
306 std::string founddir;
307 DIR* dir;
308 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
309 float maxversion = 0;
310 struct dirent* entry;
311 while ((entry = readdir(dir)) != nullptr) {
312 std::string format = subdir2 + "-%f";
313 float version;
314 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
315 if (version > maxversion) {
316 maxversion = version;
317 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
318 }
319 }
320 }
321 closedir(dir);
322 }
323
324 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000325 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100326 }
327 return founddir;
328}
329
Mathieu Chartier91c91162016-01-15 09:48:15 -0800330std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100331 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
332 "x86_64-linux-glibc2.15",
333 "x86_64-linux");
334}
335
Mathieu Chartier91c91162016-01-15 09:48:15 -0800336std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100337 switch (isa) {
Vladimir Marko33bff252017-11-01 14:35:42 +0000338 case InstructionSet::kArm:
339 case InstructionSet::kThumb2:
David Srbecky3e52aa42015-04-12 07:45:18 +0100340 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
341 "arm-linux-androideabi",
342 "arm-linux-androideabi");
Vladimir Marko33bff252017-11-01 14:35:42 +0000343 case InstructionSet::kArm64:
David Srbecky3e52aa42015-04-12 07:45:18 +0100344 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
345 "aarch64-linux-android",
346 "aarch64-linux-android");
Vladimir Marko33bff252017-11-01 14:35:42 +0000347 case InstructionSet::kX86:
348 case InstructionSet::kX86_64:
David Srbecky3e52aa42015-04-12 07:45:18 +0100349 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
350 "x86_64-linux-android",
351 "x86_64-linux-android");
Vladimir Marko33bff252017-11-01 14:35:42 +0000352 case InstructionSet::kMips:
353 case InstructionSet::kMips64:
David Srbecky3e52aa42015-04-12 07:45:18 +0100354 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
355 "mips64el-linux-android",
356 "mips64el-linux-android");
Vladimir Marko33bff252017-11-01 14:35:42 +0000357 case InstructionSet::kNone:
David Srbecky3e52aa42015-04-12 07:45:18 +0100358 break;
359 }
360 ADD_FAILURE() << "Invalid isa " << isa;
361 return "";
362}
363
Mathieu Chartier91c91162016-01-15 09:48:15 -0800364std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800365 return GetCoreFileLocation("art");
366}
367
Mathieu Chartier91c91162016-01-15 09:48:15 -0800368std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800369 return GetCoreFileLocation("oat");
370}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700371
Mathieu Chartier91c91162016-01-15 09:48:15 -0800372std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
373 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800374 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700375 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800376 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700377 static constexpr bool kVerifyChecksum = true;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100378 if (!DexFileLoader::Open(
379 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700380 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800381 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700382 } else {
383 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800384 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700385 }
386}
387
Mathieu Chartier91c91162016-01-15 09:48:15 -0800388void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700389 SetUpAndroidRoot();
390 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700391 dalvik_cache_.append(android_data_.c_str());
392 dalvik_cache_.append("/dalvik-cache");
393 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
394 ASSERT_EQ(mkdir_result, 0);
395
Ian Rogerse63db272014-07-15 15:36:11 -0700396 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
397 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
398
Ian Rogerse63db272014-07-15 15:36:11 -0700399
400 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000401 std::string boot_class_path_string = "-Xbootclasspath";
402 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
403 boot_class_path_string += ":";
404 boot_class_path_string += core_dex_file_name;
405 }
406
Richard Uhlerc2752592015-01-02 13:28:22 -0800407 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700408 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800409 options.push_back(std::make_pair(min_heap_string, nullptr));
410 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700411 options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
Andreas Gampe46c4c852017-06-21 19:49:08 -0700412 static bool gSlowDebugTestFlag = false;
413 RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700414
415 callbacks_.reset(new NoopCompilerCallbacks());
416
Ian Rogerse63db272014-07-15 15:36:11 -0700417 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800418
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700419 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
420 if (callbacks_.get() != nullptr) {
421 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
422 }
423
Richard Uhler66d874d2015-01-15 09:37:19 -0800424 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700425 if (!Runtime::Create(options, false)) {
426 LOG(FATAL) << "Failed to create runtime";
427 return;
428 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800429 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700430 runtime_.reset(Runtime::Current());
431 class_linker_ = runtime_->GetClassLinker();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700432
Andreas Gampea00f0122015-12-16 16:54:35 -0800433 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
434 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
435 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
436
437 // Get the boot class path from the runtime so it can be used in tests.
438 boot_class_path_ = class_linker_->GetBootClassPath();
439 ASSERT_FALSE(boot_class_path_.empty());
440 java_lang_dex_file_ = boot_class_path_[0];
441
442 FinalizeSetup();
Andreas Gampe46c4c852017-06-21 19:49:08 -0700443
444 // Ensure that we're really running with debug checks enabled.
445 CHECK(gSlowDebugTestFlag);
Andreas Gampea00f0122015-12-16 16:54:35 -0800446}
447
Mathieu Chartier91c91162016-01-15 09:48:15 -0800448void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700449 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
450 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700451 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700452 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700453 unstarted_initialized_ = true;
454 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700455
Andreas Gampea00f0122015-12-16 16:54:35 -0800456 {
457 ScopedObjectAccess soa(Thread::Current());
458 class_linker_->RunRootClinits();
459 }
Ian Rogerse63db272014-07-15 15:36:11 -0700460
461 // We're back in native, take the opportunity to initialize well known classes.
462 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
463
464 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
465 // pool is created by the runtime.
466 runtime_->GetHeap()->CreateThreadPool();
467 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700468 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
469 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700470}
471
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700472void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
Alex Lighta59dd802014-07-02 16:28:08 -0700473 ASSERT_TRUE(dirpath != nullptr);
474 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700475 ASSERT_TRUE(dir != nullptr);
476 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700477 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700478 while ((e = readdir(dir)) != nullptr) {
479 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
480 continue;
481 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700482 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700483 filename.push_back('/');
484 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700485 int stat_result = lstat(filename.c_str(), &s);
486 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
487 if (S_ISDIR(s.st_mode)) {
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700488 if (recursive) {
489 ClearDirectory(filename.c_str());
490 int rmdir_result = rmdir(filename.c_str());
491 ASSERT_EQ(0, rmdir_result) << filename;
492 }
Alex Lighta59dd802014-07-02 16:28:08 -0700493 } else {
494 int unlink_result = unlink(filename.c_str());
495 ASSERT_EQ(0, unlink_result) << filename;
496 }
Ian Rogerse63db272014-07-15 15:36:11 -0700497 }
498 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700499}
500
Mathieu Chartier91c91162016-01-15 09:48:15 -0800501void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700502 const char* android_data = getenv("ANDROID_DATA");
503 ASSERT_TRUE(android_data != nullptr);
504 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700505 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
506 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700507 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800508 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700509
Andreas Gampe48864112017-01-19 17:23:17 -0800510 if (runtime_ != nullptr) {
511 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
512 }
Ian Rogerse63db272014-07-15 15:36:11 -0700513}
514
Andreas Gampec7d4a582015-09-30 11:52:02 -0700515static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
516 std::string path;
517 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700518 const char* host_dir = getenv("ANDROID_HOST_OUT");
519 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700520 path = host_dir;
521 } else {
522 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700523 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700524
525 std::string suffix = host
526 ? "-hostdex" // The host version.
527 : "-testdex"; // The unstripped target version.
528
529 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
530}
531
Mathieu Chartier91c91162016-01-15 09:48:15 -0800532std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700533 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
534 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700535}
536
Mathieu Chartier91c91162016-01-15 09:48:15 -0800537std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700538 if (IsHost()) {
539 const char* host_dir = getenv("ANDROID_HOST_OUT");
540 CHECK(host_dir != nullptr);
541 return host_dir;
542 }
543 return GetAndroidRoot();
544}
545
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700546// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
547#ifdef ART_TARGET
548#ifndef ART_TARGET_NATIVETEST_DIR
549#error "ART_TARGET_NATIVETEST_DIR not set."
550#endif
551// Wrap it as a string literal.
552#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
553#else
554#define ART_TARGET_NATIVETEST_DIR_STRING ""
555#endif
556
Andreas Gampee1459ae2016-06-29 09:36:30 -0700557std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700558 CHECK(name != nullptr);
559 std::string filename;
560 if (IsHost()) {
561 filename += getenv("ANDROID_HOST_OUT");
562 filename += "/framework/";
563 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700564 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700565 }
566 filename += "art-gtest-";
567 filename += name;
568 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800569 return filename;
570}
571
Mathieu Chartier91c91162016-01-15 09:48:15 -0800572std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
573 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800574 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700575 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700576 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800577 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100578 bool success = DexFileLoader::Open(filename.c_str(),
579 filename.c_str(),
580 /* verify */ true,
581 kVerifyChecksum,
582 &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700583 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800584 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700585 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
586 CHECK(dex_file->IsReadOnly());
587 }
Ian Rogerse63db272014-07-15 15:36:11 -0700588 return dex_files;
589}
590
Mathieu Chartier91c91162016-01-15 09:48:15 -0800591std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800592 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700593 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800594 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700595}
596
Mathieu Chartier91c91162016-01-15 09:48:15 -0800597std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700598 ScopedObjectAccess soa(Thread::Current());
599
Calin Juravlec79470d2017-07-12 17:37:42 -0700600 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700601 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700602 soa.Decode<mirror::ClassLoader>(jclass_loader));
Calin Juravlec79470d2017-07-12 17:37:42 -0700603 return GetDexFiles(soa, class_loader);
604}
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700605
Calin Juravlec79470d2017-07-12 17:37:42 -0700606std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
607 ScopedObjectAccess& soa,
608 Handle<mirror::ClassLoader> class_loader) {
609 std::vector<const DexFile*> ret;
610
611 DCHECK(
612 (class_loader->GetClass() ==
613 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
614 (class_loader->GetClass() ==
615 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700616
617 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
618 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800619 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700620 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800621 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700622 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800623 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
624 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700625 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700626 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700627 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800628 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
629 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700630 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
631 // at the mCookie which is a DexFile vector.
632 if (dex_elements_obj != nullptr) {
Calin Juravlec79470d2017-07-12 17:37:42 -0700633 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700634 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
635 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
636 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700637 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700638 if (element == nullptr) {
639 // Should never happen, fall back to java code to throw a NPE.
640 break;
641 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700642 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700643 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700644 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700645 DCHECK(long_array != nullptr);
646 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700647 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700648 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
649 long_array->GetWithoutChecks(j)));
650 if (cp_dex_file == nullptr) {
651 LOG(WARNING) << "Null DexFile";
652 continue;
653 }
654 ret.push_back(cp_dex_file);
655 }
656 }
657 }
658 }
659 }
660
661 return ret;
662}
663
Mathieu Chartier91c91162016-01-15 09:48:15 -0800664const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700665 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
666 DCHECK(!tmp.empty());
667 const DexFile* ret = tmp[0];
668 DCHECK(ret != nullptr);
669 return ret;
670}
671
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100672jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
673 const char* second_dex_name) {
674 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
675 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
676 std::vector<const DexFile*> class_path;
677 CHECK_NE(0U, first_dex_files.size());
678 CHECK_NE(0U, second_dex_files.size());
679 for (auto& dex_file : first_dex_files) {
680 class_path.push_back(dex_file.get());
681 loaded_dex_files_.push_back(std::move(dex_file));
682 }
683 for (auto& dex_file : second_dex_files) {
684 class_path.push_back(dex_file.get());
685 loaded_dex_files_.push_back(std::move(dex_file));
686 }
687
688 Thread* self = Thread::Current();
689 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
690 class_path);
691 self->SetClassLoaderOverride(class_loader);
692 return class_loader;
693}
694
Mathieu Chartier91c91162016-01-15 09:48:15 -0800695jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Calin Juravle7865ac72017-06-28 11:03:12 -0700696 jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
697 Thread::Current()->SetClassLoaderOverride(class_loader);
698 return class_loader;
699}
700
701jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
702 jclass loader_class,
703 jobject parent_loader) {
704 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800705 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700706 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800707 for (auto& dex_file : dex_files) {
708 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800709 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700710 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700711 Thread* self = Thread::Current();
Calin Juravle7865ac72017-06-28 11:03:12 -0700712 ScopedObjectAccess soa(self);
713
714 jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
715 self,
716 class_path,
717 loader_class,
718 parent_loader);
719
720 {
721 // Verify we build the correct chain.
722
723 ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
724 // Verify that the result has the correct class.
725 CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
726 // Verify that the parent is not null. The boot class loader will be set up as a
727 // proper object.
728 ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
729 CHECK(actual_parent != nullptr);
730
731 if (parent_loader != nullptr) {
732 // We were given a parent. Verify that it's what we expect.
733 ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
734 CHECK_EQ(expected_parent, actual_parent);
735 } else {
736 // No parent given. The parent must be the BootClassLoader.
737 CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
738 }
739 }
740
741 return result;
742}
743
744jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
745 jobject parent_loader) {
746 return LoadDexInWellKnownClassLoader(dex_name,
747 WellKnownClasses::dalvik_system_PathClassLoader,
748 parent_loader);
749}
750
751jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
752 jobject parent_loader) {
753 return LoadDexInWellKnownClassLoader(dex_name,
754 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
755 parent_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700756}
757
Mathieu Chartier91c91162016-01-15 09:48:15 -0800758std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800759 CHECK(suffix != nullptr);
760
761 std::string location;
762 if (IsHost()) {
763 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700764 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000765 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800766 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000767 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800768 }
769
770 return location;
771}
772
Calin Juravlec79470d2017-07-12 17:37:42 -0700773std::string CommonRuntimeTestImpl::CreateClassPath(
774 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
775 CHECK(!dex_files.empty());
776 std::string classpath = dex_files[0]->GetLocation();
777 for (size_t i = 1; i < dex_files.size(); i++) {
778 classpath += ":" + dex_files[i]->GetLocation();
779 }
780 return classpath;
781}
782
783std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
784 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
785 CHECK(!dex_files.empty());
786 std::string classpath = dex_files[0]->GetLocation() + "*" +
787 std::to_string(dex_files[0]->GetLocationChecksum());
788 for (size_t i = 1; i < dex_files.size(); i++) {
789 classpath += ":" + dex_files[i]->GetLocation() + "*" +
790 std::to_string(dex_files[i]->GetLocationChecksum());
791 }
792 return classpath;
793}
794
Andreas Gampe26761f72017-07-20 18:00:39 -0700795void CommonRuntimeTestImpl::FillHeap(Thread* self,
796 ClassLinker* class_linker,
797 VariableSizedHandleScope* handle_scope) {
798 DCHECK(handle_scope != nullptr);
799
800 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
801
802 // Class java.lang.Object.
803 Handle<mirror::Class> c(handle_scope->NewHandle(
804 class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
805 // Array helps to fill memory faster.
806 Handle<mirror::Class> ca(handle_scope->NewHandle(
807 class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
808
809 // Start allocating with ~128K
810 size_t length = 128 * KB;
811 while (length > 40) {
812 const int32_t array_length = length / 4; // Object[] has elements of size 4.
813 MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
814 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
815 if (self->IsExceptionPending() || h == nullptr) {
816 self->ClearException();
817
818 // Try a smaller length
819 length = length / 2;
820 // Use at most a quarter the reported free space.
821 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
822 if (length * 4 > mem) {
823 length = mem / 4;
824 }
825 }
826 }
827
828 // Allocate simple objects till it fails.
829 while (!self->IsExceptionPending()) {
830 handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
831 }
832 self->ClearException();
833}
834
835void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
836 // Use a smaller heap
837 bool found = false;
838 for (std::pair<std::string, const void*>& pair : *options) {
839 if (pair.first.find("-Xmx") == 0) {
840 pair.first = "-Xmx4M"; // Smallest we can go.
841 found = true;
842 }
843 }
844 if (!found) {
845 options->emplace_back("-Xmx4M", nullptr);
846 }
847}
848
Ian Rogerse63db272014-07-15 15:36:11 -0700849CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700850 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700851}
852
853CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700854 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700855 EXPECT_TRUE(actual_.empty()) << actual_;
856}
857
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700858void CheckJniAbortCatcher::Check(const std::string& expected_text) {
859 Check(expected_text.c_str());
860}
861
Ian Rogerse63db272014-07-15 15:36:11 -0700862void CheckJniAbortCatcher::Check(const char* expected_text) {
863 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
864 << "Expected to find: " << expected_text << "\n"
865 << "In the output : " << actual_;
866 actual_.clear();
867}
868
869void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
870 // We use += because when we're hooking the aborts like this, multiple problems can be found.
871 *reinterpret_cast<std::string*>(data) += reason;
872}
873
874} // namespace art