oat_writer.cc revision 49a0f158ed11974fa2cc12014c9f55a31dabd8df
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 */ 16e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 17e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_writer.h" 18e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 19a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include <zlib.h> 20a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes 211aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 22761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h" 23e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "class_linker.h" 24e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "class_loader.h" 25e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "os.h" 26cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom#include "output_stream.h" 27a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 2800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 297469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h" 30ec0142313a470edecf52b4f034433404b7264358jeffhao#include "verifier/method_verifier.h" 31e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 32e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 34cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::Create(OutputStream& output_stream, 3510037c866b04550fc5461058c398c2e3e509381ajeffhao const std::vector<const DexFile*>& dex_files, 3628db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_checksum, 3728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_begin, 3881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 4081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom OatWriter oat_writer(dex_files, 4128db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum, 4228db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin, 4381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location, 4481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom compiler); 45cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom return oat_writer.Write(output_stream); 46e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 47e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 483320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, 4928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_checksum, 5028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_begin, 5181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 533320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom compiler_ = &compiler; 5428db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_ = image_file_location_oat_checksum; 5528db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin_ = image_file_location_oat_begin; 5681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_ = image_file_location; 57e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_files_ = &dex_files; 580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers oat_header_ = NULL; 590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers executable_offset_padding_length_ = 0; 60e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 6181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom size_t offset = InitOatHeader(); 62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatDexFiles(offset); 6389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = InitDexFiles(offset); 64389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset = InitOatClasses(offset); 65e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCode(offset); 66e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFiles(offset); 67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); 69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 70e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersOatWriter::~OatWriter() { 720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers delete oat_header_; 730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_dex_files_); 74389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom STLDeleteElements(&oat_classes_); 750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 7781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromsize_t OatWriter::InitOatHeader() { 78e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatHeader 7981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom oat_header_ = new OatHeader(compiler_->GetInstructionSet(), 8081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom dex_files_, 8128db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_, 8228db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin_, 8381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_); 84e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t offset = sizeof(*oat_header_); 8581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom offset += image_file_location_.size(); 86e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 87e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 88e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 89e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatDexFiles(size_t offset) { 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatDexFiles 91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom OatDexFile* oat_dex_file = new OatDexFile(*dex_file); 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_.push_back(oat_dex_file); 96e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_dex_file->SizeOf(); 97e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 98e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 99e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 100e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 10189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstromsize_t OatWriter::InitDexFiles(size_t offset) { 10289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // calculate the offsets within OatDexFiles to the DexFiles 10389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 10489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // dex files are required to be 4 byte aligned 10589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = RoundUp(offset, 4); 10689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 10789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // set offset in OatDexFile to DexFile 10889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_dex_files_[i]->dex_file_offset_ = offset; 10989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 11089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 11189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset += dex_file->GetHeader().file_size_; 11289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 11389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return offset; 11489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom} 11589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 116389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::InitOatClasses(size_t offset) { 117389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // create the OatClasses 118389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // calculate the offsets within OatDexFiles to OatClasses 119e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 120e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 121e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t class_def_index = 0; 122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file->NumClassDefs(); 123c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers class_def_index++) { 1246e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->methods_offsets_[class_def_index] = offset; 125e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 126e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file->GetClassData(class_def); 1270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t num_methods = 0; 1280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data != NULL) { // ie not an empty class, such as a marker interface 1290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(*dex_file, class_data); 1300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_direct_methods = it.NumDirectMethods(); 1310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_virtual_methods = it.NumVirtualMethods(); 1320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers num_methods = num_direct_methods + num_virtual_methods; 1330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1340755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 135ec0142313a470edecf52b4f034433404b7264358jeffhao Compiler::ClassReference class_ref = Compiler::ClassReference(dex_file, class_def_index); 136ec0142313a470edecf52b4f034433404b7264358jeffhao CompiledClass* compiled_class = compiler_->GetCompiledClass(class_ref); 137ec0142313a470edecf52b4f034433404b7264358jeffhao Class::Status status; 138ec0142313a470edecf52b4f034433404b7264358jeffhao if (compiled_class != NULL) { 139ec0142313a470edecf52b4f034433404b7264358jeffhao status = compiled_class->GetStatus(); 140ec0142313a470edecf52b4f034433404b7264358jeffhao } else if (verifier::MethodVerifier::IsClassRejected(class_ref)) { 141ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusError; 142ec0142313a470edecf52b4f034433404b7264358jeffhao } else { 143ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusNotReady; 144ec0142313a470edecf52b4f034433404b7264358jeffhao } 1450755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 1460755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom OatClass* oat_class = new OatClass(status, num_methods); 147389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_.push_back(oat_class); 148389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset += oat_class->SizeOf(); 149e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1506e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->UpdateChecksum(*oat_header_); 151e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 152e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 153e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 154e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 155e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCode(size_t offset) { 156e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatHeader to executable code 157e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t old_offset = offset; 158e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // required to be on a new page boundary 159e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = RoundUp(offset, kPageSize); 160e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header_->SetExecutableOffset(offset); 161e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom executable_offset_padding_length_ = offset - old_offset; 162e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 164e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 165e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFiles(size_t offset) { 166e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t oat_class_index = 0; 167e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 168e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 169e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 170e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFile(offset, oat_class_index, *dex_file); 171e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 172e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 173e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 174e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 175e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFile(size_t offset, 176e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t& oat_class_index, 177e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file) { 178ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes for (size_t class_def_index = 0; 179e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file.NumClassDefs(); 180e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index++, oat_class_index++) { 181e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 182c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers offset = InitOatCodeClassDef(offset, oat_class_index, class_def_index, dex_file, class_def); 183389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->UpdateChecksum(*oat_header_); 184e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 185e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 186e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 187e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 188e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeClassDef(size_t offset, 189c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers size_t oat_class_index, size_t class_def_index, 190e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 191e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 192e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 1940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, such as a marker interface 195387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return offset; 196387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 1970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 198389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom CHECK_EQ(oat_classes_[oat_class_index]->method_offsets_.size(), 1990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.NumDirectMethods() + it.NumVirtualMethods()); 2000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 2010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 2020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 203e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 2050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 206e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 2080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 2090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 210c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 21108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 21208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 21308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 218c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 21908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 22008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 22108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 226e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 227e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 228e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2291bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughessize_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, 2301bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t __attribute__((unused)) class_def_index, 2311bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t class_def_method_index, 2321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes bool __attribute__((unused)) is_native, 23308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType type, 2341bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes uint32_t method_idx, const DexFile* dex_file) { 2353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledMethod if available 2363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t code_offset = 0; 2373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t frame_size_in_bytes = kStackAlignment; 2383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t core_spill_mask = 0; 2393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t fp_spill_mask = 0; 2403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t mapping_table_offset = 0; 2413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t vmap_table_offset = 0; 242e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint32_t gc_map_offset = 0; 2433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledInvokeStub if available 2443320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t invoke_stub_offset = 0; 245fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#if defined(ART_USE_LLVM_COMPILER) 246971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_offset = 0; 247fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#endif 2483320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledMethod* compiled_method = 25011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file, method_idx)); 2513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 252971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = compiled_method->AlignCode(offset); 253971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 254971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 255971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 256971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 257971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_method->CodeDelta(); 258971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = offset + sizeof(code_size) + thumb_offset; 259971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 260971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 261971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 262971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end()) { 263971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = code_iter->second; 26455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 265971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&code, code_offset); 266971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(code_size); // code size is prepended before code 267971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += code_size; 268971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&code[0], code_size); 269971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 270971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); 271971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien core_spill_mask = compiled_method->GetCoreSpillMask(); 272971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien fp_spill_mask = compiled_method->GetFpSpillMask(); 273971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 274971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 275971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 276971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = (mapping_table_size == 0) ? 0 : offset; 277971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 278971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 279971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table); 280971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end()) { 281971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = mapping_iter->second; 282971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 283971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.Put(&mapping_table, mapping_table_offset); 284971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += mapping_table_size; 285971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size); 286971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 287ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 288971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 289971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 290971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = (vmap_table_size == 0) ? 0 : offset; 291e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 292971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 293971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table); 294971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end()) { 295971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = vmap_iter->second; 296971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 297971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.Put(&vmap_table, vmap_table_offset); 298971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += vmap_table_size; 299971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size); 300971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 301e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 3020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const std::vector<uint8_t>& gc_map = compiled_method->GetNativeGcMap(); 303971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 304971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = (gc_map_size == 0) ? 0 : offset; 305971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 306ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa#if !defined(NDEBUG) 307971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // We expect GC maps except when the class hasn't been verified or the method is native 308ec0142313a470edecf52b4f034433404b7264358jeffhao Compiler::ClassReference class_ref = Compiler::ClassReference(dex_file, class_def_index); 309ec0142313a470edecf52b4f034433404b7264358jeffhao CompiledClass* compiled_class = compiler_->GetCompiledClass(class_ref); 310ec0142313a470edecf52b4f034433404b7264358jeffhao Class::Status status; 311ec0142313a470edecf52b4f034433404b7264358jeffhao if (compiled_class != NULL) { 312ec0142313a470edecf52b4f034433404b7264358jeffhao status = compiled_class->GetStatus(); 313ec0142313a470edecf52b4f034433404b7264358jeffhao } else if (verifier::MethodVerifier::IsClassRejected(class_ref)) { 314ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusError; 315ec0142313a470edecf52b4f034433404b7264358jeffhao } else { 316ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusNotReady; 317ec0142313a470edecf52b4f034433404b7264358jeffhao } 318971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(gc_map_size != 0 || is_native || status < Class::kStatusVerified) 319971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " << (status < Class::kStatusVerified) << " " << status << " " << PrettyMethod(method_idx, *dex_file); 320c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers#endif 321c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers 322971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 323971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = gc_map_offsets_.find(&gc_map); 324971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end()) { 325971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = gc_map_iter->second; 326971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 327971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.Put(&gc_map, gc_map_offset); 328971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += gc_map_size; 329971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&gc_map[0], gc_map_size); 330e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 3313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx)); 33408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(type == kStatic, 33508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers shorty); 3363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 337971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 338971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 339971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 340971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 341971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 342971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_invoke_stub->CodeDelta(); 343971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset; 344971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 345971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 346971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); 347971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 348971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = stub_iter->second; 34955d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 350971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&invoke_stub, invoke_stub_offset); 351971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code 352971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += invoke_stub_size; 353971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); 35455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 3553320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3577a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 35899bc2176824556730c948f17cbdb7993b17fcb6eLogan Chien if (type != kStatic) { 3597a2a23a44d27f769718e28327af671f4e486c49aLogan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 3607a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub != NULL) { 361971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 362971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 363971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 364971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 365971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 366971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_proxy_stub->CodeDelta(); 367971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = offset + sizeof(proxy_stub_size) + thumb_offset; 368971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 369971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 370971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&proxy_stub); 371971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 372971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = stub_iter->second; 373971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 374971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&proxy_stub, proxy_stub_offset); 375971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(proxy_stub_size); // proxy stub size is prepended before code 376971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += proxy_stub_size; 377971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&proxy_stub[0], proxy_stub_size); 378971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 3797a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3807a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3817a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#endif 3827a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 383389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index] 3843320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom = OatMethodOffsets(code_offset, 3853320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes, 3863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask, 3873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask, 3883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset, 3893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset, 390e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom gc_map_offset, 391ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien invoke_stub_offset 392ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#if defined(ART_USE_LLVM_COMPILER) 393971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien , proxy_stub_offset 394ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#endif 395ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien ); 3963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiler_->IsImage()) { 3980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DexCache* dex_cache = linker->FindDexCache(*dex_file); 40000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Unchecked as we hold mutator_lock_ on entry. 40100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 40266f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, 403ff2d2c555a9055452caa707fd5194dbf1a5696c8Brian Carlstrom NULL, NULL, type); 4040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(method != NULL); 4050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFrameSizeInBytes(frame_size_in_bytes); 4060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetCoreSpillMask(core_spill_mask); 4070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFpSpillMask(fp_spill_mask); 4080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatMappingTableOffset(mapping_table_offset); 4091984651929744dd603fd082e23eacd877b9bc177Ian Rogers // Don't overwrite static method trampoline 4101984651929744dd603fd082e23eacd877b9bc177Ian Rogers if (!method->IsStatic() || method->IsConstructor() || 4111984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->GetDeclaringClass()->IsInitialized()) { 4121984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetOatCodeOffset(code_offset); 4131984651929744dd603fd082e23eacd877b9bc177Ian Rogers } else { 4141984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetCode(Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()); 4151984651929744dd603fd082e23eacd877b9bc177Ian Rogers } 4160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatVmapTableOffset(vmap_table_offset); 4170c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers method->SetOatNativeGcMapOffset(gc_map_offset); 4180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatInvokeStubOffset(invoke_stub_offset); 4190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4208b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 421e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 422e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 423e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 4243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#define DCHECK_CODE_OFFSET() \ 42549a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom DCHECK_EQ(static_cast<off_t>(code_offset), out.Seek(0, kSeekCurrent)) 4263320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 427cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::Write(OutputStream& out) { 428cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(oat_header_, sizeof(*oat_header_))) { 429cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat header to " << out.GetLocation(); 430e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 431e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 432e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 433cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(image_file_location_.data(), image_file_location_.size())) { 434cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat header image file location to " << out.GetLocation(); 43581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom return false; 43681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom } 43781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 438cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!WriteTables(out)) { 439cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom LOG(ERROR) << "Failed to write oat tables to " << out.GetLocation(); 440e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 441e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 442e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 443cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom size_t code_offset = WriteCode(out); 444e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 445cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom LOG(ERROR) << "Failed to write oat code to " << out.GetLocation(); 446e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 447e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 448e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 449cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeDexFiles(out, code_offset); 450e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 451cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom LOG(ERROR) << "Failed to write oat code for dex files to " << out.GetLocation(); 452e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 453e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 454e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 455e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 456e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 457e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 458cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::WriteTables(OutputStream& out) { 459e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 460cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!oat_dex_files_[i]->Write(out)) { 461cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat dex information to " << out.GetLocation(); 462e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 463e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 464e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 46589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 46689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom uint32_t expected_offset = oat_dex_files_[i]->dex_file_offset_; 46749a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t actual_offset = out.Seek(expected_offset, kSeekSet); 46889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (static_cast<uint32_t>(actual_offset) != expected_offset) { 46989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 47089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to seek to dex file section. Actual: " << actual_offset 47189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom << " Expected: " << expected_offset << " File: " << dex_file->GetLocation(); 47289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 47389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 47489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 475cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file->GetHeader(), dex_file->GetHeader().file_size_)) { 476cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file " << dex_file->GetLocation() << " to " << out.GetLocation(); 47789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 47889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 47989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 480389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 481cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!oat_classes_[i]->Write(out)) { 482cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat methods information to " << out.GetLocation(); 483e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 484e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 485e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 486e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 487e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 488e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 489cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCode(OutputStream& out) { 490e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom uint32_t code_offset = oat_header_->GetExecutableOffset(); 49149a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(executable_offset_padding_length_, kSeekCurrent); 492e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (static_cast<uint32_t>(new_offset) != code_offset) { 4933320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to oat code section. Actual: " << new_offset 494cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom << " Expected: " << code_offset << " File: " << out.GetLocation(); 495e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 496e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 498e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 499e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 500e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 501cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeDexFiles(OutputStream& out, size_t code_offset) { 5020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t oat_class_index = 0; 5036e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 504e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 505e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 506cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeDexFile(out, code_offset, oat_class_index, *dex_file); 507e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 508e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 509e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 510e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 511e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 512e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 513e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 514cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeDexFile(OutputStream& out, size_t code_offset, size_t& oat_class_index, 5150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file) { 5160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); 5170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_index++, oat_class_index++) { 518e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 519cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeClassDef(out, code_offset, oat_class_index, dex_file, class_def); 520e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 521e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 522e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 523e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 524e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 525e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 526e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid OatWriter::ReportWriteFailure(const char* what, uint32_t method_idx, 528cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom const DexFile& dex_file, OutputStream& out) const { 5290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers PLOG(ERROR) << "Failed to write " << what << " for " << PrettyMethod(method_idx, dex_file) 530cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom << " to " << out.GetLocation(); 531234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes} 532234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 533cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeClassDef(OutputStream& out, 5340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t code_offset, size_t oat_class_index, 535e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 536e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 537e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 5380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 5390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // ie. an empty class such as a marker interface 540387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return code_offset; 541387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 5420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 5430571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 5440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 5450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 5480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 5510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 5520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 5530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 554cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeMethod(out, code_offset, oat_class_index, class_def_method_index, 5550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_static, it.GetMemberIndex(), dex_file); 556e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 557e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 558e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 561e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 563cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeMethod(out, code_offset, oat_class_index, class_def_method_index, 5640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers false, it.GetMemberIndex(), dex_file); 565e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 566e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 567e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 570e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 571e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 572e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 573e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 574cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeMethod(OutputStream& out, size_t code_offset, size_t oat_class_index, 5750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, 5760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile& dex_file) { 5770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 57811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file, method_idx)); 5790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers OatMethodOffsets method_offsets = 581389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index]; 5820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_method != NULL) { // ie. not an abstract method 585971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset); 586971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 587971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 58849a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(aligned_code_delta, kSeekCurrent); 589971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 590971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset 591cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom << " Expected: " << aligned_code_offset << " File: " << out.GetLocation(); 592971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 593f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 594971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 595f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 596971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 597971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 598971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 599971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 600971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 601971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 602971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 603971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(code_size) + compiled_method->CodeDelta(); 604971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 605971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) { 606971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(code_iter->second == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 607971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 608971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 609cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&code_size, sizeof(code_size))) { 610cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("method code size", method_idx, dex_file, out); 611971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 61255d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 613971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(code_size); 614ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 615cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&code[0], code_size)) { 616cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("method code", method_idx, dex_file, out); 617971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 61855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 619971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += code_size; 620971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 621971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 622971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 623971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 624971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 625971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 626971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 627971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = 628971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.find(&mapping_table); 629971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end() && 630971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.mapping_table_offset_) { 631971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 632971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || mapping_iter->second == method_offsets.mapping_table_offset_) 633971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 634971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 635971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 636971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.mapping_table_offset_) 637971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 638cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&mapping_table[0], mapping_table_size)) { 639cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("mapping table", method_idx, dex_file, out); 640971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 641e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 642971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += mapping_table_size; 643971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 644971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 645971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 646971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 647971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 648971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 649971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 650971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = 651971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.find(&vmap_table); 652971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end() && 653971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.vmap_table_offset_) { 654971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 655971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || vmap_iter->second == method_offsets.vmap_table_offset_) 656971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 657971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 658971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 659971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.vmap_table_offset_) 660971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 661cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&vmap_table[0], vmap_table_size)) { 662cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("vmap table", method_idx, dex_file, out); 663971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 664971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 665971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += vmap_table_size; 666e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 667971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 668971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 6690c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const std::vector<uint8_t>& gc_map = compiled_method->GetNativeGcMap(); 670971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 671971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 672971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 673971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = 674971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.find(&gc_map); 675971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end() && 676971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.gc_map_offset_) { 677971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 678971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || gc_map_iter->second == method_offsets.gc_map_offset_) 679971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 680971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 681971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 682971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.gc_map_offset_) 683971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 684cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&gc_map[0], gc_map_size)) { 685cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("GC map", method_idx, dex_file, out); 686971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 687971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 688971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += gc_map_size; 689971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 690971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 691e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 6920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 6930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 6943320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 695971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 696971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiler_->GetInstructionSet()); 697971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 698971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 69949a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(aligned_code_delta, kSeekCurrent); 700971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 701971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset 702971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset; 703971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 704971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 705971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 706971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 707971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 708971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 709971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 710971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 711971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 712971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 713971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 714971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta(); 715971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 716971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&invoke_stub); 717971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.invoke_stub_offset_) { 718971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 719971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 720971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 721cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) { 722cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("invoke stub code size", method_idx, dex_file, out); 723971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 724971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 725971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(invoke_stub_size); 726971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 727cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&invoke_stub[0], invoke_stub_size)) { 728cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("invoke stub code", method_idx, dex_file, out); 729971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 730971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 731971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += invoke_stub_size; 732971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 733971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 734971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 735971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 736971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#if defined(ART_USE_LLVM_COMPILER) 73799bc2176824556730c948f17cbdb7993b17fcb6eLogan Chien if (!is_static) { 738971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 739971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (compiled_proxy_stub != NULL) { 740ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 741ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien compiler_->GetInstructionSet()); 742ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 743971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(aligned_code_delta < 48u); 744ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (aligned_code_delta != 0) { 74549a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(aligned_code_delta, kSeekCurrent); 746ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 747971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align proxy stub code. Actual: " << new_offset 748ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien << " Expected: " << aligned_code_offset; 749ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 750ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 751ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien code_offset += aligned_code_delta; 752ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 7533320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 754ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 755971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 756971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 757971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 758ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 759971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 760971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(proxy_stub_size) + compiled_proxy_stub->CodeDelta(); 761a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 762971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&proxy_stub); 763971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.proxy_stub_offset_) { 764971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 765ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } else { 766971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 767cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&proxy_stub_size, sizeof(proxy_stub_size))) { 768cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("proxy stub code size", method_idx, dex_file, out); 769ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 770ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 771971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(proxy_stub_size); 772ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 773cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&proxy_stub[0], proxy_stub_size)) { 774cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("proxy stub code", method_idx, dex_file, out); 775ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 776ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 777971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += proxy_stub_size; 778971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 779f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 780f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 7813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 7823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 783971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#endif 7848b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 785e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 786e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 787e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 788e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatDexFile::OatDexFile(const DexFile& dex_file) { 789955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string& location(dex_file.GetLocation()); 790e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_size_ = location.size(); 791e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_data_ = reinterpret_cast<const uint8_t*>(location.data()); 7925b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom dex_file_location_checksum_ = dex_file.GetLocationChecksum(); 79389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom dex_file_offset_ = 0; 7946e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom methods_offsets_.resize(dex_file.NumClassDefs()); 795e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 796e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 797e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatDexFile::SizeOf() const { 798e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return sizeof(dex_file_location_size_) 799e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + dex_file_location_size_ 8005b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom + sizeof(dex_file_location_checksum_) 80189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom + sizeof(dex_file_offset_) 8026e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom + (sizeof(methods_offsets_[0]) * methods_offsets_.size()); 803e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 804e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 805e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatDexFile::UpdateChecksum(OatHeader& oat_header) const { 806e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); 807e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(dex_file_location_data_, dex_file_location_size_); 8085b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_)); 80989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_header.UpdateChecksum(&dex_file_offset_, sizeof(dex_file_offset_)); 8106e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_header.UpdateChecksum(&methods_offsets_[0], 8116e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size()); 812e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 813e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 814cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::OatDexFile::Write(OutputStream& out) const { 815cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { 816cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file location length to " << out.GetLocation(); 817e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 818e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 819cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(dex_file_location_data_, dex_file_location_size_)) { 820cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file location data to " << out.GetLocation(); 821e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 822e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 823cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) { 824cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file location checksum to " << out.GetLocation(); 825e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 826e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 827cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) { 828cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file offset to " << out.GetLocation(); 82989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 83089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 831cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&methods_offsets_[0], 832cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size())) { 833cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write methods offsets to " << out.GetLocation(); 834e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 835e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 836e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 837e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 838e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 8390755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromOatWriter::OatClass::OatClass(Class::Status status, uint32_t methods_count) { 8400755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom status_ = status; 841e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom method_offsets_.resize(methods_count); 842e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 843e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 844389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::OatClass::SizeOf() const { 8450755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return sizeof(status_) 8460755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom + (sizeof(method_offsets_[0]) * method_offsets_.size()); 847e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 848e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 849389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromvoid OatWriter::OatClass::UpdateChecksum(OatHeader& oat_header) const { 8500755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&status_, sizeof(status_)); 8510755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&method_offsets_[0], 8520755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size()); 853e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 854e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 855cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::OatClass::Write(OutputStream& out) const { 856cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&status_, sizeof(status_))) { 857cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write class status to " << out.GetLocation(); 8580755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return false; 8590755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 860cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&method_offsets_[0], 861cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size())) { 862cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write method offsets to " << out.GetLocation(); 863e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 864e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 865e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 866e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 867e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 868e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 869