image_test.cc revision 0795f23920ee9aabf28e45c63cd592dcccf00216
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 */ 16db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 17a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "image.h" 18a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 19700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 200cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers#include <string> 210cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers#include <vector> 220cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 23e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/unix_file/fd_file.h" 243481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h" 25a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h" 264fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/method_debug_info.h" 273f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe#include "driver/compiler_options.h" 2862d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen#include "elf_writer.h" 2910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko#include "elf_writer_quick.h" 3051c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom#include "gc/space/image_space.h" 31e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "image_writer.h" 32944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko#include "linker/multi_oat_relative_patcher.h" 33d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word.h" 34d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "mirror/object-inl.h" 35e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "oat_writer.h" 360795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 3742ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes#include "signal_catcher.h" 38c143c55718342519db5398e41dda31422cf16c79buzbee#include "utils.h" 39db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 40db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromnamespace art { 41db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 42496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartierstatic const uintptr_t kRequestedImageBase = ART_BASE_ADDRESS; 43496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 44496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartierstruct CompilationHelper { 45496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<std::string> dex_file_locations; 46496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> image_locations; 47496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<std::unique_ptr<const DexFile>> extra_dex_files; 48496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> image_files; 49496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> oat_files; 50496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> vdex_files; 51496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::string image_dir; 52496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 53496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier void Compile(CompilerDriver* driver, 54496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ImageHeader::StorageMode storage_mode); 55496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 56496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> GetImageObjectSectionSizes(); 57496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 58496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ~CompilationHelper(); 59496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier}; 60496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 61a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass ImageTest : public CommonCompilerTest { 6210c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers protected: 6310c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers virtual void SetUp() { 64700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom ReserveImageSpace(); 65a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom CommonCompilerTest::SetUp(); 6610c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers } 67496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 68ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier void TestWriteRead(ImageHeader::StorageMode storage_mode); 69496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 70496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier void Compile(ImageHeader::StorageMode storage_mode, 71496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper& out_helper, 72496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const std::string& extra_dex = "", 73496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const std::string& image_class = ""); 74496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 75496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unordered_set<std::string>* GetImageClasses() OVERRIDE { 76496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier return new std::unordered_set<std::string>(image_classes_); 77496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 78496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 79496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier private: 80496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unordered_set<std::string> image_classes_; 8110c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers}; 82db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 83496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu ChartierCompilationHelper::~CompilationHelper() { 84496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& image_file : image_files) { 85496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_file.Unlink(); 86496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 87496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& oat_file : oat_files) { 88496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier oat_file.Unlink(); 89496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 90496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& vdex_file : vdex_files) { 91496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier vdex_file.Unlink(); 92496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 93496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const int rmdir_result = rmdir(image_dir.c_str()); 94496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK_EQ(0, rmdir_result); 95496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 963f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe 97496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartierstd::vector<size_t> CompilationHelper::GetImageObjectSectionSizes() { 98496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> ret; 99496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& image_file : image_files) { 100496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unique_ptr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str())); 101496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK(file.get() != nullptr); 102496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ImageHeader image_header; 103496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK_EQ(file->ReadFully(&image_header, sizeof(image_header)), true); 104496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK(image_header.IsValid()); 105496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ret.push_back(image_header.GetImageSize()); 106496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 107496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier return ret; 108496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 1093f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe 110496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartiervoid CompilationHelper::Compile(CompilerDriver* driver, 111496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ImageHeader::StorageMode storage_mode) { 112ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 113496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<const DexFile*> class_path = class_linker->GetBootClassPath(); 114496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 115496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (const std::unique_ptr<const DexFile>& dex_file : extra_dex_files) { 116496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier { 117496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ScopedObjectAccess soa(Thread::Current()); 118496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Inject in boot class path so that the compiler driver can see it. 119496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier class_linker->AppendToBootClassPath(soa.Self(), *dex_file.get()); 120496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 121496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier class_path.push_back(dex_file.get()); 122496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 123866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 124ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier // Enable write for dex2dex. 125496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (const DexFile* dex_file : class_path) { 126496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier dex_file_locations.push_back(dex_file->GetLocation()); 127496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier if (dex_file->IsReadOnly()) { 128496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier dex_file->EnableWrite(); 129496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 130ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier } 131866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier { 132496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Create a generic tmp file, to be the base of the .art and .oat temporary files. 133866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ScratchFile location; 134496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (int i = 0; i < static_cast<int>(class_path.size()); ++i) { 135866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string cur_location(StringPrintf("%s-%d.art", location.GetFilename().c_str(), i)); 136866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_locations.push_back(ScratchFile(cur_location)); 137866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 138866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 139866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::string> image_filenames; 140866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (ScratchFile& file : image_locations) { 141866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string image_filename(GetSystemImageFilename(file.GetFilename().c_str(), kRuntimeISA)); 142866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filenames.push_back(image_filename); 143866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t pos = image_filename.rfind('/'); 144866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier CHECK_NE(pos, std::string::npos) << image_filename; 145866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (image_dir.empty()) { 146866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_dir = image_filename.substr(0, pos); 147866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier int mkdir_result = mkdir(image_dir.c_str(), 0700); 148866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier CHECK_EQ(0, mkdir_result) << image_dir; 149866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 150866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_files.push_back(ScratchFile(OS::CreateEmptyFile(image_filename.c_str()))); 151866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 1520e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom 153866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::string> oat_filenames; 154866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::string> vdex_filenames; 155866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (const std::string& image_filename : image_filenames) { 156866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string oat_filename = ReplaceFileExtension(image_filename, "oat"); 157866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_files.push_back(ScratchFile(OS::CreateEmptyFile(oat_filename.c_str()))); 158866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filenames.push_back(oat_filename); 159866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string vdex_filename = ReplaceFileExtension(image_filename, "vdex"); 160866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier vdex_files.push_back(ScratchFile(OS::CreateEmptyFile(vdex_filename.c_str()))); 161866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier vdex_filenames.push_back(vdex_filename); 162866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 1637b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil 164944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko std::unordered_map<const DexFile*, size_t> dex_file_to_oat_index_map; 165866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<const char*> oat_filename_vector; 166866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (const std::string& file : oat_filenames) { 167866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filename_vector.push_back(file.c_str()); 168866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 169866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<const char*> image_filename_vector; 170866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (const std::string& file : image_filenames) { 171866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filename_vector.push_back(file.c_str()); 172866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 173866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t image_idx = 0; 174496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (const DexFile* dex_file : class_path) { 175866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_file_to_oat_index_map.emplace(dex_file, image_idx); 176866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ++image_idx; 177dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 178866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // TODO: compile_pic should be a test argument. 179496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unique_ptr<ImageWriter> writer(new ImageWriter(*driver, 180496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier kRequestedImageBase, 181da5b28adf5ba013f0784578a8b97577782e23d95Mathieu Chartier /*compile_pic*/false, 182ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier /*compile_app_image*/false, 183dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao storage_mode, 184dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao oat_filename_vector, 185944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko dex_file_to_oat_index_map)); 18600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 187700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom { 1882cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier jobject class_loader = nullptr; 1895fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers TimingLogger timings("ImageTest::WriteRead", false, false); 190f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t("CompileAll", &timings); 191496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->SetDexFilesForOatFile(class_path); 192496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->CompileAll(class_loader, class_path, &timings); 19396391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom 194f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("WriteElf"); 19522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string> key_value_store; 196866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<const char*> dex_filename_vector; 197496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (size_t i = 0; i < class_path.size(); ++i) { 198866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_filename_vector.push_back(""); 199866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 200866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier key_value_store.Put(OatHeader::kBootClassPathKey, 201866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier gc::space::ImageSpace::GetMultiImageBootClassPath( 202866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_filename_vector, 203866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filename_vector, 204866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filename_vector)); 205866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 206866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<ElfWriter>> elf_writers; 207866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<OatWriter>> oat_writers; 208866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (ScratchFile& oat_file : oat_files) { 209496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier elf_writers.emplace_back(CreateElfWriterQuick(driver->GetInstructionSet(), 210496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSetFeatures(), 211496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier &driver->GetCompilerOptions(), 212496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier oat_file.GetFile())); 213866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writers.back()->Start(); 214866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writers.emplace_back(new OatWriter(/*compiling_boot_image*/true, &timings)); 215866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 216866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 217866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<OutputStream*> rodata; 218866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<MemMap>> opened_dex_files_map; 219866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<const DexFile>> opened_dex_files; 220866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // Now that we have finalized key_value_store_, start writing the oat file. 221866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t i = 0, size = oat_writers.size(); i != size; ++i) { 222496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const DexFile* dex_file = class_path[i]; 223866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier rodata.push_back(elf_writers[i]->StartRoData()); 2249bdf108885a27ba05fae8501725649574d7c491bVladimir Marko ArrayRef<const uint8_t> raw_dex_file( 2259bdf108885a27ba05fae8501725649574d7c491bVladimir Marko reinterpret_cast<const uint8_t*>(&dex_file->GetHeader()), 2269bdf108885a27ba05fae8501725649574d7c491bVladimir Marko dex_file->GetHeader().file_size_); 227866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writers[i]->AddRawDexFileSource(raw_dex_file, 228866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_file->GetLocation().c_str(), 229866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_file->GetLocationChecksum()); 230866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 231866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::unique_ptr<MemMap> cur_opened_dex_files_map; 232866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<const DexFile>> cur_opened_dex_files; 233866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool dex_files_ok = oat_writers[i]->WriteAndOpenDexFiles( 234866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier kIsVdexEnabled ? vdex_files[i].GetFile() : oat_files[i].GetFile(), 235866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier rodata.back(), 236496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSet(), 237496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSetFeatures(), 2387b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil &key_value_store, 2397b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil /* verify */ false, // Dex files may be dex-to-dex-ed, don't verify. 240866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier &cur_opened_dex_files_map, 241866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier &cur_opened_dex_files); 2427b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil ASSERT_TRUE(dex_files_ok); 243944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko 244866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (cur_opened_dex_files_map != nullptr) { 245866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier opened_dex_files_map.push_back(std::move(cur_opened_dex_files_map)); 246866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (std::unique_ptr<const DexFile>& cur_dex_file : cur_opened_dex_files) { 247866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // dex_file_oat_index_map_.emplace(dex_file.get(), i); 248866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier opened_dex_files.push_back(std::move(cur_dex_file)); 249866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 250866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } else { 251866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(cur_opened_dex_files.empty()); 252866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 253866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 2549bdf108885a27ba05fae8501725649574d7c491bVladimir Marko bool image_space_ok = writer->PrepareImageAddressSpace(); 2559bdf108885a27ba05fae8501725649574d7c491bVladimir Marko ASSERT_TRUE(image_space_ok); 2569bdf108885a27ba05fae8501725649574d7c491bVladimir Marko 257866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t i = 0, size = oat_files.size(); i != size; ++i) { 258496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier linker::MultiOatRelativePatcher patcher(driver->GetInstructionSet(), 259496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSetFeatures()); 260866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier OatWriter* const oat_writer = oat_writers[i].get(); 261866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ElfWriter* const elf_writer = elf_writers[i].get(); 262496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<const DexFile*> cur_dex_files(1u, class_path[i]); 263496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier oat_writer->PrepareLayout(driver, writer.get(), cur_dex_files, &patcher); 264866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t rodata_size = oat_writer->GetOatHeader().GetExecutableOffset(); 265866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t text_size = oat_writer->GetOatSize() - rodata_size; 266866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->SetLoadedSectionSizes(rodata_size, text_size, oat_writer->GetBssSize()); 267866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 268866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier writer->UpdateOatFileLayout(i, 269866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->GetLoadedSize(), 270866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writer->GetOatDataOffset(), 271866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writer->GetOatSize()); 272866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 273866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool rodata_ok = oat_writer->WriteRodata(rodata[i]); 274866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(rodata_ok); 275866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->EndRoData(rodata[i]); 276866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 277866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier OutputStream* text = elf_writer->StartText(); 278866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool text_ok = oat_writer->WriteCode(text); 279866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(text_ok); 280866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->EndText(text); 281866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 282866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool header_ok = oat_writer->WriteHeader(elf_writer->GetStream(), 0u, 0u, 0u); 283866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(header_ok); 284866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 285866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier writer->UpdateOatFileHeader(i, oat_writer->GetOatHeader()); 286866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 287866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->WriteDynamicSection(); 288866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->WriteDebugInfo(oat_writer->GetMethodDebugInfo()); 289866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->WritePatchLocations(oat_writer->GetAbsolutePatchLocations()); 290866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 291866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool success = elf_writer->End(); 292866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(success); 293866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 29400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 295357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier 296fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier bool success_image = writer->Write(kInvalidFd, 297866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filename_vector, 298866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filename_vector); 2998161c0336b97e11e02c000af357f8f40de2e23e4jeffhao ASSERT_TRUE(success_image); 3004303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe 301866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t i = 0, size = oat_filenames.size(); i != size; ++i) { 302866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier const char* oat_filename = oat_filenames[i].c_str(); 303866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename)); 304866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(oat_file != nullptr); 305866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool success_fixup = ElfWriter::Fixup(oat_file.get(), 306866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier writer->GetOatDataBegin(i)); 307866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(success_fixup); 308866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_EQ(oat_file->FlushCloseOrErase(), 0) << "Could not flush and close oat file " 309866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier << oat_filename; 310866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 3118161c0336b97e11e02c000af357f8f40de2e23e4jeffhao } 312496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 313496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 314496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartiervoid ImageTest::Compile(ImageHeader::StorageMode storage_mode, 315496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper& helper, 316496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const std::string& extra_dex, 317496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const std::string& image_class) { 318496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier if (!image_class.empty()) { 319496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_classes_.insert(image_class); 320496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 321496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CreateCompilerDriver(Compiler::kOptimizing, kRuntimeISA, kIsTargetBuild ? 2U : 16U); 322496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Set inline filter values. 323496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier compiler_options_->SetInlineDepthLimit(CompilerOptions::kDefaultInlineDepthLimit); 324496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier compiler_options_->SetInlineMaxCodeUnits(CompilerOptions::kDefaultInlineMaxCodeUnits); 325496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_classes_.clear(); 326496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier if (!extra_dex.empty()) { 327496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier helper.extra_dex_files = OpenTestDexFiles(extra_dex.c_str()); 328496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 329496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier helper.Compile(compiler_driver_.get(), storage_mode); 330496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier if (!image_class.empty()) { 331496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Make sure the class got initialized. 332496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ScopedObjectAccess soa(Thread::Current()); 333496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 334496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier mirror::Class* klass = class_linker->FindSystemClass(Thread::Current(), image_class.c_str()); 335496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier EXPECT_TRUE(klass != nullptr); 336496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier EXPECT_TRUE(klass->IsInitialized()); 337496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 338496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 3394a289ed61242964b921434de7d375f46480472a1Brian Carlstrom 340496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartiervoid ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode) { 341496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper helper; 342496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier Compile(storage_mode, /*out*/ helper); 343866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<uint64_t> image_file_sizes; 344496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& image_file : helper.image_files) { 345700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str())); 3462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(file.get() != nullptr); 3474a289ed61242964b921434de7d375f46480472a1Brian Carlstrom ImageHeader image_header; 3484303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe ASSERT_EQ(file->ReadFully(&image_header, sizeof(image_header)), true); 3494a289ed61242964b921434de7d375f46480472a1Brian Carlstrom ASSERT_TRUE(image_header.IsValid()); 350e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const auto& bitmap_section = image_header.GetImageSection(ImageHeader::kSectionImageBitmap); 351e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ASSERT_GE(bitmap_section.Offset(), sizeof(image_header)); 352e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ASSERT_NE(0U, bitmap_section.Size()); 35369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 3541d54e73444e017d3a65234e0f193846f3e27472bIan Rogers gc::Heap* heap = Runtime::Current()->GetHeap(); 355a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ASSERT_TRUE(heap->HaveContinuousSpaces()); 356590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier gc::space::ContinuousSpace* space = heap->GetNonMovingSpace(); 3573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom ASSERT_FALSE(space->IsImageSpace()); 3582cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(space != nullptr); 359cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi ASSERT_TRUE(space->IsMallocSpace()); 360866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_file_sizes.push_back(file->GetLength()); 3614a289ed61242964b921434de7d375f46480472a1Brian Carlstrom } 3628a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 3632cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(compiler_driver_->GetImageClasses() != nullptr); 364b1fceadbd42b3047a9c06a8af6239c737d67344eAndreas Gampe std::unordered_set<std::string> image_classes(*compiler_driver_->GetImageClasses()); 36596391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom 3660e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Need to delete the compiler since it has worker threads which are attached to runtime. 3671212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_driver_.reset(); 3680e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier 36910c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers // Tear down old runtime before making a new one, clearing out misc state. 3706e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier 3716e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier // Remove the reservation of the memory for use to load the image. 3726e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier // Need to do this before we reset the runtime. 3736e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier UnreserveImageSpace(); 3746e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier 375496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier helper.extra_dex_files.clear(); 37610c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers runtime_.reset(); 3772cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier java_lang_dex_file_ = nullptr; 3789cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom 3796e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier MemMap::Init(); 3808a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 381e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers RuntimeOptions options; 38258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::string image("-Ximage:"); 383496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image.append(helper.image_locations[0].GetFilename()); 3842cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier options.push_back(std::make_pair(image.c_str(), static_cast<void*>(nullptr))); 3856e183f2e973a20f2eaca135c240908e1bf98c5d0Alex Light // By default the compiler this creates will not include patch information. 3866e183f2e973a20f2eaca135c240908e1bf98c5d0Alex Light options.push_back(std::make_pair("-Xnorelocate", nullptr)); 3878a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 38800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Create(options, false)) { 38900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "Failed to create runtime"; 39000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 39100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 39200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers runtime_.reset(Runtime::Current()); 39300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, 39400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // give it away now and then switch to a more managable ScopedObjectAccess. 39500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread::Current()->TransitionFromRunnableToSuspended(kNative); 39600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 3972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(runtime_.get() != nullptr); 3988a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom class_linker_ = runtime_->GetClassLinker(); 3999cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom 4001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers gc::Heap* heap = Runtime::Current()->GetHeap(); 401dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao ASSERT_TRUE(heap->HasBootImageSpace()); 402cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi ASSERT_TRUE(heap->GetNonMovingSpace()->IsMallocSpace()); 403a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 404dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao // We loaded the runtime with an explicit image, so it must exist. 405866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_EQ(heap->GetBootImageSpaces().size(), image_file_sizes.size()); 406496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (size_t i = 0; i < helper.dex_file_locations.size(); ++i) { 407866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::unique_ptr<const DexFile> dex( 408496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier LoadExpectSingleDexFile(helper.dex_file_locations[i].c_str())); 409496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ASSERT_TRUE(dex != nullptr); 410866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier uint64_t image_file_size = image_file_sizes[i]; 411866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier gc::space::ImageSpace* image_space = heap->GetBootImageSpaces()[i]; 412866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(image_space != nullptr); 413866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (storage_mode == ImageHeader::kStorageModeUncompressed) { 414866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // Uncompressed, image should be smaller than file. 415866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_LE(image_space->GetImageHeader().GetImageSize(), image_file_size); 416496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } else if (image_file_size > 16 * KB) { 417496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Compressed, file should be smaller than image. Not really valid for small images. 418866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_LE(image_file_size, image_space->GetImageHeader().GetImageSize()); 419866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 420866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 421866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_space->VerifyImageAllocations(); 422866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier uint8_t* image_begin = image_space->Begin(); 423866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier uint8_t* image_end = image_space->End(); 424866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (i == 0) { 425866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // This check is only valid for image 0. 426496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK_EQ(kRequestedImageBase, reinterpret_cast<uintptr_t>(image_begin)); 427866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 428866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t j = 0; j < dex->NumClassDefs(); ++j) { 429866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier const DexFile::ClassDef& class_def = dex->GetClassDef(j); 430866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier const char* descriptor = dex->GetClassDescriptor(class_def); 431866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier mirror::Class* klass = class_linker_->FindSystemClass(soa.Self(), descriptor); 432866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_TRUE(klass != nullptr) << descriptor; 433866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (image_classes.find(descriptor) == image_classes.end()) { 434866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_TRUE(reinterpret_cast<uint8_t*>(klass) >= image_end || 435866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier reinterpret_cast<uint8_t*>(klass) < image_begin) << descriptor; 436866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } else { 437866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // Image classes should be located inside the image. 438866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_LT(image_begin, reinterpret_cast<uint8_t*>(klass)) << descriptor; 439866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_LT(reinterpret_cast<uint8_t*>(klass), image_end) << descriptor; 440866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 441866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_TRUE(Monitor::IsValidLockWord(klass->GetLockWord(false))); 44296391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom } 4439cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom } 444db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom} 445db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 446ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu ChartierTEST_F(ImageTest, WriteReadUncompressed) { 447ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier TestWriteRead(ImageHeader::kStorageModeUncompressed); 448ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier} 449ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier 450ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu ChartierTEST_F(ImageTest, WriteReadLZ4) { 451ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier TestWriteRead(ImageHeader::kStorageModeLZ4); 452ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier} 453ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier 454a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu ChartierTEST_F(ImageTest, WriteReadLZ4HC) { 455a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu Chartier TestWriteRead(ImageHeader::kStorageModeLZ4HC); 456a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu Chartier} 457a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu Chartier 458496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu ChartierTEST_F(ImageTest, TestImageLayout) { 459496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> image_sizes; 460496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> image_sizes_extra; 461496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Compile multi-image with ImageLayoutA being the last image. 462496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier { 463496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper helper; 464496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier Compile(ImageHeader::kStorageModeUncompressed, helper, "ImageLayoutA", "LMyClass;"); 465496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_sizes = helper.GetImageObjectSectionSizes(); 466496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 467496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier TearDown(); 468496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier runtime_.reset(); 469496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier SetUp(); 470496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Compile multi-image with ImageLayoutB being the last image. 471496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier { 472496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper helper; 473496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier Compile(ImageHeader::kStorageModeUncompressed, helper, "ImageLayoutB", "LMyClass;"); 474496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_sizes_extra = helper.GetImageObjectSectionSizes(); 475496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 476496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Make sure that the new stuff in the clinit in ImageLayoutB is in the last image and not in the 477496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // first two images. 478496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ASSERT_EQ(image_sizes.size(), image_sizes.size()); 479496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Sizes of the images should be the same. These sizes are for the whole image unrounded. 480496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (size_t i = 0; i < image_sizes.size() - 1; ++i) { 481496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier EXPECT_EQ(image_sizes[i], image_sizes_extra[i]); 482496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 483496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Last image should be larger since it has a hash map and a string. 484496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier EXPECT_LT(image_sizes.back(), image_sizes_extra.back()); 485496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 486496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 487179486aee731f734207873244542993ed4bcff21Brian CarlstromTEST_F(ImageTest, ImageHeaderIsValid) { 488179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t image_begin = ART_BASE_ADDRESS; 489179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t image_size_ = 16 * KB; 490179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB); 491179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_checksum = 0; 492179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_file_begin = ART_BASE_ADDRESS + (4 * KB); // page aligned 493179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_data_begin = ART_BASE_ADDRESS + (8 * KB); // page aligned 494179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_data_end = ART_BASE_ADDRESS + (9 * KB); 495179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB); 496e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ImageSection sections[ImageHeader::kSectionCount]; 497179486aee731f734207873244542993ed4bcff21Brian Carlstrom ImageHeader image_header(image_begin, 498179486aee731f734207873244542993ed4bcff21Brian Carlstrom image_size_, 499e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier sections, 500179486aee731f734207873244542993ed4bcff21Brian Carlstrom image_roots, 501179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_checksum, 502179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_file_begin, 503179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_data_begin, 504179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_data_end, 50546774767fcf7780d1455e755729198648d08742eIgor Murashkin oat_file_end, 506fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_image_begin*/0U, 507fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_image_size*/0U, 508fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_oat_begin*/0U, 509fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_oat_size_*/0U, 510e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier sizeof(void*), 511ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier /*compile_pic*/false, 512fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*is_pic*/false, 513ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier ImageHeader::kDefaultStorageMode, 514ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier /*data_size*/0u); 515179486aee731f734207873244542993ed4bcff21Brian Carlstrom ASSERT_TRUE(image_header.IsValid()); 516fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ASSERT_TRUE(!image_header.IsAppImage()); 517179486aee731f734207873244542993ed4bcff21Brian Carlstrom 518179486aee731f734207873244542993ed4bcff21Brian Carlstrom char* magic = const_cast<char*>(image_header.GetMagic()); 519179486aee731f734207873244542993ed4bcff21Brian Carlstrom strcpy(magic, ""); // bad magic 520179486aee731f734207873244542993ed4bcff21Brian Carlstrom ASSERT_FALSE(image_header.IsValid()); 521179486aee731f734207873244542993ed4bcff21Brian Carlstrom strcpy(magic, "art\n000"); // bad version 522179486aee731f734207873244542993ed4bcff21Brian Carlstrom ASSERT_FALSE(image_header.IsValid()); 523179486aee731f734207873244542993ed4bcff21Brian Carlstrom} 524179486aee731f734207873244542993ed4bcff21Brian Carlstrom 525db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom} // namespace art 526