blob: d35402fd470d1d5d7edcadef90098e4a928fb96c [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>
24#include "nativehelper/ScopedLocalRef.h"
Ian Rogerse63db272014-07-15 15:36:11 -070025
26#include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080027#include "android-base/stringprintf.h"
28
Mathieu Chartiere401d142015-04-22 13:56:20 -070029#include "art_field-inl.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080030#include "base/logging.h"
Steven Morelande431e272017-07-18 16:53:49 -070031#include "base/macros.h"
Ian Rogerse63db272014-07-15 15:36:11 -070032#include "base/stl_util.h"
Ian Rogerse63db272014-07-15 15:36:11 -070033#include "base/unix_file/fd_file.h"
34#include "class_linker.h"
35#include "compiler_callbacks.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070036#include "dex_file-inl.h"
Mathieu Chartier79c87da2017-10-10 11:54:29 -070037#include "dex_file_loader.h"
Ian Rogerse63db272014-07-15 15:36:11 -070038#include "gc/heap.h"
Steven Morelande431e272017-07-18 16:53:49 -070039#include "gc_root-inl.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070040#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070041#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070042#include "interpreter/unstarted_runtime.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070043#include "java_vm_ext.h"
Ian Rogerse63db272014-07-15 15:36:11 -070044#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070045#include "mem_map.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070046#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070047#include "mirror/class_loader.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070048#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070049#include "noop_compiler_callbacks.h"
50#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070051#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070052#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070053#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070054#include "thread.h"
55#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070056
57int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080058 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
59 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
60 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000061 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080062
Andreas Gampe51d80cc2017-06-21 21:05:13 -070063 art::InitLogging(argv, art::Runtime::Abort);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070064 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070065 testing::InitGoogleTest(&argc, argv);
66 return RUN_ALL_TESTS();
67}
Ian Rogerse63db272014-07-15 15:36:11 -070068
69namespace art {
70
Andreas Gampe46ee31b2016-12-14 10:11:49 -080071using android::base::StringPrintf;
72
Alex Lighta01b5242017-03-27 10:15:27 -070073static const uint8_t kBase64Map[256] = {
74 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
78 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
79 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
80 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
81 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
82 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
83 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
84 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
85 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 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
96};
97
98uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
99 CHECK(dst_size != nullptr);
100 std::vector<uint8_t> tmp;
101 uint32_t t = 0, y = 0;
102 int g = 3;
103 for (size_t i = 0; src[i] != '\0'; ++i) {
104 uint8_t c = kBase64Map[src[i] & 0xFF];
105 if (c == 255) continue;
106 // the final = symbols are read and used to trim the remaining bytes
107 if (c == 254) {
108 c = 0;
109 // prevent g < 0 which would potentially allow an overflow later
110 if (--g < 0) {
111 *dst_size = 0;
112 return nullptr;
113 }
114 } else if (g != 3) {
115 // we only allow = to be at the end
116 *dst_size = 0;
117 return nullptr;
118 }
119 t = (t << 6) | c;
120 if (++y == 4) {
121 tmp.push_back((t >> 16) & 255);
122 if (g > 1) {
123 tmp.push_back((t >> 8) & 255);
124 }
125 if (g > 2) {
126 tmp.push_back(t & 255);
127 }
128 y = t = 0;
129 }
130 }
131 if (y != 0) {
132 *dst_size = 0;
133 return nullptr;
134 }
135 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
136 *dst_size = tmp.size();
137 std::copy(tmp.begin(), tmp.end(), dst.get());
138 return dst.release();
139}
140
Ian Rogerse63db272014-07-15 15:36:11 -0700141ScratchFile::ScratchFile() {
142 // ANDROID_DATA needs to be set
143 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
144 "Are you subclassing RuntimeTest?";
145 filename_ = getenv("ANDROID_DATA");
146 filename_ += "/TmpFile-XXXXXX";
147 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000148 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800149 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700150}
151
Mathieu Chartier866d8742016-09-21 15:24:18 -0700152ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
153 : ScratchFile(other.GetFilename() + suffix) {}
154
155ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700156 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
157 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800158 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700159}
160
161ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700162 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700163 filename_ = file->GetPath();
164 file_.reset(file);
165}
166
Mathieu Chartier866d8742016-09-21 15:24:18 -0700167ScratchFile::ScratchFile(ScratchFile&& other) {
168 *this = std::move(other);
169}
170
171ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
172 if (GetFile() != other.GetFile()) {
173 std::swap(filename_, other.filename_);
174 std::swap(file_, other.file_);
175 }
176 return *this;
177}
178
Ian Rogerse63db272014-07-15 15:36:11 -0700179ScratchFile::~ScratchFile() {
180 Unlink();
181}
182
183int ScratchFile::GetFd() const {
184 return file_->Fd();
185}
186
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800187void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800188 if (file_.get() != nullptr) {
189 if (file_->FlushCloseOrErase() != 0) {
190 PLOG(WARNING) << "Error closing scratch file.";
191 }
192 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800193}
194
195void ScratchFile::Unlink() {
196 if (!OS::FileExists(filename_.c_str())) {
197 return;
198 }
199 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700200 int unlink_result = unlink(filename_.c_str());
201 CHECK_EQ(0, unlink_result);
202}
203
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700204static bool unstarted_initialized_ = false;
205
Andreas Gampe48864112017-01-19 17:23:17 -0800206CommonRuntimeTestImpl::CommonRuntimeTestImpl()
207 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
208}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800209
210CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800211 // Ensure the dex files are cleaned up before the runtime.
212 loaded_dex_files_.clear();
213 runtime_.reset();
214}
Ian Rogerse63db272014-07-15 15:36:11 -0700215
Mathieu Chartier91c91162016-01-15 09:48:15 -0800216void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700217 if (IsHost()) {
218 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
219 // But it needs to be set so that icu4c can find its locale data.
220 const char* android_root_from_env = getenv("ANDROID_ROOT");
221 if (android_root_from_env == nullptr) {
222 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
223 const char* android_host_out = getenv("ANDROID_HOST_OUT");
224 if (android_host_out != nullptr) {
225 setenv("ANDROID_ROOT", android_host_out, 1);
226 } else {
227 // Build it from ANDROID_BUILD_TOP or cwd
228 std::string root;
229 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
230 if (android_build_top != nullptr) {
231 root += android_build_top;
232 } else {
233 // Not set by build server, so default to current directory
234 char* cwd = getcwd(nullptr, 0);
235 setenv("ANDROID_BUILD_TOP", cwd, 1);
236 root += cwd;
237 free(cwd);
238 }
239#if defined(__linux__)
240 root += "/out/host/linux-x86";
241#elif defined(__APPLE__)
242 root += "/out/host/darwin-x86";
243#else
244#error unsupported OS
245#endif
246 setenv("ANDROID_ROOT", root.c_str(), 1);
247 }
248 }
249 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
250
251 // Not set by build server, so default
252 if (getenv("ANDROID_HOST_OUT") == nullptr) {
253 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
254 }
255 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700256}
Ian Rogerse63db272014-07-15 15:36:11 -0700257
Mathieu Chartier91c91162016-01-15 09:48:15 -0800258void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700259 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700260 if (IsHost()) {
261 const char* tmpdir = getenv("TMPDIR");
262 if (tmpdir != nullptr && tmpdir[0] != 0) {
263 android_data = tmpdir;
264 } else {
265 android_data = "/tmp";
266 }
267 } else {
268 android_data = "/data/dalvik-cache";
269 }
270 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700271 if (mkdtemp(&android_data[0]) == nullptr) {
272 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
273 }
274 setenv("ANDROID_DATA", android_data.c_str(), 1);
275}
276
Mathieu Chartier91c91162016-01-15 09:48:15 -0800277void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
278 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700279 if (fail_on_error) {
280 ASSERT_EQ(rmdir(android_data.c_str()), 0);
281 } else {
282 rmdir(android_data.c_str());
283 }
284}
285
David Srbecky3e52aa42015-04-12 07:45:18 +0100286// Helper - find directory with the following format:
287// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
288static std::string GetAndroidToolsDir(const std::string& subdir1,
289 const std::string& subdir2,
290 const std::string& subdir3) {
291 std::string root;
292 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
293 if (android_build_top != nullptr) {
294 root = android_build_top;
295 } else {
296 // Not set by build server, so default to current directory
297 char* cwd = getcwd(nullptr, 0);
298 setenv("ANDROID_BUILD_TOP", cwd, 1);
299 root = cwd;
300 free(cwd);
301 }
302
303 std::string toolsdir = root + "/" + subdir1;
304 std::string founddir;
305 DIR* dir;
306 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
307 float maxversion = 0;
308 struct dirent* entry;
309 while ((entry = readdir(dir)) != nullptr) {
310 std::string format = subdir2 + "-%f";
311 float version;
312 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
313 if (version > maxversion) {
314 maxversion = version;
315 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
316 }
317 }
318 }
319 closedir(dir);
320 }
321
322 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000323 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100324 }
325 return founddir;
326}
327
Mathieu Chartier91c91162016-01-15 09:48:15 -0800328std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100329 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
330 "x86_64-linux-glibc2.15",
331 "x86_64-linux");
332}
333
Mathieu Chartier91c91162016-01-15 09:48:15 -0800334std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100335 switch (isa) {
336 case kArm:
337 case kThumb2:
338 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
339 "arm-linux-androideabi",
340 "arm-linux-androideabi");
341 case kArm64:
342 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
343 "aarch64-linux-android",
344 "aarch64-linux-android");
345 case kX86:
346 case kX86_64:
347 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
348 "x86_64-linux-android",
349 "x86_64-linux-android");
350 case kMips:
351 case kMips64:
352 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
353 "mips64el-linux-android",
354 "mips64el-linux-android");
355 case kNone:
356 break;
357 }
358 ADD_FAILURE() << "Invalid isa " << isa;
359 return "";
360}
361
Mathieu Chartier91c91162016-01-15 09:48:15 -0800362std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800363 return GetCoreFileLocation("art");
364}
365
Mathieu Chartier91c91162016-01-15 09:48:15 -0800366std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800367 return GetCoreFileLocation("oat");
368}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700369
Mathieu Chartier91c91162016-01-15 09:48:15 -0800370std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
371 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800372 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700373 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800374 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700375 static constexpr bool kVerifyChecksum = true;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100376 if (!DexFileLoader::Open(
377 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700378 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800379 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700380 } else {
381 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800382 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700383 }
384}
385
Mathieu Chartier91c91162016-01-15 09:48:15 -0800386void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700387 SetUpAndroidRoot();
388 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700389 dalvik_cache_.append(android_data_.c_str());
390 dalvik_cache_.append("/dalvik-cache");
391 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
392 ASSERT_EQ(mkdir_result, 0);
393
Ian Rogerse63db272014-07-15 15:36:11 -0700394 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
395 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
396
Ian Rogerse63db272014-07-15 15:36:11 -0700397
398 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000399 std::string boot_class_path_string = "-Xbootclasspath";
400 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
401 boot_class_path_string += ":";
402 boot_class_path_string += core_dex_file_name;
403 }
404
Richard Uhlerc2752592015-01-02 13:28:22 -0800405 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700406 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800407 options.push_back(std::make_pair(min_heap_string, nullptr));
408 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700409 options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
Andreas Gampe46c4c852017-06-21 19:49:08 -0700410 static bool gSlowDebugTestFlag = false;
411 RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700412
413 callbacks_.reset(new NoopCompilerCallbacks());
414
Ian Rogerse63db272014-07-15 15:36:11 -0700415 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800416
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700417 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
418 if (callbacks_.get() != nullptr) {
419 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
420 }
421
Richard Uhler66d874d2015-01-15 09:37:19 -0800422 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700423 if (!Runtime::Create(options, false)) {
424 LOG(FATAL) << "Failed to create runtime";
425 return;
426 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800427 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700428 runtime_.reset(Runtime::Current());
429 class_linker_ = runtime_->GetClassLinker();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700430
Andreas Gampea00f0122015-12-16 16:54:35 -0800431 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
432 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
433 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
434
435 // Get the boot class path from the runtime so it can be used in tests.
436 boot_class_path_ = class_linker_->GetBootClassPath();
437 ASSERT_FALSE(boot_class_path_.empty());
438 java_lang_dex_file_ = boot_class_path_[0];
439
440 FinalizeSetup();
Andreas Gampe46c4c852017-06-21 19:49:08 -0700441
442 // Ensure that we're really running with debug checks enabled.
443 CHECK(gSlowDebugTestFlag);
Andreas Gampea00f0122015-12-16 16:54:35 -0800444}
445
Mathieu Chartier91c91162016-01-15 09:48:15 -0800446void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700447 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
448 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700449 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700450 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700451 unstarted_initialized_ = true;
452 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700453
Andreas Gampea00f0122015-12-16 16:54:35 -0800454 {
455 ScopedObjectAccess soa(Thread::Current());
456 class_linker_->RunRootClinits();
457 }
Ian Rogerse63db272014-07-15 15:36:11 -0700458
459 // We're back in native, take the opportunity to initialize well known classes.
460 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
461
462 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
463 // pool is created by the runtime.
464 runtime_->GetHeap()->CreateThreadPool();
465 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700466 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
467 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700468}
469
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700470void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
Alex Lighta59dd802014-07-02 16:28:08 -0700471 ASSERT_TRUE(dirpath != nullptr);
472 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700473 ASSERT_TRUE(dir != nullptr);
474 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700475 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700476 while ((e = readdir(dir)) != nullptr) {
477 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
478 continue;
479 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700480 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700481 filename.push_back('/');
482 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700483 int stat_result = lstat(filename.c_str(), &s);
484 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
485 if (S_ISDIR(s.st_mode)) {
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700486 if (recursive) {
487 ClearDirectory(filename.c_str());
488 int rmdir_result = rmdir(filename.c_str());
489 ASSERT_EQ(0, rmdir_result) << filename;
490 }
Alex Lighta59dd802014-07-02 16:28:08 -0700491 } else {
492 int unlink_result = unlink(filename.c_str());
493 ASSERT_EQ(0, unlink_result) << filename;
494 }
Ian Rogerse63db272014-07-15 15:36:11 -0700495 }
496 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700497}
498
Mathieu Chartier91c91162016-01-15 09:48:15 -0800499void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700500 const char* android_data = getenv("ANDROID_DATA");
501 ASSERT_TRUE(android_data != nullptr);
502 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700503 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
504 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700505 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800506 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700507
Andreas Gampe48864112017-01-19 17:23:17 -0800508 if (runtime_ != nullptr) {
509 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
510 }
Ian Rogerse63db272014-07-15 15:36:11 -0700511}
512
Andreas Gampec7d4a582015-09-30 11:52:02 -0700513static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
514 std::string path;
515 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700516 const char* host_dir = getenv("ANDROID_HOST_OUT");
517 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700518 path = host_dir;
519 } else {
520 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700521 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700522
523 std::string suffix = host
524 ? "-hostdex" // The host version.
525 : "-testdex"; // The unstripped target version.
526
527 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
528}
529
Mathieu Chartier91c91162016-01-15 09:48:15 -0800530std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700531 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
532 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700533}
534
Mathieu Chartier91c91162016-01-15 09:48:15 -0800535std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700536 if (IsHost()) {
537 const char* host_dir = getenv("ANDROID_HOST_OUT");
538 CHECK(host_dir != nullptr);
539 return host_dir;
540 }
541 return GetAndroidRoot();
542}
543
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700544// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
545#ifdef ART_TARGET
546#ifndef ART_TARGET_NATIVETEST_DIR
547#error "ART_TARGET_NATIVETEST_DIR not set."
548#endif
549// Wrap it as a string literal.
550#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
551#else
552#define ART_TARGET_NATIVETEST_DIR_STRING ""
553#endif
554
Andreas Gampee1459ae2016-06-29 09:36:30 -0700555std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700556 CHECK(name != nullptr);
557 std::string filename;
558 if (IsHost()) {
559 filename += getenv("ANDROID_HOST_OUT");
560 filename += "/framework/";
561 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700562 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700563 }
564 filename += "art-gtest-";
565 filename += name;
566 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800567 return filename;
568}
569
Mathieu Chartier91c91162016-01-15 09:48:15 -0800570std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
571 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800572 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700573 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700574 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800575 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100576 bool success = DexFileLoader::Open(filename.c_str(),
577 filename.c_str(),
578 /* verify */ true,
579 kVerifyChecksum,
580 &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700581 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800582 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700583 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
584 CHECK(dex_file->IsReadOnly());
585 }
Ian Rogerse63db272014-07-15 15:36:11 -0700586 return dex_files;
587}
588
Mathieu Chartier91c91162016-01-15 09:48:15 -0800589std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800590 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700591 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800592 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700593}
594
Mathieu Chartier91c91162016-01-15 09:48:15 -0800595std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700596 ScopedObjectAccess soa(Thread::Current());
597
Calin Juravlec79470d2017-07-12 17:37:42 -0700598 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700599 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700600 soa.Decode<mirror::ClassLoader>(jclass_loader));
Calin Juravlec79470d2017-07-12 17:37:42 -0700601 return GetDexFiles(soa, class_loader);
602}
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700603
Calin Juravlec79470d2017-07-12 17:37:42 -0700604std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
605 ScopedObjectAccess& soa,
606 Handle<mirror::ClassLoader> class_loader) {
607 std::vector<const DexFile*> ret;
608
609 DCHECK(
610 (class_loader->GetClass() ==
611 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
612 (class_loader->GetClass() ==
613 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700614
615 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
616 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800617 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700618 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800619 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700620 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800621 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
622 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700623 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700624 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700625 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800626 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
627 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700628 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
629 // at the mCookie which is a DexFile vector.
630 if (dex_elements_obj != nullptr) {
Calin Juravlec79470d2017-07-12 17:37:42 -0700631 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700632 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
633 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
634 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700635 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700636 if (element == nullptr) {
637 // Should never happen, fall back to java code to throw a NPE.
638 break;
639 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700640 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700641 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700642 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700643 DCHECK(long_array != nullptr);
644 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700645 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700646 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
647 long_array->GetWithoutChecks(j)));
648 if (cp_dex_file == nullptr) {
649 LOG(WARNING) << "Null DexFile";
650 continue;
651 }
652 ret.push_back(cp_dex_file);
653 }
654 }
655 }
656 }
657 }
658
659 return ret;
660}
661
Mathieu Chartier91c91162016-01-15 09:48:15 -0800662const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700663 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
664 DCHECK(!tmp.empty());
665 const DexFile* ret = tmp[0];
666 DCHECK(ret != nullptr);
667 return ret;
668}
669
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100670jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
671 const char* second_dex_name) {
672 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
673 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
674 std::vector<const DexFile*> class_path;
675 CHECK_NE(0U, first_dex_files.size());
676 CHECK_NE(0U, second_dex_files.size());
677 for (auto& dex_file : first_dex_files) {
678 class_path.push_back(dex_file.get());
679 loaded_dex_files_.push_back(std::move(dex_file));
680 }
681 for (auto& dex_file : second_dex_files) {
682 class_path.push_back(dex_file.get());
683 loaded_dex_files_.push_back(std::move(dex_file));
684 }
685
686 Thread* self = Thread::Current();
687 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
688 class_path);
689 self->SetClassLoaderOverride(class_loader);
690 return class_loader;
691}
692
Mathieu Chartier91c91162016-01-15 09:48:15 -0800693jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Calin Juravle7865ac72017-06-28 11:03:12 -0700694 jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
695 Thread::Current()->SetClassLoaderOverride(class_loader);
696 return class_loader;
697}
698
699jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
700 jclass loader_class,
701 jobject parent_loader) {
702 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800703 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700704 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800705 for (auto& dex_file : dex_files) {
706 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800707 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700708 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700709 Thread* self = Thread::Current();
Calin Juravle7865ac72017-06-28 11:03:12 -0700710 ScopedObjectAccess soa(self);
711
712 jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
713 self,
714 class_path,
715 loader_class,
716 parent_loader);
717
718 {
719 // Verify we build the correct chain.
720
721 ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
722 // Verify that the result has the correct class.
723 CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
724 // Verify that the parent is not null. The boot class loader will be set up as a
725 // proper object.
726 ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
727 CHECK(actual_parent != nullptr);
728
729 if (parent_loader != nullptr) {
730 // We were given a parent. Verify that it's what we expect.
731 ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
732 CHECK_EQ(expected_parent, actual_parent);
733 } else {
734 // No parent given. The parent must be the BootClassLoader.
735 CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
736 }
737 }
738
739 return result;
740}
741
742jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
743 jobject parent_loader) {
744 return LoadDexInWellKnownClassLoader(dex_name,
745 WellKnownClasses::dalvik_system_PathClassLoader,
746 parent_loader);
747}
748
749jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
750 jobject parent_loader) {
751 return LoadDexInWellKnownClassLoader(dex_name,
752 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
753 parent_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700754}
755
Mathieu Chartier91c91162016-01-15 09:48:15 -0800756std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800757 CHECK(suffix != nullptr);
758
759 std::string location;
760 if (IsHost()) {
761 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700762 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000763 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800764 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000765 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800766 }
767
768 return location;
769}
770
Calin Juravlec79470d2017-07-12 17:37:42 -0700771std::string CommonRuntimeTestImpl::CreateClassPath(
772 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
773 CHECK(!dex_files.empty());
774 std::string classpath = dex_files[0]->GetLocation();
775 for (size_t i = 1; i < dex_files.size(); i++) {
776 classpath += ":" + dex_files[i]->GetLocation();
777 }
778 return classpath;
779}
780
781std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
782 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
783 CHECK(!dex_files.empty());
784 std::string classpath = dex_files[0]->GetLocation() + "*" +
785 std::to_string(dex_files[0]->GetLocationChecksum());
786 for (size_t i = 1; i < dex_files.size(); i++) {
787 classpath += ":" + dex_files[i]->GetLocation() + "*" +
788 std::to_string(dex_files[i]->GetLocationChecksum());
789 }
790 return classpath;
791}
792
Andreas Gampe26761f72017-07-20 18:00:39 -0700793void CommonRuntimeTestImpl::FillHeap(Thread* self,
794 ClassLinker* class_linker,
795 VariableSizedHandleScope* handle_scope) {
796 DCHECK(handle_scope != nullptr);
797
798 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
799
800 // Class java.lang.Object.
801 Handle<mirror::Class> c(handle_scope->NewHandle(
802 class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
803 // Array helps to fill memory faster.
804 Handle<mirror::Class> ca(handle_scope->NewHandle(
805 class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
806
807 // Start allocating with ~128K
808 size_t length = 128 * KB;
809 while (length > 40) {
810 const int32_t array_length = length / 4; // Object[] has elements of size 4.
811 MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
812 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
813 if (self->IsExceptionPending() || h == nullptr) {
814 self->ClearException();
815
816 // Try a smaller length
817 length = length / 2;
818 // Use at most a quarter the reported free space.
819 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
820 if (length * 4 > mem) {
821 length = mem / 4;
822 }
823 }
824 }
825
826 // Allocate simple objects till it fails.
827 while (!self->IsExceptionPending()) {
828 handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
829 }
830 self->ClearException();
831}
832
833void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
834 // Use a smaller heap
835 bool found = false;
836 for (std::pair<std::string, const void*>& pair : *options) {
837 if (pair.first.find("-Xmx") == 0) {
838 pair.first = "-Xmx4M"; // Smallest we can go.
839 found = true;
840 }
841 }
842 if (!found) {
843 options->emplace_back("-Xmx4M", nullptr);
844 }
845}
846
Ian Rogerse63db272014-07-15 15:36:11 -0700847CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700848 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700849}
850
851CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700852 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700853 EXPECT_TRUE(actual_.empty()) << actual_;
854}
855
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700856void CheckJniAbortCatcher::Check(const std::string& expected_text) {
857 Check(expected_text.c_str());
858}
859
Ian Rogerse63db272014-07-15 15:36:11 -0700860void CheckJniAbortCatcher::Check(const char* expected_text) {
861 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
862 << "Expected to find: " << expected_text << "\n"
863 << "In the output : " << actual_;
864 actual_.clear();
865}
866
867void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
868 // We use += because when we're hooking the aborts like this, multiple problems can be found.
869 *reinterpret_cast<std::string*>(data) += reason;
870}
871
872} // namespace art