image_test.cc revision b3f2b5cfeac75cce1babfc61db46d457fb7c4d70
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 2346ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe#include "android-base/stringprintf.h" 2446ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 25e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/unix_file/fd_file.h" 263481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h" 27857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle#include "compiler_callbacks.h" 28a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h" 294fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/method_debug_info.h" 30857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle#include "dex/quick_compiler_callbacks.h" 313f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe#include "driver/compiler_options.h" 3262d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen#include "elf_writer.h" 3310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko#include "elf_writer_quick.h" 3451c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom#include "gc/space/image_space.h" 35e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "image_writer.h" 36f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray#include "linker/buffered_output_stream.h" 37f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray#include "linker/file_output_stream.h" 38944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko#include "linker/multi_oat_relative_patcher.h" 39d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word.h" 40d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "mirror/object-inl.h" 41e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "oat_writer.h" 420795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 4342ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes#include "signal_catcher.h" 44c143c55718342519db5398e41dda31422cf16c79buzbee#include "utils.h" 45db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 46db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromnamespace art { 47db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 48496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartierstatic const uintptr_t kRequestedImageBase = ART_BASE_ADDRESS; 49496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 50496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartierstruct CompilationHelper { 51496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<std::string> dex_file_locations; 52496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> image_locations; 53496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<std::unique_ptr<const DexFile>> extra_dex_files; 54496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> image_files; 55496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> oat_files; 56496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<ScratchFile> vdex_files; 57496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::string image_dir; 58496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 59496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier void Compile(CompilerDriver* driver, 60496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ImageHeader::StorageMode storage_mode); 61496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 62496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> GetImageObjectSectionSizes(); 63496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 64496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ~CompilationHelper(); 65496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier}; 66496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 67a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass ImageTest : public CommonCompilerTest { 6810c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers protected: 6910c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers virtual void SetUp() { 70700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom ReserveImageSpace(); 71a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom CommonCompilerTest::SetUp(); 7210c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers } 73496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 74ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier void TestWriteRead(ImageHeader::StorageMode storage_mode); 75496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 76496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier void Compile(ImageHeader::StorageMode storage_mode, 77496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper& out_helper, 78496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const std::string& extra_dex = "", 79b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko const std::initializer_list<std::string>& image_classes = {}); 80496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 81857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE { 82857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle CommonCompilerTest::SetUpRuntimeOptions(options); 83857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle callbacks_.reset(new QuickCompilerCallbacks( 84857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle verification_results_.get(), 85857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle CompilerCallbacks::CallbackMode::kCompileBootImage)); 86857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle options->push_back(std::make_pair("compilercallbacks", callbacks_.get())); 87857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle } 88857f058d4b7bd07c5c99eda416ad91516a10b4daCalin Juravle 89496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unordered_set<std::string>* GetImageClasses() OVERRIDE { 90496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier return new std::unordered_set<std::string>(image_classes_); 91496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 92496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 93b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ArtMethod* FindCopiedMethod(ArtMethod* origin, mirror::Class* klass) 94b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko REQUIRES_SHARED(Locks::mutator_lock_) { 95b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko PointerSize pointer_size = class_linker_->GetImagePointerSize(); 96b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko for (ArtMethod& m : klass->GetCopiedMethods(pointer_size)) { 97b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko if (strcmp(origin->GetName(), m.GetName()) == 0 && 98b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko origin->GetSignature() == m.GetSignature()) { 99b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko return &m; 100b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko } 101b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko } 102b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko return nullptr; 103b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko } 104b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko 105496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier private: 106496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unordered_set<std::string> image_classes_; 10710c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers}; 108db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 109496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu ChartierCompilationHelper::~CompilationHelper() { 110496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& image_file : image_files) { 111496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_file.Unlink(); 112496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 113496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& oat_file : oat_files) { 114496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier oat_file.Unlink(); 115496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 116496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& vdex_file : vdex_files) { 117496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier vdex_file.Unlink(); 118496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 119496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const int rmdir_result = rmdir(image_dir.c_str()); 120496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK_EQ(0, rmdir_result); 121496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 1223f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe 123496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartierstd::vector<size_t> CompilationHelper::GetImageObjectSectionSizes() { 124496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> ret; 125496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& image_file : image_files) { 126496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unique_ptr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str())); 127496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK(file.get() != nullptr); 128496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ImageHeader image_header; 129496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK_EQ(file->ReadFully(&image_header, sizeof(image_header)), true); 130496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK(image_header.IsValid()); 131496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ret.push_back(image_header.GetImageSize()); 132496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 133496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier return ret; 134496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 1353f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe 136496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartiervoid CompilationHelper::Compile(CompilerDriver* driver, 137496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ImageHeader::StorageMode storage_mode) { 138ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 139496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<const DexFile*> class_path = class_linker->GetBootClassPath(); 140496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 141496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (const std::unique_ptr<const DexFile>& dex_file : extra_dex_files) { 142496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier { 143496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ScopedObjectAccess soa(Thread::Current()); 144496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Inject in boot class path so that the compiler driver can see it. 145496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier class_linker->AppendToBootClassPath(soa.Self(), *dex_file.get()); 146496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 147496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier class_path.push_back(dex_file.get()); 148496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 149866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 150ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier // Enable write for dex2dex. 151496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (const DexFile* dex_file : class_path) { 152496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier dex_file_locations.push_back(dex_file->GetLocation()); 153496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier if (dex_file->IsReadOnly()) { 154496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier dex_file->EnableWrite(); 155496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 156ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier } 157866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier { 158496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Create a generic tmp file, to be the base of the .art and .oat temporary files. 159866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ScratchFile location; 160496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (int i = 0; i < static_cast<int>(class_path.size()); ++i) { 16146ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe std::string cur_location = 16246ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe android::base::StringPrintf("%s-%d.art", location.GetFilename().c_str(), i); 163866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_locations.push_back(ScratchFile(cur_location)); 164866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 165866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 166866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::string> image_filenames; 167866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (ScratchFile& file : image_locations) { 168866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string image_filename(GetSystemImageFilename(file.GetFilename().c_str(), kRuntimeISA)); 169866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filenames.push_back(image_filename); 170866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t pos = image_filename.rfind('/'); 171866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier CHECK_NE(pos, std::string::npos) << image_filename; 172866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (image_dir.empty()) { 173866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_dir = image_filename.substr(0, pos); 174866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier int mkdir_result = mkdir(image_dir.c_str(), 0700); 175866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier CHECK_EQ(0, mkdir_result) << image_dir; 176866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 177866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_files.push_back(ScratchFile(OS::CreateEmptyFile(image_filename.c_str()))); 178866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 1790e12bdc49744eb6d5c29b9611a8dbe10bac4cd53Brian Carlstrom 180866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::string> oat_filenames; 181866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::string> vdex_filenames; 182866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (const std::string& image_filename : image_filenames) { 183866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string oat_filename = ReplaceFileExtension(image_filename, "oat"); 184866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_files.push_back(ScratchFile(OS::CreateEmptyFile(oat_filename.c_str()))); 185866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filenames.push_back(oat_filename); 186866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::string vdex_filename = ReplaceFileExtension(image_filename, "vdex"); 187866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier vdex_files.push_back(ScratchFile(OS::CreateEmptyFile(vdex_filename.c_str()))); 188866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier vdex_filenames.push_back(vdex_filename); 189866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 1907b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil 191944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko std::unordered_map<const DexFile*, size_t> dex_file_to_oat_index_map; 192866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<const char*> oat_filename_vector; 193866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (const std::string& file : oat_filenames) { 194866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filename_vector.push_back(file.c_str()); 195866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 196866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<const char*> image_filename_vector; 197866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (const std::string& file : image_filenames) { 198866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filename_vector.push_back(file.c_str()); 199866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 200866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t image_idx = 0; 201496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (const DexFile* dex_file : class_path) { 202866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_file_to_oat_index_map.emplace(dex_file, image_idx); 203866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ++image_idx; 204dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 205866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // TODO: compile_pic should be a test argument. 206496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::unique_ptr<ImageWriter> writer(new ImageWriter(*driver, 207496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier kRequestedImageBase, 208da5b28adf5ba013f0784578a8b97577782e23d95Mathieu Chartier /*compile_pic*/false, 209ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier /*compile_app_image*/false, 210dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao storage_mode, 211dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao oat_filename_vector, 212944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko dex_file_to_oat_index_map)); 21300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 214700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom { 2152cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier jobject class_loader = nullptr; 2165fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers TimingLogger timings("ImageTest::WriteRead", false, false); 217f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t("CompileAll", &timings); 218496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->SetDexFilesForOatFile(class_path); 2196bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray driver->CompileAll(class_loader, class_path, /* verifier_deps */ nullptr, &timings); 22096391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom 221f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("WriteElf"); 22222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string> key_value_store; 223866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<const char*> dex_filename_vector; 224496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (size_t i = 0; i < class_path.size(); ++i) { 225866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_filename_vector.push_back(""); 226866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 227866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier key_value_store.Put(OatHeader::kBootClassPathKey, 228866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier gc::space::ImageSpace::GetMultiImageBootClassPath( 229866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_filename_vector, 230866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filename_vector, 231866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filename_vector)); 232866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 233866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<ElfWriter>> elf_writers; 234866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<OatWriter>> oat_writers; 235866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (ScratchFile& oat_file : oat_files) { 236496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier elf_writers.emplace_back(CreateElfWriterQuick(driver->GetInstructionSet(), 237496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSetFeatures(), 238496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier &driver->GetCompilerOptions(), 239496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier oat_file.GetFile())); 240866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writers.back()->Start(); 241608f2ce4b9870354079b9d63d40363914889f01aJeff Hao oat_writers.emplace_back(new OatWriter(/*compiling_boot_image*/true, 242608f2ce4b9870354079b9d63d40363914889f01aJeff Hao &timings, 243608f2ce4b9870354079b9d63d40363914889f01aJeff Hao /*profile_compilation_info*/nullptr)); 244866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 245866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 246866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<OutputStream*> rodata; 247866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<MemMap>> opened_dex_files_map; 248866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<const DexFile>> opened_dex_files; 249866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // Now that we have finalized key_value_store_, start writing the oat file. 250866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t i = 0, size = oat_writers.size(); i != size; ++i) { 251496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const DexFile* dex_file = class_path[i]; 252866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier rodata.push_back(elf_writers[i]->StartRoData()); 2539bdf108885a27ba05fae8501725649574d7c491bVladimir Marko ArrayRef<const uint8_t> raw_dex_file( 2549bdf108885a27ba05fae8501725649574d7c491bVladimir Marko reinterpret_cast<const uint8_t*>(&dex_file->GetHeader()), 2559bdf108885a27ba05fae8501725649574d7c491bVladimir Marko dex_file->GetHeader().file_size_); 256866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writers[i]->AddRawDexFileSource(raw_dex_file, 257866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_file->GetLocation().c_str(), 258866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier dex_file->GetLocationChecksum()); 259866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 260866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::unique_ptr<MemMap> cur_opened_dex_files_map; 261866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<std::unique_ptr<const DexFile>> cur_opened_dex_files; 262866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool dex_files_ok = oat_writers[i]->WriteAndOpenDexFiles( 263866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier kIsVdexEnabled ? vdex_files[i].GetFile() : oat_files[i].GetFile(), 264866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier rodata.back(), 265496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSet(), 266496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSetFeatures(), 2677b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil &key_value_store, 2687b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil /* verify */ false, // Dex files may be dex-to-dex-ed, don't verify. 26981f57d12de3f3983bbee1e8214a6088aa7bd504bNicolas Geoffray /* update_input_vdex */ false, 270866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier &cur_opened_dex_files_map, 271866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier &cur_opened_dex_files); 2727b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil ASSERT_TRUE(dex_files_ok); 273944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko 274866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (cur_opened_dex_files_map != nullptr) { 275866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier opened_dex_files_map.push_back(std::move(cur_opened_dex_files_map)); 276866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (std::unique_ptr<const DexFile>& cur_dex_file : cur_opened_dex_files) { 277866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // dex_file_oat_index_map_.emplace(dex_file.get(), i); 278866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier opened_dex_files.push_back(std::move(cur_dex_file)); 279866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 280866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } else { 281866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(cur_opened_dex_files.empty()); 282866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 283866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 2849bdf108885a27ba05fae8501725649574d7c491bVladimir Marko bool image_space_ok = writer->PrepareImageAddressSpace(); 2859bdf108885a27ba05fae8501725649574d7c491bVladimir Marko ASSERT_TRUE(image_space_ok); 2869bdf108885a27ba05fae8501725649574d7c491bVladimir Marko 287f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray if (kIsVdexEnabled) { 288f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray for (size_t i = 0, size = vdex_files.size(); i != size; ++i) { 289f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray std::unique_ptr<BufferedOutputStream> vdex_out( 290f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray MakeUnique<BufferedOutputStream>( 291f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray MakeUnique<FileOutputStream>(vdex_files[i].GetFile()))); 292f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray oat_writers[i]->WriteVerifierDeps(vdex_out.get(), nullptr); 293f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray oat_writers[i]->WriteChecksumsAndVdexHeader(vdex_out.get()); 294f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray } 295f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray } 296f54e5df37cb42d9a83fc54b375da5ef335d604a9Nicolas Geoffray 297866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t i = 0, size = oat_files.size(); i != size; ++i) { 298496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier linker::MultiOatRelativePatcher patcher(driver->GetInstructionSet(), 299496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier driver->GetInstructionSetFeatures()); 300866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier OatWriter* const oat_writer = oat_writers[i].get(); 301866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ElfWriter* const elf_writer = elf_writers[i].get(); 302496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<const DexFile*> cur_dex_files(1u, class_path[i]); 3034acefd33064d37b41ca55c3c9355345a20e5f9c2Nicolas Geoffray oat_writer->Initialize(driver, writer.get(), cur_dex_files); 3044acefd33064d37b41ca55c3c9355345a20e5f9c2Nicolas Geoffray oat_writer->PrepareLayout(&patcher); 305866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t rodata_size = oat_writer->GetOatHeader().GetExecutableOffset(); 306866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier size_t text_size = oat_writer->GetOatSize() - rodata_size; 307aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko elf_writer->PrepareDynamicSection(rodata_size, 308aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko text_size, 309aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko oat_writer->GetBssSize(), 310aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko oat_writer->GetBssRootsOffset()); 311866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 312866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier writer->UpdateOatFileLayout(i, 313866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->GetLoadedSize(), 314866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writer->GetOatDataOffset(), 315866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_writer->GetOatSize()); 316866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 317866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool rodata_ok = oat_writer->WriteRodata(rodata[i]); 318866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(rodata_ok); 319866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->EndRoData(rodata[i]); 320866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 321866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier OutputStream* text = elf_writer->StartText(); 322866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool text_ok = oat_writer->WriteCode(text); 323866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(text_ok); 324866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->EndText(text); 325866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 326866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool header_ok = oat_writer->WriteHeader(elf_writer->GetStream(), 0u, 0u, 0u); 327866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(header_ok); 328866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 329866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier writer->UpdateOatFileHeader(i, oat_writer->GetOatHeader()); 330866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 331866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->WriteDynamicSection(); 332866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier elf_writer->WriteDebugInfo(oat_writer->GetMethodDebugInfo()); 333866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 334866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool success = elf_writer->End(); 335866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(success); 336866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 338357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier 339fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier bool success_image = writer->Write(kInvalidFd, 340866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_filename_vector, 341866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier oat_filename_vector); 3428161c0336b97e11e02c000af357f8f40de2e23e4jeffhao ASSERT_TRUE(success_image); 3434303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe 344866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t i = 0, size = oat_filenames.size(); i != size; ++i) { 345866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier const char* oat_filename = oat_filenames[i].c_str(); 346866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename)); 347866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(oat_file != nullptr); 348866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier bool success_fixup = ElfWriter::Fixup(oat_file.get(), 349866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier writer->GetOatDataBegin(i)); 350866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(success_fixup); 351866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_EQ(oat_file->FlushCloseOrErase(), 0) << "Could not flush and close oat file " 352866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier << oat_filename; 353866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 3548161c0336b97e11e02c000af357f8f40de2e23e4jeffhao } 355496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 356496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 357496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartiervoid ImageTest::Compile(ImageHeader::StorageMode storage_mode, 358496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper& helper, 359496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier const std::string& extra_dex, 360b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko const std::initializer_list<std::string>& image_classes) { 361b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko for (const std::string& image_class : image_classes) { 362496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_classes_.insert(image_class); 363496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 364496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CreateCompilerDriver(Compiler::kOptimizing, kRuntimeISA, kIsTargetBuild ? 2U : 16U); 365496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Set inline filter values. 366496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier compiler_options_->SetInlineDepthLimit(CompilerOptions::kDefaultInlineDepthLimit); 367496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier compiler_options_->SetInlineMaxCodeUnits(CompilerOptions::kDefaultInlineMaxCodeUnits); 368496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_classes_.clear(); 369496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier if (!extra_dex.empty()) { 370496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier helper.extra_dex_files = OpenTestDexFiles(extra_dex.c_str()); 371496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 372496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier helper.Compile(compiler_driver_.get(), storage_mode); 373b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko if (image_classes.begin() != image_classes.end()) { 374496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Make sure the class got initialized. 375496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ScopedObjectAccess soa(Thread::Current()); 376496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 377b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko for (const std::string& image_class : image_classes) { 378b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko mirror::Class* klass = class_linker->FindSystemClass(Thread::Current(), image_class.c_str()); 379b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko EXPECT_TRUE(klass != nullptr); 380b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko EXPECT_TRUE(klass->IsInitialized()); 381b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko } 382496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 383496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 3844a289ed61242964b921434de7d375f46480472a1Brian Carlstrom 385496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartiervoid ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode) { 386496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper helper; 387496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier Compile(storage_mode, /*out*/ helper); 388866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::vector<uint64_t> image_file_sizes; 389496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (ScratchFile& image_file : helper.image_files) { 390700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str())); 3912cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(file.get() != nullptr); 3924a289ed61242964b921434de7d375f46480472a1Brian Carlstrom ImageHeader image_header; 3934303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe ASSERT_EQ(file->ReadFully(&image_header, sizeof(image_header)), true); 3944a289ed61242964b921434de7d375f46480472a1Brian Carlstrom ASSERT_TRUE(image_header.IsValid()); 395e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const auto& bitmap_section = image_header.GetImageSection(ImageHeader::kSectionImageBitmap); 396e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ASSERT_GE(bitmap_section.Offset(), sizeof(image_header)); 397e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ASSERT_NE(0U, bitmap_section.Size()); 39869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 3991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers gc::Heap* heap = Runtime::Current()->GetHeap(); 400a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ASSERT_TRUE(heap->HaveContinuousSpaces()); 401590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier gc::space::ContinuousSpace* space = heap->GetNonMovingSpace(); 4023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom ASSERT_FALSE(space->IsImageSpace()); 4032cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(space != nullptr); 404cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi ASSERT_TRUE(space->IsMallocSpace()); 405866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_file_sizes.push_back(file->GetLength()); 4064a289ed61242964b921434de7d375f46480472a1Brian Carlstrom } 4078a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 4082cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(compiler_driver_->GetImageClasses() != nullptr); 409b1fceadbd42b3047a9c06a8af6239c737d67344eAndreas Gampe std::unordered_set<std::string> image_classes(*compiler_driver_->GetImageClasses()); 41096391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom 4110e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Need to delete the compiler since it has worker threads which are attached to runtime. 4121212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_driver_.reset(); 4130e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier 41410c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers // Tear down old runtime before making a new one, clearing out misc state. 4156e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier 4166e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier // Remove the reservation of the memory for use to load the image. 4176e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier // Need to do this before we reset the runtime. 4186e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier UnreserveImageSpace(); 4196e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier 420496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier helper.extra_dex_files.clear(); 42110c5b78436bf9e603d817b40d1b98961919362b1Ian Rogers runtime_.reset(); 4222cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier java_lang_dex_file_ = nullptr; 4239cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom 4246e88ef6b604a7a945a466784580c42e6554c1289Mathieu Chartier MemMap::Init(); 4258a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 426e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers RuntimeOptions options; 42758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::string image("-Ximage:"); 428496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image.append(helper.image_locations[0].GetFilename()); 4292cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier options.push_back(std::make_pair(image.c_str(), static_cast<void*>(nullptr))); 4306e183f2e973a20f2eaca135c240908e1bf98c5d0Alex Light // By default the compiler this creates will not include patch information. 4316e183f2e973a20f2eaca135c240908e1bf98c5d0Alex Light options.push_back(std::make_pair("-Xnorelocate", nullptr)); 4328a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 43300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Create(options, false)) { 43400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "Failed to create runtime"; 43500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 43600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 43700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers runtime_.reset(Runtime::Current()); 43800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, 43900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // give it away now and then switch to a more managable ScopedObjectAccess. 44000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread::Current()->TransitionFromRunnableToSuspended(kNative); 44100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 4422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(runtime_.get() != nullptr); 4438a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom class_linker_ = runtime_->GetClassLinker(); 4449cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom 4451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers gc::Heap* heap = Runtime::Current()->GetHeap(); 446dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao ASSERT_TRUE(heap->HasBootImageSpace()); 447cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi ASSERT_TRUE(heap->GetNonMovingSpace()->IsMallocSpace()); 448a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 449dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao // We loaded the runtime with an explicit image, so it must exist. 450866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_EQ(heap->GetBootImageSpaces().size(), image_file_sizes.size()); 451496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (size_t i = 0; i < helper.dex_file_locations.size(); ++i) { 452866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier std::unique_ptr<const DexFile> dex( 453496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier LoadExpectSingleDexFile(helper.dex_file_locations[i].c_str())); 454496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ASSERT_TRUE(dex != nullptr); 455866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier uint64_t image_file_size = image_file_sizes[i]; 456866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier gc::space::ImageSpace* image_space = heap->GetBootImageSpaces()[i]; 457866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_TRUE(image_space != nullptr); 458866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (storage_mode == ImageHeader::kStorageModeUncompressed) { 459866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // Uncompressed, image should be smaller than file. 460866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_LE(image_space->GetImageHeader().GetImageSize(), image_file_size); 461496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } else if (image_file_size > 16 * KB) { 462496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Compressed, file should be smaller than image. Not really valid for small images. 463866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier ASSERT_LE(image_file_size, image_space->GetImageHeader().GetImageSize()); 464866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 465866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier 466866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier image_space->VerifyImageAllocations(); 467866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier uint8_t* image_begin = image_space->Begin(); 468866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier uint8_t* image_end = image_space->End(); 469866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (i == 0) { 470866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // This check is only valid for image 0. 471496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CHECK_EQ(kRequestedImageBase, reinterpret_cast<uintptr_t>(image_begin)); 472866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 473866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier for (size_t j = 0; j < dex->NumClassDefs(); ++j) { 474866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier const DexFile::ClassDef& class_def = dex->GetClassDef(j); 475866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier const char* descriptor = dex->GetClassDescriptor(class_def); 476866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier mirror::Class* klass = class_linker_->FindSystemClass(soa.Self(), descriptor); 477866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_TRUE(klass != nullptr) << descriptor; 478866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier if (image_classes.find(descriptor) == image_classes.end()) { 479866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_TRUE(reinterpret_cast<uint8_t*>(klass) >= image_end || 480866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier reinterpret_cast<uint8_t*>(klass) < image_begin) << descriptor; 481866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } else { 482866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier // Image classes should be located inside the image. 483866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_LT(image_begin, reinterpret_cast<uint8_t*>(klass)) << descriptor; 484866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_LT(reinterpret_cast<uint8_t*>(klass), image_end) << descriptor; 485866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier } 486866d874c4fca90385251a1df28eed0eb6e1b88e2Mathieu Chartier EXPECT_TRUE(Monitor::IsValidLockWord(klass->GetLockWord(false))); 48796391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom } 4889cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom } 489db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom} 490db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 491ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu ChartierTEST_F(ImageTest, WriteReadUncompressed) { 492ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier TestWriteRead(ImageHeader::kStorageModeUncompressed); 493ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier} 494ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier 495ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu ChartierTEST_F(ImageTest, WriteReadLZ4) { 496ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier TestWriteRead(ImageHeader::kStorageModeLZ4); 497ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier} 498ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier 499a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu ChartierTEST_F(ImageTest, WriteReadLZ4HC) { 500a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu Chartier TestWriteRead(ImageHeader::kStorageModeLZ4HC); 501a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu Chartier} 502a6e81ed4c185b7362cd5199ebe5507d00883a9b0Mathieu Chartier 503496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu ChartierTEST_F(ImageTest, TestImageLayout) { 504496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> image_sizes; 505496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier std::vector<size_t> image_sizes_extra; 506496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Compile multi-image with ImageLayoutA being the last image. 507496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier { 508496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper helper; 509b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko Compile(ImageHeader::kStorageModeUncompressed, helper, "ImageLayoutA", {"LMyClass;"}); 510496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_sizes = helper.GetImageObjectSectionSizes(); 511496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 512496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier TearDown(); 513496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier runtime_.reset(); 514496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier SetUp(); 515496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Compile multi-image with ImageLayoutB being the last image. 516496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier { 517496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier CompilationHelper helper; 518b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko Compile(ImageHeader::kStorageModeUncompressed, helper, "ImageLayoutB", {"LMyClass;"}); 519496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier image_sizes_extra = helper.GetImageObjectSectionSizes(); 520496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 521496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Make sure that the new stuff in the clinit in ImageLayoutB is in the last image and not in the 522496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // first two images. 523496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier ASSERT_EQ(image_sizes.size(), image_sizes.size()); 524496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Sizes of the images should be the same. These sizes are for the whole image unrounded. 525496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier for (size_t i = 0; i < image_sizes.size() - 1; ++i) { 526496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier EXPECT_EQ(image_sizes[i], image_sizes_extra[i]); 527496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier } 528496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier // Last image should be larger since it has a hash map and a string. 529496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier EXPECT_LT(image_sizes.back(), image_sizes_extra.back()); 530496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier} 531496577fb4d6d7baea9c093d35d17e208c831bbcaMathieu Chartier 532179486aee731f734207873244542993ed4bcff21Brian CarlstromTEST_F(ImageTest, ImageHeaderIsValid) { 533179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t image_begin = ART_BASE_ADDRESS; 534179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t image_size_ = 16 * KB; 535179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB); 536179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_checksum = 0; 537179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_file_begin = ART_BASE_ADDRESS + (4 * KB); // page aligned 538179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_data_begin = ART_BASE_ADDRESS + (8 * KB); // page aligned 539179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_data_end = ART_BASE_ADDRESS + (9 * KB); 540179486aee731f734207873244542993ed4bcff21Brian Carlstrom uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB); 541e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ImageSection sections[ImageHeader::kSectionCount]; 542179486aee731f734207873244542993ed4bcff21Brian Carlstrom ImageHeader image_header(image_begin, 543179486aee731f734207873244542993ed4bcff21Brian Carlstrom image_size_, 544e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier sections, 545179486aee731f734207873244542993ed4bcff21Brian Carlstrom image_roots, 546179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_checksum, 547179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_file_begin, 548179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_data_begin, 549179486aee731f734207873244542993ed4bcff21Brian Carlstrom oat_data_end, 55046774767fcf7780d1455e755729198648d08742eIgor Murashkin oat_file_end, 551fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_image_begin*/0U, 552fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_image_size*/0U, 553fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_oat_begin*/0U, 554fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*boot_oat_size_*/0U, 555e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier sizeof(void*), 556ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier /*compile_pic*/false, 557fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*is_pic*/false, 558ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier ImageHeader::kDefaultStorageMode, 559ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier /*data_size*/0u); 560179486aee731f734207873244542993ed4bcff21Brian Carlstrom ASSERT_TRUE(image_header.IsValid()); 561fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ASSERT_TRUE(!image_header.IsAppImage()); 562179486aee731f734207873244542993ed4bcff21Brian Carlstrom 563179486aee731f734207873244542993ed4bcff21Brian Carlstrom char* magic = const_cast<char*>(image_header.GetMagic()); 564179486aee731f734207873244542993ed4bcff21Brian Carlstrom strcpy(magic, ""); // bad magic 565179486aee731f734207873244542993ed4bcff21Brian Carlstrom ASSERT_FALSE(image_header.IsValid()); 566179486aee731f734207873244542993ed4bcff21Brian Carlstrom strcpy(magic, "art\n000"); // bad version 567179486aee731f734207873244542993ed4bcff21Brian Carlstrom ASSERT_FALSE(image_header.IsValid()); 568179486aee731f734207873244542993ed4bcff21Brian Carlstrom} 569179486aee731f734207873244542993ed4bcff21Brian Carlstrom 570b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko// Test that pointer to quick code is the same in 571b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko// a default method of an interface and in a copied method 572b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko// of a class which implements the interface. This should be true 573b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko// only if the copied method and the origin method are located in the 574b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko// same oat file. 575b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem UdovichenkoTEST_F(ImageTest, TestDefaultMethods) { 576b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko CompilationHelper helper; 577b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko Compile(ImageHeader::kStorageModeUncompressed, 578b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko helper, 579b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko "DefaultMethods", 580b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko {"LIface;", "LImpl;", "LIterableBase;"}); 581b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko 582b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko PointerSize pointer_size = class_linker_->GetImagePointerSize(); 583b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko Thread* self = Thread::Current(); 584b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ScopedObjectAccess soa(self); 585b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko 586b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // Test the pointer to quick code is the same in origin method 587b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // and in the copied method form the same oat file. 588b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko mirror::Class* iface_klass = class_linker_->LookupClass( 589b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko self, "LIface;", ObjPtr<mirror::ClassLoader>()); 590b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, iface_klass); 591b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ArtMethod* origin = iface_klass->FindDeclaredVirtualMethod( 592b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko "defaultMethod", "()V", pointer_size); 593b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, origin); 594b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko const void* code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 595b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // The origin method should have a pointer to quick code 596b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, code); 597b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code)); 598b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko mirror::Class* impl_klass = class_linker_->LookupClass( 599b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko self, "LImpl;", ObjPtr<mirror::ClassLoader>()); 600b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, impl_klass); 601b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ArtMethod* copied = FindCopiedMethod(origin, impl_klass); 602b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, copied); 603b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // the copied method should have pointer to the same quick code as the origin method 604b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_EQ(code, copied->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)); 605b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko 606b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // Test the origin method has pointer to quick code 607b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // but the copied method has pointer to interpreter 608b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // because these methods are in different oat files. 609b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko mirror::Class* iterable_klass = class_linker_->LookupClass( 610b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko self, "Ljava/lang/Iterable;", ObjPtr<mirror::ClassLoader>()); 611b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, iterable_klass); 612b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko origin = iterable_klass->FindDeclaredVirtualMethod( 613b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko "forEach", "(Ljava/util/function/Consumer;)V", pointer_size); 614b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, origin); 615b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 616b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // the origin method should have a pointer to quick code 617b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, code); 618b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code)); 619b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko mirror::Class* iterablebase_klass = class_linker_->LookupClass( 620b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko self, "LIterableBase;", ObjPtr<mirror::ClassLoader>()); 621b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, iterablebase_klass); 622b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko copied = FindCopiedMethod(origin, iterablebase_klass); 623b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_NE(nullptr, copied); 624b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko code = copied->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 625b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko // the copied method should have a pointer to interpreter 626b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko ASSERT_TRUE(class_linker_->IsQuickToInterpreterBridge(code)); 627b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko} 628b3f2b5cfeac75cce1babfc61db46d457fb7c4d70Artem Udovichenko 629db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom} // namespace art 630