common_test.h revision 265091e581c9f643b37e7966890911f09e223269
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License");
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * you may not use this file except in compliance with the License.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * You may obtain a copy of the License at
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *      http://www.apache.org/licenses/LICENSE-2.0
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS,
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * See the License for the specific language governing permissions and
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * limitations under the License.
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <dirent.h>
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <dlfcn.h>
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <sys/mman.h>
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <sys/stat.h>
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <sys/types.h>
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "../../external/icu4c/common/unicode/uvernum.h"
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "base/macros.h"
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "base/stl_util.h"
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "base/stringprintf.h"
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "base/unix_file/fd_file.h"
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "class_linker.h"
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "compiler/driver/compiler_driver.h"
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "dex_file.h"
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gtest/gtest.h"
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "heap.h"
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "instruction_set.h"
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "mirror/class_loader.h"
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "oat_file.h"
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "object_utils.h"
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "os.h"
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "runtime.h"
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "scoped_thread_state_change.h"
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "ScopedLocalRef.h"
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "thread.h"
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "UniquePtr.h"
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "well_known_classes.h"
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace art {
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const byte kBase64Map[256] = {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18, // NOLINT
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru   19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255, // NOLINT
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru   37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48, // NOLINT
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru   49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  255, 255, 255, 255
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubyte* DecodeBase64(const char* src, size_t* dst_size) {
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  std::vector<byte> tmp;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  uint32_t t = 0, y = 0;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  int g = 3;
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  for (size_t i = 0; src[i] != '\0'; ++i) {
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    byte c = kBase64Map[src[i] & 0xFF];
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (c == 255) continue;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // the final = symbols are read and used to trim the remaining bytes
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (c == 254) {
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      c = 0;
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      // prevent g < 0 which would potentially allow an overflow later
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      if (--g < 0) {
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *dst_size = 0;
85096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return NULL;
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      }
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else if (g != 3) {
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      // we only allow = to be at the end
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      *dst_size = 0;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      return NULL;
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    t = (t << 6) | c;
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (++y == 4) {
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      tmp.push_back((t >> 16) & 255);
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      if (g > 1) {
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.push_back((t >> 8) & 255);
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      }
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      if (g > 2) {
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.push_back(t & 255);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      }
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      y = t = 0;
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  }
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  if (y != 0) {
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *dst_size = 0;
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return NULL;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  }
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  UniquePtr<byte[]> dst(new byte[tmp.size()]);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  if (dst_size != NULL) {
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *dst_size = tmp.size();
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  } else {
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *dst_size = 0;
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  }
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  std::copy(tmp.begin(), tmp.end(), dst.get());
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  return dst.release();
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline const DexFile* OpenDexFileBase64(const char* base64,
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                               const std::string& location) {
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  // decode base64
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  CHECK(base64 != NULL);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  size_t length;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru  UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
124  CHECK(dex_bytes.get() != NULL);
125
126  // write to provided file
127  UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
128  CHECK(file.get() != NULL);
129  if (!file->WriteFully(dex_bytes.get(), length)) {
130    PLOG(FATAL) << "Failed to write base64 as dex file";
131  }
132  file.reset();
133
134  // read dex file
135  const DexFile* dex_file = DexFile::Open(location, location);
136  CHECK(dex_file != NULL);
137  return dex_file;
138}
139
140class ScratchFile {
141 public:
142  ScratchFile() {
143    filename_ = getenv("ANDROID_DATA");
144    filename_ += "/TmpFile-XXXXXX";
145    int fd = mkstemp(&filename_[0]);
146    CHECK_NE(-1, fd);
147    file_.reset(new File(fd, GetFilename()));
148  }
149
150  ~ScratchFile() {
151    int unlink_result = unlink(filename_.c_str());
152    CHECK_EQ(0, unlink_result);
153  }
154
155  const std::string& GetFilename() const {
156    return filename_;
157  }
158
159  File* GetFile() const {
160    return file_.get();
161  }
162
163  int GetFd() const {
164    return file_->Fd();
165  }
166
167 private:
168  std::string filename_;
169  UniquePtr<File> file_;
170};
171
172class CommonTest : public testing::Test {
173 public:
174  static void MakeExecutable(const mirror::ByteArray* code_array) {
175    CHECK(code_array != NULL);
176    MakeExecutable(code_array->GetData(), code_array->GetLength());
177  }
178
179  static void MakeExecutable(const std::vector<uint8_t>& code) {
180    CHECK_NE(code.size(), 0U);
181    MakeExecutable(&code[0], code.size());
182  }
183
184  // Create an OatMethod based on pointers (for unit tests)
185  OatFile::OatMethod CreateOatMethod(const void* code,
186                                     const size_t frame_size_in_bytes,
187                                     const uint32_t core_spill_mask,
188                                     const uint32_t fp_spill_mask,
189                                     const uint32_t* mapping_table,
190                                     const uint16_t* vmap_table,
191                                     const uint8_t* gc_map,
192                                     const mirror::AbstractMethod::InvokeStub* invoke_stub) {
193      return OatFile::OatMethod(NULL,
194                                reinterpret_cast<uint32_t>(code),
195                                frame_size_in_bytes,
196                                core_spill_mask,
197                                fp_spill_mask,
198                                reinterpret_cast<uint32_t>(mapping_table),
199                                reinterpret_cast<uint32_t>(vmap_table),
200                                reinterpret_cast<uint32_t>(gc_map),
201                                reinterpret_cast<uint32_t>(invoke_stub)
202#if defined(ART_USE_PORTABLE_COMPILER)
203                              , 0
204#endif
205                                );
206  }
207
208  void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
209    CHECK(method != NULL);
210
211    MethodHelper mh(method);
212    const CompiledInvokeStub* compiled_invoke_stub =
213        compiler_driver_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
214    CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
215
216    const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
217    MakeExecutable(invoke_stub);
218    const mirror::AbstractMethod::InvokeStub* method_invoke_stub =
219        reinterpret_cast<const mirror::AbstractMethod::InvokeStub*>(
220          CompiledCode::CodePointer(&invoke_stub[0],
221                                    compiled_invoke_stub->GetInstructionSet()));
222
223    LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
224              << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
225
226    if (!method->IsAbstract()) {
227      const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
228      const DexFile& dex_file = *dex_cache->GetDexFile();
229      const CompiledMethod* compiled_method =
230          compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(&dex_file,
231                                                                              method->GetDexMethodIndex()));
232      CHECK(compiled_method != NULL) << PrettyMethod(method);
233
234      const std::vector<uint8_t>& code = compiled_method->GetCode();
235      MakeExecutable(code);
236      const void* method_code = CompiledMethod::CodePointer(&code[0],
237                                                            compiled_method->GetInstructionSet());
238
239      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
240
241      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
242                                                      compiled_method->GetFrameSizeInBytes(),
243                                                      compiled_method->GetCoreSpillMask(),
244                                                      compiled_method->GetFpSpillMask(),
245                                                      &compiled_method->GetMappingTable()[0],
246                                                      &compiled_method->GetVmapTable()[0],
247                                                      NULL,
248                                                      method_invoke_stub);
249      oat_method.LinkMethod(method);
250    } else {
251      MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
252      const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
253      LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
254      OatFile::OatMethod oat_method = CreateOatMethod(method_code,
255                                                      kStackAlignment,
256                                                      0,
257                                                      0,
258                                                      NULL,
259                                                      NULL,
260                                                      NULL,
261                                                      method_invoke_stub);
262      oat_method.LinkMethod(method);
263    }
264  }
265
266  static void MakeExecutable(const void* code_start, size_t code_length) {
267    CHECK(code_start != NULL);
268    CHECK_NE(code_length, 0U);
269    uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
270    uintptr_t base = RoundDown(data, kPageSize);
271    uintptr_t limit = RoundUp(data + code_length, kPageSize);
272    uintptr_t len = limit - base;
273    int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
274    CHECK_EQ(result, 0);
275
276    // Flush instruction cache
277    // Only uses __builtin___clear_cache if GCC >= 4.3.3
278#if GCC_VERSION >= 40303
279    __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
280#elif defined(__APPLE__)
281    // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
282    // need to generate clear_cache on x86.
283#else
284#error unsupported
285#endif
286  }
287
288  static void SetEnvironmentVariables(std::string& android_data) {
289    if (IsHost()) {
290      // $ANDROID_ROOT is set on the device, but not on the host.
291      // We need to set this so that icu4c can find its locale data.
292      std::string root;
293      root += getenv("ANDROID_BUILD_TOP");
294#if defined(__linux__)
295      root += "/out/host/linux-x86";
296#elif defined(__APPLE__)
297      root += "/out/host/darwin-x86";
298#else
299#error unsupported OS
300#endif
301      setenv("ANDROID_ROOT", root.c_str(), 1);
302      setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
303    }
304
305    // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
306    android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
307    if (mkdtemp(&android_data[0]) == NULL) {
308      PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
309    }
310    setenv("ANDROID_DATA", android_data.c_str(), 1);
311  }
312
313 protected:
314  static bool IsHost() {
315    return (getenv("ANDROID_BUILD_TOP") != NULL);
316  }
317
318  virtual void SetUp() {
319    SetEnvironmentVariables(android_data_);
320    art_cache_.append(android_data_.c_str());
321    art_cache_.append("/art-cache");
322    int mkdir_result = mkdir(art_cache_.c_str(), 0700);
323    ASSERT_EQ(mkdir_result, 0);
324
325    java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
326    boot_class_path_.push_back(java_lang_dex_file_);
327
328    std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
329    std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
330
331    Runtime::Options options;
332    options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
333    options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
334    options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
335    options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
336    options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
337    if(!Runtime::Create(options, false)) {
338      LOG(FATAL) << "Failed to create runtime";
339      return;
340    }
341    runtime_.reset(Runtime::Current());
342    // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
343    // give it away now and then switch to a more managable ScopedObjectAccess.
344    Thread::Current()->TransitionFromRunnableToSuspended(kNative);
345    // Whilst we're in native take the opportunity to initialize well known classes.
346    WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
347    ScopedObjectAccess soa(Thread::Current());
348    ASSERT_TRUE(runtime_.get() != NULL);
349    class_linker_ = runtime_->GetClassLinker();
350
351    InstructionSet instruction_set = kNone;
352#if defined(__arm__)
353    instruction_set = kThumb2;
354#elif defined(__mips__)
355    instruction_set = kMips;
356#elif defined(__i386__)
357    instruction_set = kX86;
358#endif
359
360    // TODO: make selectable
361#if defined(ART_USE_PORTABLE_COMPILER)
362    CompilerBackend compiler_backend = kPortable;
363#else
364    CompilerBackend compiler_backend = kQuick;
365#endif
366
367    runtime_->SetJniDlsymLookupStub(CompilerDriver::CreateJniDlsymLookupStub(instruction_set));
368    runtime_->SetAbstractMethodErrorStubArray(CompilerDriver::CreateAbstractMethodErrorStub(instruction_set));
369    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
370      Runtime::TrampolineType type = Runtime::TrampolineType(i);
371      if (!runtime_->HasResolutionStubArray(type)) {
372        runtime_->SetResolutionStubArray(
373            CompilerDriver::CreateResolutionStub(instruction_set, type), type);
374      }
375    }
376    if (!runtime_->HasResolutionMethod()) {
377      runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
378    }
379    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
380      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
381      if (!runtime_->HasCalleeSaveMethod(type)) {
382        runtime_->SetCalleeSaveMethod(
383            runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
384      }
385    }
386    class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
387    image_classes_.reset(new std::set<std::string>);
388    compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
389                                              true, true));
390
391    // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
392    // pool is created by the runtime.
393    runtime_->GetHeap()->CreateThreadPool();
394
395    runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
396  }
397
398  virtual void TearDown() {
399    const char* android_data = getenv("ANDROID_DATA");
400    ASSERT_TRUE(android_data != NULL);
401    DIR* dir = opendir(art_cache_.c_str());
402    ASSERT_TRUE(dir != NULL);
403    dirent* e;
404    while ((e = readdir(dir)) != NULL) {
405      if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
406        continue;
407      }
408      std::string filename(art_cache_);
409      filename.push_back('/');
410      filename.append(e->d_name);
411      int unlink_result = unlink(filename.c_str());
412      ASSERT_EQ(0, unlink_result);
413    }
414    closedir(dir);
415    int rmdir_cache_result = rmdir(art_cache_.c_str());
416    ASSERT_EQ(0, rmdir_cache_result);
417    int rmdir_data_result = rmdir(android_data_.c_str());
418    ASSERT_EQ(0, rmdir_data_result);
419
420    // icu4c has a fixed 10-element array "gCommonICUDataArray".
421    // If we run > 10 tests, we fill that array and u_setCommonData fails.
422    // There's a function to clear the array, but it's not public...
423    typedef void (*IcuCleanupFn)();
424    void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
425    CHECK(sym != NULL);
426    IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
427    (*icu_cleanup_fn)();
428
429    compiler_driver_.reset();
430    image_classes_.reset();
431    STLDeleteElements(&opened_dex_files_);
432
433    Runtime::Current()->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
434  }
435
436  std::string GetLibCoreDexFileName() {
437    return GetDexFileName("core");
438  }
439
440  std::string GetDexFileName(const std::string& jar_prefix) {
441    if (IsHost()) {
442      const char* host_dir = getenv("ANDROID_HOST_OUT");
443      CHECK(host_dir != NULL);
444      return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
445    }
446    return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
447  }
448
449  const DexFile* OpenTestDexFile(const char* name) {
450    CHECK(name != NULL);
451    std::string filename;
452    if (IsHost()) {
453      filename += getenv("ANDROID_HOST_OUT");
454      filename += "/framework/";
455    } else {
456      filename += "/data/nativetest/art/";
457    }
458    filename += "art-test-dex-";
459    filename += name;
460    filename += ".jar";
461    const DexFile* dex_file = DexFile::Open(filename, filename);
462    CHECK(dex_file != NULL) << "Failed to open " << filename;
463    opened_dex_files_.push_back(dex_file);
464    return dex_file;
465  }
466
467  jobject LoadDex(const char* dex_name)
468      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
469    const DexFile* dex_file = OpenTestDexFile(dex_name);
470    CHECK(dex_file != NULL);
471    class_linker_->RegisterDexFile(*dex_file);
472    std::vector<const DexFile*> class_path;
473    class_path.push_back(dex_file);
474    ScopedObjectAccessUnchecked soa(Thread::Current());
475    ScopedLocalRef<jobject> class_loader_local(soa.Env(),
476        soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
477    jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
478    soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
479    Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
480    return class_loader;
481  }
482
483  void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
484    std::string class_descriptor(DotToDescriptor(class_name));
485    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
486    CHECK(klass != NULL) << "Class not found " << class_name;
487    for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
488      CompileMethod(klass->GetDirectMethod(i));
489    }
490    for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
491      CompileMethod(klass->GetVirtualMethod(i));
492    }
493  }
494
495  void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
496    CHECK(method != NULL);
497    compiler_driver_->CompileOne(method);
498    MakeExecutable(method);
499
500    MakeExecutable(runtime_->GetJniDlsymLookupStub());
501  }
502
503  void CompileDirectMethod(mirror::ClassLoader* class_loader,
504                           const char* class_name,
505                           const char* method_name,
506                           const char* signature)
507      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
508    std::string class_descriptor(DotToDescriptor(class_name));
509    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
510    CHECK(klass != NULL) << "Class not found " << class_name;
511    mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
512    CHECK(method != NULL) << "Direct method not found: "
513                          << class_name << "." << method_name << signature;
514    CompileMethod(method);
515  }
516
517  void CompileVirtualMethod(mirror::ClassLoader* class_loader,
518                            const char* class_name,
519                            const char* method_name,
520                            const char* signature)
521      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
522    std::string class_descriptor(DotToDescriptor(class_name));
523    mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
524    CHECK(klass != NULL) << "Class not found " << class_name;
525    mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
526    CHECK(method != NULL) << "Virtual method not found: "
527                          << class_name << "." << method_name << signature;
528    CompileMethod(method);
529  }
530
531  void ReserveImageSpace() {
532    // Reserve where the image will be loaded up front so that other parts of test set up don't
533    // accidentally end up colliding with the fixed memory address when we need to load the image.
534    image_reservation_.reset(MemMap::MapAnonymous("image reservation", (byte*)ART_BASE_ADDRESS,
535                                                  (size_t)100 * 1024 * 1024,  // 100MB
536                                                  PROT_NONE));
537  }
538
539  void UnreserveImageSpace() {
540    image_reservation_.reset();
541  }
542
543  std::string android_data_;
544  std::string art_cache_;
545  const DexFile* java_lang_dex_file_;  // owned by runtime_
546  std::vector<const DexFile*> boot_class_path_;
547  UniquePtr<Runtime> runtime_;
548  // Owned by the runtime
549  ClassLinker* class_linker_;
550  UniquePtr<CompilerDriver> compiler_driver_;
551  UniquePtr<std::set<std::string> > image_classes_;
552
553 private:
554  std::vector<const DexFile*> opened_dex_files_;
555  UniquePtr<MemMap> image_reservation_;
556};
557
558// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
559// rather than aborting, so be careful!
560class CheckJniAbortCatcher {
561 public:
562  CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
563    vm_->check_jni_abort_hook = Hook;
564    vm_->check_jni_abort_hook_data = &actual_;
565  }
566
567  ~CheckJniAbortCatcher() {
568    vm_->check_jni_abort_hook = NULL;
569    vm_->check_jni_abort_hook_data = NULL;
570    EXPECT_TRUE(actual_.empty()) << actual_;
571  }
572
573  void Check(const char* expected_text) {
574    EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
575        << "Expected to find: " << expected_text << "\n"
576        << "In the output   : " << actual_;
577    actual_.clear();
578  }
579
580 private:
581  static void Hook(void* data, const std::string& reason) {
582    // We use += because when we're hooking the aborts like this, multiple problems can be found.
583    *reinterpret_cast<std::string*>(data) += reason;
584  }
585
586  JavaVMExt* vm_;
587  std::string actual_;
588
589  DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
590};
591
592// TODO: These tests were disabled for portable when we went to having
593// MCLinker link LLVM ELF output because we no longer just have code
594// blobs in memory. We'll need to dlopen to load and relocate
595// temporary output to resurrect these tests.
596#if defined(ART_USE_PORTABLE_COMPILER)
597#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
598#else
599#define TEST_DISABLED_FOR_PORTABLE()
600#endif
601
602}  // namespace art
603
604namespace std {
605
606// TODO: isn't gtest supposed to be able to print STL types for itself?
607template <typename T>
608std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
609  os << ::art::ToString(rhs);
610  return os;
611}
612
613}  // namespace std
614