common_test.h revision 971bf3f9184010d68b9a3ad30b396fa401af91a3
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 17b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <dirent.h> 180af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h> 1927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h> 20b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/stat.h> 21b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/types.h> 22b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 23578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h" 241f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h" 259baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "compiler.h" 26578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h" 2733f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "file.h" 2890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h" 291f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "heap.h" 300f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "instruction_set.h" 317a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#include "macros.h" 323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 3433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "os.h" 351f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 3614134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes#include "stl_util.h" 3790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "stringprintf.h" 3890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h" 390af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uclean.h" 400af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uvernum.h" 410f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "UniquePtr.h" 420af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 43934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art { 44934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 45b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstromstatic const byte kBase64Map[256] = { 46b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 47b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 48b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 49b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 50b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 51b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 52a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT 53a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT 54b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 55a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT 56a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT 57b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 58b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 59b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 60b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 61b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 63b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 64b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 65b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 66b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 67b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255 68b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom}; 69b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 70b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrombyte* DecodeBase64(const char* src, size_t* dst_size) { 71b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom std::vector<byte> tmp; 72a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes uint32_t t = 0, y = 0; 73b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom int g = 3; 74b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom for (size_t i = 0; src[i] != '\0'; ++i) { 75b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom byte c = kBase64Map[src[i] & 0xFF]; 76b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (c == 255) continue; 77b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom // the final = symbols are read and used to trim the remaining bytes 78b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (c == 254) { 79b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom c = 0; 80b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom // prevent g < 0 which would potentially allow an overflow later 81b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (--g < 0) { 825147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 83b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return NULL; 84b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 85b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } else if (g != 3) { 86b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom // we only allow = to be at the end 875147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 88b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return NULL; 89b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 90b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom t = (t << 6) | c; 91b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (++y == 4) { 92b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom tmp.push_back((t >> 16) & 255); 93b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (g > 1) { 94b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom tmp.push_back((t >> 8) & 255); 95b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 96b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (g > 2) { 97b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom tmp.push_back(t & 255); 98b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 99b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom y = t = 0; 100b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 101b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 102b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (y != 0) { 1035147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 104b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return NULL; 105b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 106b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom UniquePtr<byte[]> dst(new byte[tmp.size()]); 107b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (dst_size != NULL) { 108b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom *dst_size = tmp.size(); 1095147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom } else { 1105147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 111b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 112b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom std::copy(tmp.begin(), tmp.end(), dst.get()); 113b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return dst.release(); 114b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom} 115b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 1169f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic inline const DexFile* OpenDexFileBase64(const char* base64, 1179f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const std::string& location) { 11833f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom // decode base64 119578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom CHECK(base64 != NULL); 120578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom size_t length; 1214d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length)); 1224d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes CHECK(dex_bytes.get() != NULL); 12333f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom 12433f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom // write to provided file 12533f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom UniquePtr<File> file(OS::OpenFile(location.c_str(), true)); 12633f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom CHECK(file.get() != NULL); 1274d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes if (!file->WriteFully(dex_bytes.get(), length)) { 12833f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom PLOG(FATAL) << "Failed to write base64 as dex file"; 12933f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom } 13033f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom file.reset(); 13133f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom 13233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom // read dex file 133a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const DexFile* dex_file = DexFile::Open(location, location); 134578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom CHECK(dex_file != NULL); 135f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom return dex_file; 136578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom} 137578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 138db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile { 139db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public: 140db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom ScratchFile() { 14134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes filename_ = getenv("ANDROID_DATA"); 14234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes filename_ += "/TmpFile-XXXXXX"; 14334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes fd_ = mkstemp(&filename_[0]); 144db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_NE(-1, fd_); 145a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom file_.reset(OS::FileFromFd(GetFilename().c_str(), fd_)); 146db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 147db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 148db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom ~ScratchFile() { 14934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes int unlink_result = unlink(filename_.c_str()); 150db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_EQ(0, unlink_result); 151db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int close_result = close(fd_); 152db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_EQ(0, close_result); 153db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 154db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 155a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const std::string& GetFilename() const { 156a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom return filename_; 157db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 158db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 159234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes File* GetFile() const { 160234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes return file_.get(); 161234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes } 162234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 163db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int GetFd() const { 164db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom return fd_; 165db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 166db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 167db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private: 16834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes std::string filename_; 169db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int fd_; 170234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes UniquePtr<File> file_; 171db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom}; 172db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 173f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test { 1749baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public: 1753320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom static void MakeExecutable(const ByteArray* code_array) { 1763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(code_array != NULL); 1773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(code_array->GetData(), code_array->GetLength()); 1783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 1793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1801cb0ae742072b5ea2c7f677e6ad220ba01255daeShih-wei Liao static void MakeExecutable(const std::vector<uint8_t>& code) { 1813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK_NE(code.size(), 0U); 1823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(&code[0], code.size()); 1833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 1843320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 185ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Create an OatMethod based on pointers (for unit tests) 186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OatFile::OatMethod CreateOatMethod(const void* code, 187ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const size_t frame_size_in_bytes, 188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const uint32_t core_spill_mask, 189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const uint32_t fp_spill_mask, 190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const uint32_t* mapping_table, 191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const uint16_t* vmap_table, 192e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const uint8_t* gc_map, 193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const Method::InvokeStub* invoke_stub) { 194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return OatFile::OatMethod(NULL, 195ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom reinterpret_cast<uint32_t>(code), 196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom frame_size_in_bytes, 197ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom core_spill_mask, 198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fp_spill_mask, 199ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom reinterpret_cast<uint32_t>(mapping_table), 200ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom reinterpret_cast<uint32_t>(vmap_table), 201e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom reinterpret_cast<uint32_t>(gc_map), 2020c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien reinterpret_cast<uint32_t>(invoke_stub) 2030c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien#if defined(ART_USE_LLVM_COMPILER) 204971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien , 0 2050c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien#endif 2060c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien ); 207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 208ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 2093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom void MakeExecutable(Method* method) { 2103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(method != NULL); 2113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2126d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers MethodHelper mh(method); 2130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = 2146d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty()); 2153320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method); 216f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 217971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 218971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien MakeExecutable(invoke_stub); 219971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const Method::InvokeStub* method_invoke_stub = 220971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien reinterpret_cast<const Method::InvokeStub*>( 2214284bb9e8b79add46e61da897fa02df3625888f7Logan Chien CompiledCode::CodePointer(&invoke_stub[0], 2224284bb9e8b79add46e61da897fa02df3625888f7Logan Chien compiled_invoke_stub->GetInstructionSet())); 223f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 2243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom LOG(INFO) << "MakeExecutable " << PrettyMethod(method) 2253320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub); 2263320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (!method->IsAbstract()) { 2280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 2290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); 2300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 2310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file, 2320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->GetDexMethodIndex())); 2333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL) << PrettyMethod(method); 234f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 235971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 236971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien MakeExecutable(code); 237971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const void* method_code = CompiledMethod::CodePointer(&code[0], 238971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiled_method->GetInstructionSet()); 239f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 2403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code; 241f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 242ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OatFile::OatMethod oat_method = CreateOatMethod(method_code, 243ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiled_method->GetFrameSizeInBytes(), 244ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiled_method->GetCoreSpillMask(), 245ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiled_method->GetFpSpillMask(), 246ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom &compiled_method->GetMappingTable()[0], 247ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom &compiled_method->GetVmapTable()[0], 248e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom NULL, 249ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom method_invoke_stub); 250ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.LinkMethodPointers(method); 2513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } else { 2523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(runtime_->GetAbstractMethodErrorStubArray()); 2533320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData(); 2543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code; 255ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OatFile::OatMethod oat_method = CreateOatMethod(method_code, 256ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom kStackAlignment, 257ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 0, 258ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 0, 259ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom NULL, 260ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom NULL, 261e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom NULL, 262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom method_invoke_stub); 263ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.LinkMethodPointers(method); 2643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 2653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 2663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom static void MakeExecutable(const void* code_start, size_t code_length) { 2683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(code_start != NULL); 2693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK_NE(code_length, 0U); 2703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uintptr_t data = reinterpret_cast<uintptr_t>(code_start); 2719baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom uintptr_t base = RoundDown(data, kPageSize); 2723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uintptr_t limit = RoundUp(data + code_length, kPageSize); 2739baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom uintptr_t len = limit - base; 2749baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC); 2757a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom CHECK_EQ(result, 0); 27624782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao 2771634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers // Flush instruction cache 27824782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao // Only uses __builtin___clear_cache if GCC >= 4.3.3 27924782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303 2801634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len)); 2817a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#elif defined(__APPLE__) 28224782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not 28324782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao // need to generate clear_cache on x86. 2847a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else 2857a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#error unsupported 28624782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif 2879baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 2889baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 289578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom protected: 290578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom virtual void SetUp() { 2914a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom is_host_ = getenv("ANDROID_BUILD_TOP") != NULL; 2924a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom 2930af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes if (is_host_) { 2940af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // $ANDROID_ROOT is set on the device, but not on the host. 2950af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // We need to set this so that icu4c can find its locale data. 2960af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes std::string root; 2970af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes root += getenv("ANDROID_BUILD_TOP"); 298a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__) 2990af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes root += "/out/host/linux-x86"; 300a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__) 301a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes root += "/out/host/darwin-x86"; 302a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else 303a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS 304a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif 3050af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes setenv("ANDROID_ROOT", root.c_str(), 1); 3060af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 3070af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 30869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache 30969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX"); 3100f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes if (mkdtemp(&android_data_[0]) == NULL) { 3110f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes PLOG(FATAL) << "mkdtemp(\"" << &android_data_[0] << "\") failed"; 3120f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes } 31334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes setenv("ANDROID_DATA", android_data_.c_str(), 1); 31434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes art_cache_.append(android_data_.c_str()); 315b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom art_cache_.append("/art-cache"); 316b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int mkdir_result = mkdir(art_cache_.c_str(), 0700); 317b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(mkdir_result, 0); 318b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 319a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName()); 320a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom boot_class_path_.push_back(java_lang_dex_file_); 321578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 322699f9f42058ce438930ee0a5a9ae6451e3d8a2feElliott Hughes std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB)); 323699f9f42058ce438930ee0a5a9ae6451e3d8a2feElliott Hughes std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB)); 32430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers 32569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Runtime::Options options; 326a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL))); 327a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom options.push_back(std::make_pair("bootclasspath", &boot_class_path_)); 32869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL))); 32930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL))); 33030fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL))); 33169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom runtime_.reset(Runtime::Create(options, false)); 33290a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes ASSERT_TRUE(runtime_.get() != NULL); 3337a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro class_linker_ = runtime_->GetClassLinker(); 3340cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 3354f0d07c783afef89703dce32c94440fc8621a29bIan Rogers InstructionSet instruction_set = kNone; 3362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#if defined(__i386__) 3374f0d07c783afef89703dce32c94440fc8621a29bIan Rogers instruction_set = kX86; 3382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#elif defined(__arm__) 3394f0d07c783afef89703dce32c94440fc8621a29bIan Rogers instruction_set = kThumb2; 3402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif 3418add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set)); 3424f0d07c783afef89703dce32c94440fc8621a29bIan Rogers runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set)); 343362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 3441cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type = Runtime::TrampolineType(i); 3451cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers if (!runtime_->HasResolutionStubArray(type)) { 3464f0d07c783afef89703dce32c94440fc8621a29bIan Rogers runtime_->SetResolutionStubArray( 3474f0d07c783afef89703dce32c94440fc8621a29bIan Rogers Compiler::CreateResolutionStub(instruction_set, type), type); 3481cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers } 3491cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers } 3501984651929744dd603fd082e23eacd877b9bc177Ian Rogers if (!runtime_->HasResolutionMethod()) { 3511984651929744dd603fd082e23eacd877b9bc177Ian Rogers runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod()); 3521984651929744dd603fd082e23eacd877b9bc177Ian Rogers } 353362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 3544f0d07c783afef89703dce32c94440fc8621a29bIan Rogers Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 3554f0d07c783afef89703dce32c94440fc8621a29bIan Rogers if (!runtime_->HasCalleeSaveMethod(type)) { 3564f0d07c783afef89703dce32c94440fc8621a29bIan Rogers runtime_->SetCalleeSaveMethod( 3574f0d07c783afef89703dce32c94440fc8621a29bIan Rogers runtime_->CreateCalleeSaveMethod(instruction_set, type), type); 3584f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 3594f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 3601984651929744dd603fd082e23eacd877b9bc177Ian Rogers class_linker_->FixupDexCaches(runtime_->GetResolutionMethod()); 361e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes image_classes_.reset(new std::set<std::string>); 362e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes compiler_.reset(new Compiler(instruction_set, true, 2, false, image_classes_.get(), 363ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom true, true)); 3642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 365b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption before the test 366578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom } 367578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 368b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom virtual void TearDown() { 369b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom const char* android_data = getenv("ANDROID_DATA"); 370b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_TRUE(android_data != NULL); 371b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom DIR* dir = opendir(art_cache_.c_str()); 372b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_TRUE(dir != NULL); 373b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom while (true) { 3747b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes dirent entry; 3757b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes dirent* entry_ptr; 376b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int readdir_result = readdir_r(dir, &entry, &entry_ptr); 377b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, readdir_result); 378b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom if (entry_ptr == NULL) { 379b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom break; 380b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 381b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) { 382b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom continue; 383b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 384b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string filename(art_cache_); 385b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom filename.push_back('/'); 386b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom filename.append(entry_ptr->d_name); 387b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int unlink_result = unlink(filename.c_str()); 388b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, unlink_result); 389b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 390b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom closedir(dir); 391b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int rmdir_cache_result = rmdir(art_cache_.c_str()); 392b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, rmdir_cache_result); 39334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes int rmdir_data_result = rmdir(android_data_.c_str()); 394b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, rmdir_data_result); 3950af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 3960af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // icu4c has a fixed 10-element array "gCommonICUDataArray". 3970af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // If we run > 10 tests, we fill that array and u_setCommonData fails. 3980af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // There's a function to clear the array, but it's not public... 3990af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes typedef void (*IcuCleanupFn)(); 4000af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT); 4010af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes CHECK(sym != NULL); 4020af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym); 4030af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes (*icu_cleanup_fn)(); 4040cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 4050e073f7b9386a461b470d30415a96480ab1b76afIan Rogers compiler_.reset(); 406e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes image_classes_.reset(); 4074d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes STLDeleteElements(&opened_dex_files_); 4082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 409b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test 410b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 411b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 412b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string GetLibCoreDexFileName() { 413b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom if (is_host_) { 414b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom const char* host_dir = getenv("ANDROID_HOST_OUT"); 415b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom CHECK(host_dir != NULL); 416b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom return StringPrintf("%s/framework/core-hostdex.jar", host_dir); 417ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson } 418a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom return StringPrintf("%s/framework/core.jar", GetAndroidRoot()); 419b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 420ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson 4219f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const DexFile* OpenTestDexFile(const char* name) { 4229f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom CHECK(name != NULL); 4239f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom std::string filename; 4249f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom if (is_host_) { 425b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += getenv("ANDROID_HOST_OUT"); 426b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += "/framework/"; 427b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom } else { 428b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += "/data/nativetest/art/"; 4299f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom } 430b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += "art-test-dex-"; 4319f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += name; 4329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += ".jar"; 433a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const DexFile* dex_file = DexFile::Open(filename, filename); 43469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom CHECK(dex_file != NULL) << "Failed to open " << filename; 4354d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes opened_dex_files_.push_back(dex_file); 4369f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom return dex_file; 4379f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom } 4389f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom 43940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom ClassLoader* LoadDex(const char* dex_name) { 4409baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const DexFile* dex_file = OpenTestDexFile(dex_name); 4419baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(dex_file != NULL); 4429baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom class_linker_->RegisterDexFile(*dex_file); 4439baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom std::vector<const DexFile*> class_path; 4449baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom class_path.push_back(dex_file); 44540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom SirtRef<ClassLoader> class_loader(PathClassLoader::AllocCompileTime(class_path)); 44640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom CHECK(class_loader.get() != NULL); 44740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom Thread::Current()->SetClassLoaderOverride(class_loader.get()); 44840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom return class_loader.get(); 4499baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4509baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 451365c10235438607541fa2259a5fec48061b90bd8Ian Rogers void CompileClass(ClassLoader* class_loader, const char* class_name) { 452955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string class_descriptor(DotToDescriptor(class_name)); 453c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader); 454aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(klass != NULL) << "Class not found " << class_name; 455aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom for (size_t i = 0; i < klass->NumDirectMethods(); i++) { 456aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CompileMethod(klass->GetDirectMethod(i)); 457aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 458aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom for (size_t i = 0; i < klass->NumVirtualMethods(); i++) { 459aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CompileMethod(klass->GetVirtualMethod(i)); 460aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 461aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 462aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 4639baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom void CompileMethod(Method* method) { 4649baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(method != NULL); 4652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers compiler_->CompileOne(method); 4663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(method); 4673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 468169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers MakeExecutable(runtime_->GetJniDlsymLookupStub()); 4699baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4709baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 47140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom void CompileDirectMethod(ClassLoader* class_loader, 4729baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* class_name, 4739baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* method_name, 4749baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* signature) { 475955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string class_descriptor(DotToDescriptor(class_name)); 476c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader); 4779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(klass != NULL) << "Class not found " << class_name; 4789baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom Method* method = klass->FindDirectMethod(method_name, signature); 4790f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes CHECK(method != NULL) << "Direct method not found: " 4800f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes << class_name << "." << method_name << signature; 4819baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CompileMethod(method); 4829baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4839baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 48440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom void CompileVirtualMethod(ClassLoader* class_loader, 4859baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* class_name, 4869baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* method_name, 4879baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* signature) { 488955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string class_descriptor(DotToDescriptor(class_name)); 489c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader); 4909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(klass != NULL) << "Class not found " << class_name; 4919baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom Method* method = klass->FindVirtualMethod(method_name, signature); 4920f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes CHECK(method != NULL) << "Virtual method not found: " 4930f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes << class_name << "." << method_name << signature; 4949baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CompileMethod(method); 4959baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4969baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 4974a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom bool is_host_; 49834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes std::string android_data_; 499b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string art_cache_; 500a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const DexFile* java_lang_dex_file_; // owned by runtime_ 5019ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom std::vector<const DexFile*> boot_class_path_; 50290a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<Runtime> runtime_; 5030e073f7b9386a461b470d30415a96480ab1b76afIan Rogers // Owned by the runtime 5047a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro ClassLinker* class_linker_; 5050e073f7b9386a461b470d30415a96480ab1b76afIan Rogers UniquePtr<Compiler> compiler_; 506e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes UniquePtr<std::set<std::string> > image_classes_; 5079baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 5089baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private: 5094d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes std::vector<const DexFile*> opened_dex_files_; 510578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}; 511578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 512b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on 513b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// rather than aborting, so be careful! 514b264f081424642b06b0bbe7102781895d41faa9dElliott Hughesclass CheckJniAbortCatcher { 515b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes public: 516b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) { 517b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook = Hook; 518b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook_data = &actual_; 519b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 520b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 521b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes ~CheckJniAbortCatcher() { 522b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook = NULL; 523b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook_data = NULL; 52456ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes EXPECT_TRUE(actual_.empty()) << actual_; 525b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 526b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 527b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes void Check(const char* expected_text) { 528b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n" 529b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes << "Expected to find: " << expected_text << "\n" 530b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes << "In the output : " << actual_; 5313f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes actual_.clear(); 532b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 533b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 534b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes private: 535b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes static void Hook(void* data, const std::string& reason) { 5363f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes // We use += because when we're hooking the aborts like this, multiple problems can be found. 5373f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes *reinterpret_cast<std::string*>(data) += reason; 538b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 539b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 540b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes JavaVMExt* vm_; 541b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes std::string actual_; 542b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 543b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher); 544b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes}; 545b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 546934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom} // namespace art 54734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 54834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std { 54934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 55034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself? 55134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T> 55234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) { 55314134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes os << ::art::ToString(rhs); 55434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes return os; 55534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes} 55634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 55734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes} // namespace std 558