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 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_COMMON_TEST_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_COMMON_TEST_H_ 19fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom 20b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <dirent.h> 210af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h> 2227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h> 23b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/stat.h> 24b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/types.h> 25b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 26f66330a747eff155eb571b634fc9d901c55a78a7Elliott Hughes#include "../../external/icu4c/common/unicode/uvernum.h" 27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 281aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 29e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h" 30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h" 31578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h" 321212a022fa5f8ef9585d765b1809521812af882cIan Rogers#include "compiler/driver/compiler_driver.h" 334f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 347655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "entrypoints/entrypoint_utils.h" 351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/heap.h" 3690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h" 370f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "instruction_set.h" 380f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers#include "interpreter/interpreter.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 416d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 4233f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom#include "os.h" 431f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 4400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 45e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "ScopedLocalRef.h" 4690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h" 470f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "UniquePtr.h" 4800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h" 490af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 50934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art { 51934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 52b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstromstatic const byte kBase64Map[256] = { 53b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 54b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 55b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 57b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 58b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 597934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT 607934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT 61b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 627934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT 637934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT 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, 255, 255, 255, 255, 255, 255, 255, 255, 68b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 69b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 70b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 71b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 72b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 73b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 74b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 255, 255, 255, 255 75b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom}; 76b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 77b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrombyte* DecodeBase64(const char* src, size_t* dst_size) { 78b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom std::vector<byte> tmp; 79a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes uint32_t t = 0, y = 0; 80b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom int g = 3; 81b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom for (size_t i = 0; src[i] != '\0'; ++i) { 82b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom byte c = kBase64Map[src[i] & 0xFF]; 83b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (c == 255) continue; 84b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom // the final = symbols are read and used to trim the remaining bytes 85b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (c == 254) { 86b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom c = 0; 87b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom // prevent g < 0 which would potentially allow an overflow later 88b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (--g < 0) { 895147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 90b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return NULL; 91b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 92b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } else if (g != 3) { 93b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom // we only allow = to be at the end 945147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 95b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return NULL; 96b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 97b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom t = (t << 6) | c; 98b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (++y == 4) { 99b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom tmp.push_back((t >> 16) & 255); 100b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (g > 1) { 101b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom tmp.push_back((t >> 8) & 255); 102b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 103b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (g > 2) { 104b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom tmp.push_back(t & 255); 105b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 106b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom y = t = 0; 107b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 108b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 109b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (y != 0) { 1105147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 111b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return NULL; 112b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 113b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom UniquePtr<byte[]> dst(new byte[tmp.size()]); 114b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom if (dst_size != NULL) { 115b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom *dst_size = tmp.size(); 1165147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom } else { 1175147733292cd0b80ca7da3099e43cc549d67526bBrian Carlstrom *dst_size = 0; 118b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom } 119b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom std::copy(tmp.begin(), tmp.end(), dst.get()); 120b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom return dst.release(); 121b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom} 122b9cc1ca34adec5e9254f78e9ee40d57348aa2fd0Brian Carlstrom 123db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile { 124db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public: 125db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom ScratchFile() { 12634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes filename_ = getenv("ANDROID_DATA"); 12734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes filename_ += "/TmpFile-XXXXXX"; 128761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes int fd = mkstemp(&filename_[0]); 129761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes CHECK_NE(-1, fd); 130761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes file_.reset(new File(fd, GetFilename())); 131db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 132db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 133db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom ~ScratchFile() { 13434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes int unlink_result = unlink(filename_.c_str()); 135db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_EQ(0, unlink_result); 136db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 137db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 138a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const std::string& GetFilename() const { 139a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom return filename_; 140db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 141db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 142234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes File* GetFile() const { 143234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes return file_.get(); 144234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes } 145234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 146db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int GetFd() const { 147761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes return file_->Fd(); 148db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 149db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 150db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private: 15134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes std::string filename_; 152234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes UniquePtr<File> file_; 153db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom}; 154db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 155f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test { 1569baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom public: 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static void MakeExecutable(const mirror::ByteArray* code_array) { 1583320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(code_array != NULL); 1593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(code_array->GetData(), code_array->GetLength()); 1603320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 1613320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1621cb0ae742072b5ea2c7f677e6ad220ba01255daeShih-wei Liao static void MakeExecutable(const std::vector<uint8_t>& code) { 1633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK_NE(code.size(), 0U); 1643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(&code[0], code.size()); 1653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 1663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 167ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Create an OatMethod based on pointers (for unit tests) 168ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OatFile::OatMethod CreateOatMethod(const void* code, 169ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const size_t frame_size_in_bytes, 170ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const uint32_t core_spill_mask, 171ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const uint32_t fp_spill_mask, 1721809a72a66d245ae598582d658b93a24ac3bf01eIan Rogers const uint8_t* mapping_table, 1731809a72a66d245ae598582d658b93a24ac3bf01eIan Rogers const uint8_t* vmap_table, 17474180cad94848107cf297d37e72437c5a6eecf1bJeff Hao const uint8_t* gc_map) { 175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return OatFile::OatMethod(NULL, 176ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom reinterpret_cast<uint32_t>(code), 177ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom frame_size_in_bytes, 178ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom core_spill_mask, 179ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fp_spill_mask, 180ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom reinterpret_cast<uint32_t>(mapping_table), 181ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom reinterpret_cast<uint32_t>(vmap_table), 182df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom reinterpret_cast<uint32_t>(gc_map)); 183ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 184ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 185ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(method != NULL); 18774180cad94848107cf297d37e72437c5a6eecf1bJeff Hao LOG(INFO) << "MakeExecutable " << PrettyMethod(method); 1883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 189f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers const CompiledMethod* compiled_method = NULL; 1903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (!method->IsAbstract()) { 1912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 1924445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *dex_cache->GetDexFile(); 193f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers compiled_method = 19451c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom compiler_driver_->GetCompiledMethod(MethodReference(&dex_file, 19551c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom method->GetDexMethodIndex())); 196f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 197f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers if (compiled_method != NULL) { 198971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 199971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien MakeExecutable(code); 200971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const void* method_code = CompiledMethod::CodePointer(&code[0], 201971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiled_method->GetInstructionSet()); 2023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code; 203ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OatFile::OatMethod oat_method = CreateOatMethod(method_code, 204ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiled_method->GetFrameSizeInBytes(), 205ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiled_method->GetCoreSpillMask(), 206ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiled_method->GetFpSpillMask(), 207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom &compiled_method->GetMappingTable()[0], 208ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom &compiled_method->GetVmapTable()[0], 20974180cad94848107cf297d37e72437c5a6eecf1bJeff Hao NULL); 210265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_method.LinkMethod(method); 2110f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); 2123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } else { 213f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers const void* method_code; 214848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers // No code? You must mean to go into the interpreter. 215848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers method_code = GetCompiledCodeToInterpreterBridge(); 2163320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code; 217ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OatFile::OatMethod oat_method = CreateOatMethod(method_code, 218ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom kStackAlignment, 219ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 0, 220ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 0, 221ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom NULL, 222ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom NULL, 22374180cad94848107cf297d37e72437c5a6eecf1bJeff Hao NULL); 224265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_method.LinkMethod(method); 2250f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge); 2263320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 2273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 2283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom static void MakeExecutable(const void* code_start, size_t code_length) { 2303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(code_start != NULL); 2313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK_NE(code_length, 0U); 2323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uintptr_t data = reinterpret_cast<uintptr_t>(code_start); 2339baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom uintptr_t base = RoundDown(data, kPageSize); 2343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uintptr_t limit = RoundUp(data + code_length, kPageSize); 2359baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom uintptr_t len = limit - base; 2369baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC); 2377a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom CHECK_EQ(result, 0); 23824782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao 2391634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers // Flush instruction cache 24024782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao // Only uses __builtin___clear_cache if GCC >= 4.3.3 24124782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#if GCC_VERSION >= 40303 2421634155a231665f16867cbecab9332a8b1cf3b1eIan Rogers __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len)); 2437a00a3c6c9a3425ba8331ee8e479040731db651bBrian Carlstrom#else 2446f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom LOG(FATAL) << "UNIMPLEMENTED: cache flush"; 24524782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao#endif 2469baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 2479baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 248761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes static void SetEnvironmentVariables(std::string& android_data) { 249761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes if (IsHost()) { 2500af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // $ANDROID_ROOT is set on the device, but not on the host. 2510af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // We need to set this so that icu4c can find its locale data. 2520af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes std::string root; 2530af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes root += getenv("ANDROID_BUILD_TOP"); 254a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#if defined(__linux__) 2550af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes root += "/out/host/linux-x86"; 256a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#elif defined(__APPLE__) 257a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes root += "/out/host/darwin-x86"; 258a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#else 259a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#error unsupported OS 260a0cb1204543934b1f4975025cd6047eb71dc6429Elliott Hughes#endif 2610af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes setenv("ANDROID_ROOT", root.c_str(), 1); 2622fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>. 2630af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 2640af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 2657675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache 2667675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX"); 267761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes if (mkdtemp(&android_data[0]) == NULL) { 268761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed"; 2690f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes } 270761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes setenv("ANDROID_DATA", android_data.c_str(), 1); 271761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes } 272761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 273761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes protected: 274761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes static bool IsHost() { 275761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes return (getenv("ANDROID_BUILD_TOP") != NULL); 276761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes } 277761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 278761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes virtual void SetUp() { 279761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes SetEnvironmentVariables(android_data_); 2807675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom dalvik_cache_.append(android_data_.c_str()); 2817675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom dalvik_cache_.append("/dalvik-cache"); 2827675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700); 283b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(mkdir_result, 0); 284b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 285a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName()); 28633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers if (java_lang_dex_file_ == NULL) { 28733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "'\n"; 28833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers } 289654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom conscrypt_file_ = DexFile::Open(GetConscryptFileName(), GetConscryptFileName()); 29033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers if (conscrypt_file_ == NULL) { 29133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers LOG(FATAL) << "Could not open .dex file '" << GetConscryptFileName() << "'\n"; 29233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers } 293a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom boot_class_path_.push_back(java_lang_dex_file_); 294654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom boot_class_path_.push_back(conscrypt_file_); 295578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 2961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB)); 2971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB)); 29830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers 29969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Runtime::Options options; 300a4a7b48c813ad73ac795d0b405de69755b36dd6bBrian Carlstrom options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL))); 301a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom options.push_back(std::make_pair("bootclasspath", &boot_class_path_)); 30269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL))); 30330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL))); 30430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL))); 305df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom if (!Runtime::Create(options, false)) { 30600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "Failed to create runtime"; 30700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 30800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 30900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers runtime_.reset(Runtime::Current()); 31000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, 31100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // give it away now and then switch to a more managable ScopedObjectAccess. 31200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread::Current()->TransitionFromRunnableToSuspended(kNative); 3131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers { 3141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers ScopedObjectAccess soa(Thread::Current()); 3151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers ASSERT_TRUE(runtime_.get() != NULL); 3161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers class_linker_ = runtime_->GetClassLinker(); 3170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 3181d54e73444e017d3a65234e0f193846f3e27472bIan Rogers InstructionSet instruction_set = kNone; 319c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#if defined(__arm__) 3201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers instruction_set = kThumb2; 321c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#elif defined(__mips__) 3221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers instruction_set = kMips; 323c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao#elif defined(__i386__) 3241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers instruction_set = kX86; 3252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#endif 326c531cefbfb5394413122e9f57d211ba436cff012buzbee 3271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // TODO: make selectable 328c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 3291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers CompilerBackend compiler_backend = kPortable; 330c531cefbfb5394413122e9f57d211ba436cff012buzbee#else 3311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers CompilerBackend compiler_backend = kQuick; 332c531cefbfb5394413122e9f57d211ba436cff012buzbee#endif 333c531cefbfb5394413122e9f57d211ba436cff012buzbee 3341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers if (!runtime_->HasResolutionMethod()) { 3351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod()); 3361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 3371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 3381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 3391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers if (!runtime_->HasCalleeSaveMethod(type)) { 3401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers runtime_->SetCalleeSaveMethod( 3411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers runtime_->CreateCalleeSaveMethod(instruction_set, type), type); 3421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 3434f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 3441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers class_linker_->FixupDexCaches(runtime_->GetResolutionMethod()); 3451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, 3461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers true, new CompilerDriver::DescriptorSet, 3474560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom 2, true)); 3484f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 34996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom // We typically don't generate an image in unit tests, disable this optimization by default. 35096391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom compiler_driver_->SetSupportBootImageFixup(false); 3512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 3521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // We're back in native, take the opportunity to initialize well known classes. 353ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom WellKnownClasses::Init(Thread::Current()->GetJniEnv()); 35402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread 35502b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier // pool is created by the runtime. 35602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier runtime_->GetHeap()->CreateThreadPool(); 35700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test 358578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom } 359578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 360b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom virtual void TearDown() { 361b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom const char* android_data = getenv("ANDROID_DATA"); 362b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_TRUE(android_data != NULL); 3637675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom DIR* dir = opendir(dalvik_cache_.c_str()); 364b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_TRUE(dir != NULL); 3654696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes dirent* e; 3664696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes while ((e = readdir(dir)) != NULL) { 3674696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) { 368b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom continue; 369b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 3707675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom std::string filename(dalvik_cache_); 371b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom filename.push_back('/'); 3724696b5b20be2f51f4ada5f3771a205d90bff351dElliott Hughes filename.append(e->d_name); 373b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int unlink_result = unlink(filename.c_str()); 374b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, unlink_result); 375b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 376b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom closedir(dir); 3777675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom int rmdir_cache_result = rmdir(dalvik_cache_.c_str()); 378b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, rmdir_cache_result); 37934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes int rmdir_data_result = rmdir(android_data_.c_str()); 380b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, rmdir_data_result); 3810af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 3820af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // icu4c has a fixed 10-element array "gCommonICUDataArray". 3830af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // If we run > 10 tests, we fill that array and u_setCommonData fails. 3840af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // There's a function to clear the array, but it's not public... 3850af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes typedef void (*IcuCleanupFn)(); 3860af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT); 3870af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes CHECK(sym != NULL); 3880af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym); 3890af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes (*icu_cleanup_fn)(); 3900cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 3911212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_driver_.reset(); 3924d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes STLDeleteElements(&opened_dex_files_); 3932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 394b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test 395b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 396b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 397b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string GetLibCoreDexFileName() { 3983b010aa88cec548a9a4213c7cbdc416f73ea5c3cBrian Carlstrom return GetDexFileName("core-libart"); 399265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 400265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 401654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom std::string GetConscryptFileName() { 402654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom return GetDexFileName("conscrypt"); 403654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom } 404654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom 405265091e581c9f643b37e7966890911f09e223269Brian Carlstrom std::string GetDexFileName(const std::string& jar_prefix) { 406761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes if (IsHost()) { 407b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom const char* host_dir = getenv("ANDROID_HOST_OUT"); 408b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom CHECK(host_dir != NULL); 409265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str()); 410ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson } 411265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str()); 412b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 413ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson 4143f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom std::string GetTestAndroidRoot() { 4153f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom if (IsHost()) { 4163f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom const char* host_dir = getenv("ANDROID_HOST_OUT"); 4173f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom CHECK(host_dir != NULL); 4183f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom return host_dir; 4193f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom } 4203f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom return GetAndroidRoot(); 4213f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom } 4223f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom 42333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 4249f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom CHECK(name != NULL); 4259f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom std::string filename; 426761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes if (IsHost()) { 427b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += getenv("ANDROID_HOST_OUT"); 428b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += "/framework/"; 429b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom } else { 430b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += "/data/nativetest/art/"; 4319f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom } 432b2793375d42b5d90d9a0111581c4314abe11ca4cBrian Carlstrom filename += "art-test-dex-"; 4339f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += name; 4349f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += ".jar"; 435a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const DexFile* dex_file = DexFile::Open(filename, filename); 43669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom CHECK(dex_file != NULL) << "Failed to open " << filename; 437e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom CHECK_EQ(PROT_READ, dex_file->GetPermissions()); 438e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom CHECK(dex_file->IsReadOnly()); 4394d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes opened_dex_files_.push_back(dex_file); 4409f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom return dex_file; 4419f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom } 4429f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom 44333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 4449baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const DexFile* dex_file = OpenTestDexFile(dex_name); 4459baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(dex_file != NULL); 4469baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom class_linker_->RegisterDexFile(*dex_file); 4479baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom std::vector<const DexFile*> class_path; 4489baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom class_path.push_back(dex_file); 44900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 45000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jobject> class_loader_local(soa.Env(), 45100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader)); 45200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get()); 4532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get())); 45400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path); 45500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return class_loader; 4569baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4579baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 45833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) 45933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 460955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string class_descriptor(DotToDescriptor(class_name)); 4612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader); 462aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(klass != NULL) << "Class not found " << class_name; 463aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom for (size_t i = 0; i < klass->NumDirectMethods(); i++) { 464aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CompileMethod(klass->GetDirectMethod(i)); 465aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 466aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom for (size_t i = 0; i < klass->NumVirtualMethods(); i++) { 467aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CompileMethod(klass->GetVirtualMethod(i)); 468aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 469aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 470aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 471ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 4729baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(method != NULL); 4736f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum base::TimingLogger timings("CommonTest::CompileMethod", false, false); 474be576f48e4bf5c2afcaadd6e3a6d0f6a3153f031Anwar Ghuloum timings.StartSplit("CompileOne"); 4754560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom compiler_driver_->CompileOne(method, timings); 4763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom MakeExecutable(method); 4779baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4789baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 4792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers void CompileDirectMethod(mirror::ClassLoader* class_loader, 4809baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* class_name, 4819baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* method_name, 48200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* signature) 483b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 484955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string class_descriptor(DotToDescriptor(class_name)); 4852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader); 4869baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(klass != NULL) << "Class not found " << class_name; 487ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature); 4880f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes CHECK(method != NULL) << "Direct method not found: " 4890f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes << class_name << "." << method_name << signature; 4909baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CompileMethod(method); 4919baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 4929baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 4932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers void CompileVirtualMethod(mirror::ClassLoader* class_loader, 4949baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* class_name, 4959baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom const char* method_name, 49600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* signature) 497b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 498955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string class_descriptor(DotToDescriptor(class_name)); 4992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader); 5009baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(klass != NULL) << "Class not found " << class_name; 501ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature); 5020f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes CHECK(method != NULL) << "Virtual method not found: " 5030f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes << class_name << "." << method_name << signature; 5049baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CompileMethod(method); 5059baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom } 5069baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 507700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom void ReserveImageSpace() { 508700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // Reserve where the image will be loaded up front so that other parts of test set up don't 509700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // accidentally end up colliding with the fixed memory address when we need to load the image. 5102d88862f0752a7a0e65145b088f49dabd49d4284Brian Carlstrom image_reservation_.reset(MemMap::MapAnonymous("image reservation", 5112d88862f0752a7a0e65145b088f49dabd49d4284Brian Carlstrom reinterpret_cast<byte*>(ART_BASE_ADDRESS), 512700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom (size_t)100 * 1024 * 1024, // 100MB 513700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom PROT_NONE)); 514700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 515700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 516700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom void UnreserveImageSpace() { 517700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom image_reservation_.reset(); 518700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 519700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 52034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes std::string android_data_; 5217675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom std::string dalvik_cache_; 522a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const DexFile* java_lang_dex_file_; // owned by runtime_ 523654d91957edb4d1f7534ed5d743cf914db763448Brian Carlstrom const DexFile* conscrypt_file_; // owned by runtime_ 5249ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom std::vector<const DexFile*> boot_class_path_; 52590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<Runtime> runtime_; 5260e073f7b9386a461b470d30415a96480ab1b76afIan Rogers // Owned by the runtime 5277a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro ClassLinker* class_linker_; 5281212a022fa5f8ef9585d765b1809521812af882cIan Rogers UniquePtr<CompilerDriver> compiler_driver_; 5299baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 5309baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom private: 5314d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes std::vector<const DexFile*> opened_dex_files_; 532700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom UniquePtr<MemMap> image_reservation_; 533578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}; 534578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 535b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on 536b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes// rather than aborting, so be careful! 537b264f081424642b06b0bbe7102781895d41faa9dElliott Hughesclass CheckJniAbortCatcher { 538b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes public: 539b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) { 540b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook = Hook; 541b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook_data = &actual_; 542b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 543b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 544b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes ~CheckJniAbortCatcher() { 545b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook = NULL; 546b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes vm_->check_jni_abort_hook_data = NULL; 54756ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes EXPECT_TRUE(actual_.empty()) << actual_; 548b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 549b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 550b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes void Check(const char* expected_text) { 551b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n" 552b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes << "Expected to find: " << expected_text << "\n" 553b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes << "In the output : " << actual_; 5543f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes actual_.clear(); 555b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 556b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 557b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes private: 558b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes static void Hook(void* data, const std::string& reason) { 5593f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes // We use += because when we're hooking the aborts like this, multiple problems can be found. 5603f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes *reinterpret_cast<std::string*>(data) += reason; 561b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 562b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 563b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes JavaVMExt* vm_; 564b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes std::string actual_; 565b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 566b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher); 567b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes}; 568b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 569265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// TODO: These tests were disabled for portable when we went to having 570265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// MCLinker link LLVM ELF output because we no longer just have code 571265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// blobs in memory. We'll need to dlopen to load and relocate 572265091e581c9f643b37e7966890911f09e223269Brian Carlstrom// temporary output to resurrect these tests. 573265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 574265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return 575265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#else 576265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define TEST_DISABLED_FOR_PORTABLE() 577265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif 578265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 579934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom} // namespace art 58034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 58134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std { 58234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 58334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself? 58434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T> 58534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) { 58614134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes os << ::art::ToString(rhs); 58734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes return os; 58834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes} 58934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 59034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes} // namespace std 591fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom 592fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_COMMON_TEST_H_ 593