oat_writer.cc revision 265091e581c9f643b37e7966890911f09e223269
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" 242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h" 252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/array.h" 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 27e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "os.h" 28cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom#include "output_stream.h" 29a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 3000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 317469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h" 32ec0142313a470edecf52b4f034433404b7264358jeffhao#include "verifier/method_verifier.h" 33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 34e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 35e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 36cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::Create(OutputStream& output_stream, 3710037c866b04550fc5461058c398c2e3e509381ajeffhao const std::vector<const DexFile*>& dex_files, 3828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_checksum, 3928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_begin, 4081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 411212a022fa5f8ef9585d765b1809521812af882cIan Rogers const CompilerDriver& driver) { 4281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom OatWriter oat_writer(dex_files, 4328db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum, 4428db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin, 4581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location, 461212a022fa5f8ef9585d765b1809521812af882cIan Rogers &driver); 47cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom return oat_writer.Write(output_stream); 48e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 49e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 503320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, 5128db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_checksum, 5228db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_begin, 5381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 541212a022fa5f8ef9585d765b1809521812af882cIan Rogers const CompilerDriver* compiler) 551212a022fa5f8ef9585d765b1809521812af882cIan Rogers : compiler_driver_(compiler) { 5628db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_ = image_file_location_oat_checksum; 5728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin_ = image_file_location_oat_begin; 5881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_ = image_file_location; 59e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_files_ = &dex_files; 600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers oat_header_ = NULL; 610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers executable_offset_padding_length_ = 0; 62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 6381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom size_t offset = InitOatHeader(); 64e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatDexFiles(offset); 6589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = InitDexFiles(offset); 66389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset = InitOatClasses(offset); 67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCode(offset); 68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFiles(offset); 69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 70e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); 71e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 72e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersOatWriter::~OatWriter() { 740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers delete oat_header_; 750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_dex_files_); 76389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom STLDeleteElements(&oat_classes_); 770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 7981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromsize_t OatWriter::InitOatHeader() { 80e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatHeader 811212a022fa5f8ef9585d765b1809521812af882cIan Rogers oat_header_ = new OatHeader(compiler_driver_->GetInstructionSet(), 8281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom dex_files_, 8328db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_, 8428db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin_, 8581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_); 86e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t offset = sizeof(*oat_header_); 8781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom offset += image_file_location_.size(); 88e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 89e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatDexFiles(size_t offset) { 92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatDexFiles 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 96265091e581c9f643b37e7966890911f09e223269Brian Carlstrom OatDexFile* oat_dex_file = new OatDexFile(offset, *dex_file); 97e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_.push_back(oat_dex_file); 98e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_dex_file->SizeOf(); 99e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 100e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 101e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 102e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 10389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstromsize_t OatWriter::InitDexFiles(size_t offset) { 10489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // calculate the offsets within OatDexFiles to the DexFiles 10589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 10689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // dex files are required to be 4 byte aligned 10789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = RoundUp(offset, 4); 10889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 10989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // set offset in OatDexFile to DexFile 11089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_dex_files_[i]->dex_file_offset_ = offset; 11189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 11289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 11389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset += dex_file->GetHeader().file_size_; 11489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 11589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return offset; 11689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom} 11789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 118389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::InitOatClasses(size_t offset) { 119389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // create the OatClasses 120389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // calculate the offsets within OatDexFiles to OatClasses 121e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 123e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t class_def_index = 0; 124e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file->NumClassDefs(); 125c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers class_def_index++) { 1266e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->methods_offsets_[class_def_index] = offset; 127e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 128e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file->GetClassData(class_def); 1290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t num_methods = 0; 1300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data != NULL) { // ie not an empty class, such as a marker interface 1310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(*dex_file, class_data); 1320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_direct_methods = it.NumDirectMethods(); 1330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_virtual_methods = it.NumVirtualMethods(); 1340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers num_methods = num_direct_methods + num_virtual_methods; 1350571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1360755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 1371212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompilerDriver::ClassReference class_ref = CompilerDriver::ClassReference(dex_file, class_def_index); 1381212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompiledClass* compiled_class = compiler_driver_->GetCompiledClass(class_ref); 1392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class::Status status; 140ec0142313a470edecf52b4f034433404b7264358jeffhao if (compiled_class != NULL) { 141ec0142313a470edecf52b4f034433404b7264358jeffhao status = compiled_class->GetStatus(); 142ec0142313a470edecf52b4f034433404b7264358jeffhao } else if (verifier::MethodVerifier::IsClassRejected(class_ref)) { 1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers status = mirror::Class::kStatusError; 144ec0142313a470edecf52b4f034433404b7264358jeffhao } else { 1452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers status = mirror::Class::kStatusNotReady; 146ec0142313a470edecf52b4f034433404b7264358jeffhao } 1470755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 148265091e581c9f643b37e7966890911f09e223269Brian Carlstrom OatClass* oat_class = new OatClass(offset, status, num_methods); 149389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_.push_back(oat_class); 150389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset += oat_class->SizeOf(); 151e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1526e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->UpdateChecksum(*oat_header_); 153e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 154e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 155e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 156e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 157e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCode(size_t offset) { 158e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatHeader to executable code 159e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t old_offset = offset; 160e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // required to be on a new page boundary 161e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = RoundUp(offset, kPageSize); 162e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header_->SetExecutableOffset(offset); 163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom executable_offset_padding_length_ = offset - old_offset; 164e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 165e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 166e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 167e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFiles(size_t offset) { 168e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t oat_class_index = 0; 169e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 170e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 171e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 172e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFile(offset, oat_class_index, *dex_file); 173e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 174e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 175e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 176e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 177e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFile(size_t offset, 178e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t& oat_class_index, 179e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file) { 180ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes for (size_t class_def_index = 0; 181e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file.NumClassDefs(); 182e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index++, oat_class_index++) { 183e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 184c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers offset = InitOatCodeClassDef(offset, oat_class_index, class_def_index, dex_file, class_def); 185389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->UpdateChecksum(*oat_header_); 186e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 187e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 188e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 189e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 190e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeClassDef(size_t offset, 191c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers size_t oat_class_index, size_t class_def_index, 192e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 193e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 194e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 1960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, such as a marker interface 197387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return offset; 198387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 1990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 200389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom CHECK_EQ(oat_classes_[oat_class_index]->method_offsets_.size(), 2010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.NumDirectMethods() + it.NumVirtualMethods()); 2020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 2030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 2040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 205e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 2070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 208e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 2100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 2110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 212c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 21308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 21408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 21508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 220c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 22108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 22208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 22308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 228e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 229e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 230e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2311bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughessize_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, 2321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t __attribute__((unused)) class_def_index, 2331bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t class_def_method_index, 2341bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes bool __attribute__((unused)) is_native, 235265091e581c9f643b37e7966890911f09e223269Brian Carlstrom InvokeType invoke_type, 2361bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes uint32_t method_idx, const DexFile* dex_file) { 2373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledMethod if available 2383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t code_offset = 0; 2393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t frame_size_in_bytes = kStackAlignment; 2403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t core_spill_mask = 0; 2413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t fp_spill_mask = 0; 2423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t mapping_table_offset = 0; 2433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t vmap_table_offset = 0; 244e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint32_t gc_map_offset = 0; 2453320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledInvokeStub if available 2463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t invoke_stub_offset = 0; 247c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#if defined(ART_USE_PORTABLE_COMPILER) 248971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_offset = 0; 249fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#endif 2503320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 251265091e581c9f643b37e7966890911f09e223269Brian Carlstrom OatClass* oat_class = oat_classes_[oat_class_index]; 252265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 253265091e581c9f643b37e7966890911f09e223269Brian Carlstrom size_t oat_method_offsets_offset = 254265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_class->GetOatMethodOffsetsOffsetFromOatHeader(class_def_method_index); 255265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif 256265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 2570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledMethod* compiled_method = 2581212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(dex_file, method_idx)); 2593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 260265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 261265091e581c9f643b37e7966890911f09e223269Brian Carlstrom compiled_method->AddOatdataOffsetToCompliledCodeOffset( 262265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_method_offsets_offset + OFFSETOF_MEMBER(OatMethodOffsets, code_offset_)); 263265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#else 264265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<uint8_t>& code = compiled_method->GetCode(); 265971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = compiled_method->AlignCode(offset); 266971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 267971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 268971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 269971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_method->CodeDelta(); 270971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = offset + sizeof(code_size) + thumb_offset; 271971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 272971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 273971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 274971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end()) { 275971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = code_iter->second; 27655d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 277971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&code, code_offset); 278971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(code_size); // code size is prepended before code 279971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += code_size; 280971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&code[0], code_size); 281971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 282265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif 283971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); 284971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien core_spill_mask = compiled_method->GetCoreSpillMask(); 285971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien fp_spill_mask = compiled_method->GetFpSpillMask(); 286971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 287971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 288971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 289971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = (mapping_table_size == 0) ? 0 : offset; 290971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 291971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 292971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table); 293971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end()) { 294971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = mapping_iter->second; 295971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 296971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.Put(&mapping_table, mapping_table_offset); 297971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += mapping_table_size; 298971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size); 299971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 300ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 301971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 302971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 303971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = (vmap_table_size == 0) ? 0 : offset; 304e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 305971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 306971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table); 307971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end()) { 308971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = vmap_iter->second; 309971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 310971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.Put(&vmap_table, vmap_table_offset); 311971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += vmap_table_size; 312971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size); 313971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 314e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 3150c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const std::vector<uint8_t>& gc_map = compiled_method->GetNativeGcMap(); 316971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 317971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = (gc_map_size == 0) ? 0 : offset; 318971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 319ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa#if !defined(NDEBUG) 320971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // We expect GC maps except when the class hasn't been verified or the method is native 3211212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompilerDriver::ClassReference class_ref = CompilerDriver::ClassReference(dex_file, class_def_index); 3221212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompiledClass* compiled_class = compiler_driver_->GetCompiledClass(class_ref); 3232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class::Status status; 324ec0142313a470edecf52b4f034433404b7264358jeffhao if (compiled_class != NULL) { 325ec0142313a470edecf52b4f034433404b7264358jeffhao status = compiled_class->GetStatus(); 326ec0142313a470edecf52b4f034433404b7264358jeffhao } else if (verifier::MethodVerifier::IsClassRejected(class_ref)) { 3272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers status = mirror::Class::kStatusError; 328ec0142313a470edecf52b4f034433404b7264358jeffhao } else { 3292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers status = mirror::Class::kStatusNotReady; 330ec0142313a470edecf52b4f034433404b7264358jeffhao } 3312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(gc_map_size != 0 || is_native || status < mirror::Class::kStatusVerified) 3322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " 3332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << (status < mirror::Class::kStatusVerified) << " " << status << " " 3342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << PrettyMethod(method_idx, *dex_file); 335c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers#endif 336c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers 337971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 338971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = gc_map_offsets_.find(&gc_map); 339971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end()) { 340971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = gc_map_iter->second; 341971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 342971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.Put(&gc_map, gc_map_offset); 343971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += gc_map_size; 344971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&gc_map[0], gc_map_size); 345e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 3463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3473320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx)); 349265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CompiledInvokeStub* compiled_invoke_stub = compiler_driver_->FindInvokeStub(invoke_type == kStatic, 350265091e581c9f643b37e7966890911f09e223269Brian Carlstrom shorty); 3513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 352265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 353265091e581c9f643b37e7966890911f09e223269Brian Carlstrom compiled_invoke_stub->AddOatdataOffsetToCompliledCodeOffset( 354265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_method_offsets_offset + OFFSETOF_MEMBER(OatMethodOffsets, invoke_stub_offset_)); 355265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#else 356265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 3571212a022fa5f8ef9585d765b1809521812af882cIan Rogers offset = CompiledMethod::AlignCode(offset, compiler_driver_->GetInstructionSet()); 358971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 359971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 360971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 361971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_invoke_stub->CodeDelta(); 362971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset; 363971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 364971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 365971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); 366971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 367971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = stub_iter->second; 36855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 369971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&invoke_stub, invoke_stub_offset); 370971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code 371971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += invoke_stub_size; 372971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); 37355d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 374265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif 3753320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 377c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#if defined(ART_USE_PORTABLE_COMPILER) 378265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (invoke_type != kStatic) { 379265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CompiledInvokeStub* compiled_proxy_stub = compiler_driver_->FindProxyStub(shorty); 3807a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub != NULL) { 381265091e581c9f643b37e7966890911f09e223269Brian Carlstrom compiled_proxy_stub->AddOatdataOffsetToCompliledCodeOffset( 382265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_method_offsets_offset + OFFSETOF_MEMBER(OatMethodOffsets, proxy_stub_offset_)); 3837a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3847a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3857a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#endif 3867a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 387265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oat_class->method_offsets_[class_def_method_index] 3883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom = OatMethodOffsets(code_offset, 3893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes, 3903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask, 3913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask, 3923320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset, 3933320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset, 394e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom gc_map_offset, 395ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien invoke_stub_offset 396c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#if defined(ART_USE_PORTABLE_COMPILER) 397971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien , proxy_stub_offset 398ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#endif 399ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien ); 4003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4011212a022fa5f8ef9585d765b1809521812af882cIan Rogers if (compiler_driver_->IsImage()) { 4020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassLinker* linker = Runtime::Current()->GetClassLinker(); 4032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = linker->FindDexCache(*dex_file); 40400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Unchecked as we hold mutator_lock_ on entry. 40500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 4062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, 407265091e581c9f643b37e7966890911f09e223269Brian Carlstrom NULL, NULL, invoke_type); 4080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(method != NULL); 4090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFrameSizeInBytes(frame_size_in_bytes); 4100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetCoreSpillMask(core_spill_mask); 4110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFpSpillMask(fp_spill_mask); 4120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatMappingTableOffset(mapping_table_offset); 4131984651929744dd603fd082e23eacd877b9bc177Ian Rogers // Don't overwrite static method trampoline 4141984651929744dd603fd082e23eacd877b9bc177Ian Rogers if (!method->IsStatic() || method->IsConstructor() || 4151984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->GetDeclaringClass()->IsInitialized()) { 4161984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetOatCodeOffset(code_offset); 4171984651929744dd603fd082e23eacd877b9bc177Ian Rogers } else { 4181984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetCode(Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()); 4191984651929744dd603fd082e23eacd877b9bc177Ian Rogers } 4200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatVmapTableOffset(vmap_table_offset); 4210c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers method->SetOatNativeGcMapOffset(gc_map_offset); 4220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatInvokeStubOffset(invoke_stub_offset); 4230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4248b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 425e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 426e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 427e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 428265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define DCHECK_OFFSET() \ 429265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_EQ(static_cast<off_t>(offset), out.Seek(0, kSeekCurrent)) 430265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 431265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#define DCHECK_OFFSET_() \ 432265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_EQ(static_cast<off_t>(offset_), out.Seek(0, kSeekCurrent)) 4333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 434cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::Write(OutputStream& out) { 435cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(oat_header_, sizeof(*oat_header_))) { 436cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat header to " << out.GetLocation(); 437e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 438e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 439e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 440cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(image_file_location_.data(), image_file_location_.size())) { 441cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat header image file location to " << out.GetLocation(); 44281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom return false; 44381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom } 44481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 445cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!WriteTables(out)) { 446cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom LOG(ERROR) << "Failed to write oat tables to " << out.GetLocation(); 447e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 448e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 449e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 450cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom size_t code_offset = WriteCode(out); 451e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 452cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom LOG(ERROR) << "Failed to write oat code to " << out.GetLocation(); 453e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 454e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 455e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 456cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeDexFiles(out, code_offset); 457e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 458cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom LOG(ERROR) << "Failed to write oat code for dex files to " << out.GetLocation(); 459e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 460e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 461e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 462e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 463e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 464e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 465cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::WriteTables(OutputStream& out) { 466e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 467cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!oat_dex_files_[i]->Write(out)) { 468cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat dex information to " << out.GetLocation(); 469e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 470e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 471e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 47289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 47389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom uint32_t expected_offset = oat_dex_files_[i]->dex_file_offset_; 47449a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t actual_offset = out.Seek(expected_offset, kSeekSet); 47589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (static_cast<uint32_t>(actual_offset) != expected_offset) { 47689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 47789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to seek to dex file section. Actual: " << actual_offset 47889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom << " Expected: " << expected_offset << " File: " << dex_file->GetLocation(); 47989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 48089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 48189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 482cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file->GetHeader(), dex_file->GetHeader().file_size_)) { 483cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file " << dex_file->GetLocation() << " to " << out.GetLocation(); 48489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 48589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 48689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 487389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 488cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!oat_classes_[i]->Write(out)) { 489cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write oat methods information to " << out.GetLocation(); 490e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 491e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 492e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 493e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 494e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 495e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 496cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCode(OutputStream& out) { 497265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t offset = oat_header_->GetExecutableOffset(); 49849a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(executable_offset_padding_length_, kSeekCurrent); 499265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (static_cast<uint32_t>(new_offset) != offset) { 5003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to oat code section. Actual: " << new_offset 501265091e581c9f643b37e7966890911f09e223269Brian Carlstrom << " Expected: " << offset << " File: " << out.GetLocation(); 502e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 503e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 504265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 505265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return offset; 506e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 507e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 508cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeDexFiles(OutputStream& out, size_t code_offset) { 5090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t oat_class_index = 0; 5106e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 511e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 512e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 513cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeDexFile(out, code_offset, oat_class_index, *dex_file); 514e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 515e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 516e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 517e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 518e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 519e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 520e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 521cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeDexFile(OutputStream& out, size_t code_offset, size_t& oat_class_index, 5220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file) { 5230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); 5240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_index++, oat_class_index++) { 525e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 526cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeClassDef(out, code_offset, oat_class_index, dex_file, class_def); 527e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 528e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 529e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 530e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 531e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 532e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 533e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid OatWriter::ReportWriteFailure(const char* what, uint32_t method_idx, 535cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom const DexFile& dex_file, OutputStream& out) const { 5360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers PLOG(ERROR) << "Failed to write " << what << " for " << PrettyMethod(method_idx, dex_file) 537cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom << " to " << out.GetLocation(); 538234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes} 539234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 540cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstromsize_t OatWriter::WriteCodeClassDef(OutputStream& out, 5410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t code_offset, size_t oat_class_index, 542e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 543e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 544e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 5450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 5460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // ie. an empty class such as a marker interface 547387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return code_offset; 548387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 5490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 5500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 5510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 5520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 5550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 5580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 5590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 5600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 561cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeMethod(out, code_offset, oat_class_index, class_def_method_index, 5620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_static, it.GetMemberIndex(), dex_file); 563e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 564e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 565e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 568e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 570cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom code_offset = WriteCodeMethod(out, code_offset, oat_class_index, class_def_method_index, 5710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers false, it.GetMemberIndex(), dex_file); 572e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 573e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 574e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 577e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 578e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 579e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 580e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 581265091e581c9f643b37e7966890911f09e223269Brian Carlstromsize_t OatWriter::WriteCodeMethod(OutputStream& out, size_t offset, size_t oat_class_index, 5820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, 5830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile& dex_file) { 5840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 5851212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(&dex_file, method_idx)); 5860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers OatMethodOffsets method_offsets = 588389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index]; 5890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_method != NULL) { // ie. not an abstract method 592265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if !defined(ART_USE_PORTABLE_COMPILER) 593265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t aligned_offset = compiled_method->AlignCode(offset); 594265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t aligned_code_delta = aligned_offset - offset; 595971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 59649a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(aligned_code_delta, kSeekCurrent); 597265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (static_cast<uint32_t>(new_offset) != aligned_offset) { 598971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset 599265091e581c9f643b37e7966890911f09e223269Brian Carlstrom << " Expected: " << aligned_offset << " File: " << out.GetLocation(); 600971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 601f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 602265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += aligned_code_delta; 603265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 604971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 605265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_ALIGNED(offset, kArmAlignment); 606971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 607971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 608971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 609971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 610971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 611265091e581c9f643b37e7966890911f09e223269Brian Carlstrom size_t code_offset = offset + sizeof(code_size) + compiled_method->CodeDelta(); 612971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 613265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (code_iter != code_offsets_.end() && code_offset != method_offsets.code_offset_) { 614265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK(code_iter->second == method_offsets.code_offset_) 615265091e581c9f643b37e7966890911f09e223269Brian Carlstrom << PrettyMethod(method_idx, dex_file); 616971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 617265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK(code_offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 618cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&code_size, sizeof(code_size))) { 619cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("method code size", method_idx, dex_file, out); 620971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 62155d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 622265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += sizeof(code_size); 623265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 624cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&code[0], code_size)) { 625cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("method code", method_idx, dex_file, out); 626971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 62755d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 628265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += code_size; 629971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 630265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 631265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif 632971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 633971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 634971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 635971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 636971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 637971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = 638971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.find(&mapping_table); 639971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end() && 640265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset != method_offsets.mapping_table_offset_) { 641971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 642971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || mapping_iter->second == method_offsets.mapping_table_offset_) 643971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 644971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 645971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 646265091e581c9f643b37e7966890911f09e223269Brian Carlstrom || offset == method_offsets.mapping_table_offset_) 647971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 648cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&mapping_table[0], mapping_table_size)) { 649cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("mapping table", method_idx, dex_file, out); 650971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 651e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 652265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += mapping_table_size; 653971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 654265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 655971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 656971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 657971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 658971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 659971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 660971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = 661971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.find(&vmap_table); 662971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end() && 663265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset != method_offsets.vmap_table_offset_) { 664971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 665971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || vmap_iter->second == method_offsets.vmap_table_offset_) 666971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 667971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 668971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 669265091e581c9f643b37e7966890911f09e223269Brian Carlstrom || offset == method_offsets.vmap_table_offset_) 670971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 671cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&vmap_table[0], vmap_table_size)) { 672cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("vmap table", method_idx, dex_file, out); 673971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 674971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 675265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += vmap_table_size; 676e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 677265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 678971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 6790c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const std::vector<uint8_t>& gc_map = compiled_method->GetNativeGcMap(); 680971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 681971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 682971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 683971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = 684971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.find(&gc_map); 685971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end() && 686265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset != method_offsets.gc_map_offset_) { 687971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 688971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || gc_map_iter->second == method_offsets.gc_map_offset_) 689971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 690971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 691971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 692265091e581c9f643b37e7966890911f09e223269Brian Carlstrom || offset == method_offsets.gc_map_offset_) 693971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 694cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&gc_map[0], gc_map_size)) { 695cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("GC map", method_idx, dex_file, out); 696971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 697971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 698265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += gc_map_size; 699971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 700265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 701e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 702265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 703265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if !defined(ART_USE_PORTABLE_COMPILER) 7040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 7051212a022fa5f8ef9585d765b1809521812af882cIan Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_driver_->FindInvokeStub(is_static, shorty); 7063320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 707265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t aligned_offset = CompiledMethod::AlignCode(offset, 708265091e581c9f643b37e7966890911f09e223269Brian Carlstrom compiler_driver_->GetInstructionSet()); 709265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t aligned_code_delta = aligned_offset - offset; 710971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 71149a0f158ed11974fa2cc12014c9f55a31dabd8dfBrian Carlstrom off_t new_offset = out.Seek(aligned_code_delta, kSeekCurrent); 712265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (static_cast<uint32_t>(new_offset) != aligned_offset) { 713971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset 714265091e581c9f643b37e7966890911f09e223269Brian Carlstrom << " Expected: " << aligned_offset; 715971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 716971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 717265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += aligned_code_delta; 718265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 719971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 720265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_ALIGNED(offset, kArmAlignment); 721971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 722971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 723971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 724971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 725971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 726265091e581c9f643b37e7966890911f09e223269Brian Carlstrom size_t invoke_stub_offset = offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta(); 727971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 728971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&invoke_stub); 729265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (stub_iter != code_offsets_.end() 730265091e581c9f643b37e7966890911f09e223269Brian Carlstrom && invoke_stub_offset != method_offsets.invoke_stub_offset_) { 731265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) 732265091e581c9f643b37e7966890911f09e223269Brian Carlstrom << PrettyMethod(method_idx, dex_file); 733971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 734265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK(invoke_stub_offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 735cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) { 736cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("invoke stub code size", method_idx, dex_file, out); 737971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 738971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 739265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += sizeof(invoke_stub_size); 740265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 741cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&invoke_stub[0], invoke_stub_size)) { 742cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom ReportWriteFailure("invoke stub code", method_idx, dex_file, out); 743971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 744971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 745265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset += invoke_stub_size; 746265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET(); 7473320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 7483320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 749971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#endif 7508b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 751265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return offset; 752e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 753e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 754265091e581c9f643b37e7966890911f09e223269Brian CarlstromOatWriter::OatDexFile::OatDexFile(size_t offset, const DexFile& dex_file) { 755265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset_ = offset; 756955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string& location(dex_file.GetLocation()); 757e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_size_ = location.size(); 758e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_data_ = reinterpret_cast<const uint8_t*>(location.data()); 7595b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom dex_file_location_checksum_ = dex_file.GetLocationChecksum(); 76089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom dex_file_offset_ = 0; 7616e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom methods_offsets_.resize(dex_file.NumClassDefs()); 762e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 763e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 764e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatDexFile::SizeOf() const { 765e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return sizeof(dex_file_location_size_) 766e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + dex_file_location_size_ 7675b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom + sizeof(dex_file_location_checksum_) 76889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom + sizeof(dex_file_offset_) 7696e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom + (sizeof(methods_offsets_[0]) * methods_offsets_.size()); 770e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 771e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 772e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatDexFile::UpdateChecksum(OatHeader& oat_header) const { 773e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); 774e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(dex_file_location_data_, dex_file_location_size_); 7755b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_)); 77689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_header.UpdateChecksum(&dex_file_offset_, sizeof(dex_file_offset_)); 7776e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_header.UpdateChecksum(&methods_offsets_[0], 7786e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size()); 779e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 780e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 781cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::OatDexFile::Write(OutputStream& out) const { 782265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET_(); 783cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { 784cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file location length to " << out.GetLocation(); 785e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 786e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 787cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(dex_file_location_data_, dex_file_location_size_)) { 788cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file location data to " << out.GetLocation(); 789e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 790e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 791cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) { 792cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file location checksum to " << out.GetLocation(); 793e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 794e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 795cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) { 796cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write dex file offset to " << out.GetLocation(); 79789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 79889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 799cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&methods_offsets_[0], 800cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size())) { 801cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write methods offsets to " << out.GetLocation(); 802e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 803e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 804e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 805e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 806e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 807265091e581c9f643b37e7966890911f09e223269Brian CarlstromOatWriter::OatClass::OatClass(size_t offset, mirror::Class::Status status, uint32_t methods_count) { 808265091e581c9f643b37e7966890911f09e223269Brian Carlstrom offset_ = offset; 8090755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom status_ = status; 810e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom method_offsets_.resize(methods_count); 811e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 812e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 813265091e581c9f643b37e7966890911f09e223269Brian Carlstromsize_t OatWriter::OatClass::GetOatMethodOffsetsOffsetFromOatHeader( 814265091e581c9f643b37e7966890911f09e223269Brian Carlstrom size_t class_def_method_index_) const { 815265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return offset_ + GetOatMethodOffsetsOffsetFromOatClass(class_def_method_index_); 816265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 817265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 818265091e581c9f643b37e7966890911f09e223269Brian Carlstromsize_t OatWriter::OatClass::GetOatMethodOffsetsOffsetFromOatClass( 819265091e581c9f643b37e7966890911f09e223269Brian Carlstrom size_t class_def_method_index_) const { 8200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return sizeof(status_) 821265091e581c9f643b37e7966890911f09e223269Brian Carlstrom + (sizeof(method_offsets_[0]) * class_def_method_index_); 822265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 823265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 824265091e581c9f643b37e7966890911f09e223269Brian Carlstromsize_t OatWriter::OatClass::SizeOf() const { 825265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return GetOatMethodOffsetsOffsetFromOatClass(method_offsets_.size()); 826e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 827e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 828389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromvoid OatWriter::OatClass::UpdateChecksum(OatHeader& oat_header) const { 8290755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&status_, sizeof(status_)); 8300755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&method_offsets_[0], 8310755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size()); 832e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 833e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 834cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrombool OatWriter::OatClass::Write(OutputStream& out) const { 835265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_OFFSET_(); 836cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&status_, sizeof(status_))) { 837cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write class status to " << out.GetLocation(); 8380755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return false; 8390755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 840265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_EQ(static_cast<off_t>(GetOatMethodOffsetsOffsetFromOatHeader(0)), 841265091e581c9f643b37e7966890911f09e223269Brian Carlstrom out.Seek(0, kSeekCurrent)); 842cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom if (!out.WriteFully(&method_offsets_[0], 843cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size())) { 844cd60ac736bc7104785dc67671660d70fb434466fBrian Carlstrom PLOG(ERROR) << "Failed to write method offsets to " << out.GetLocation(); 845e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 846e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 847265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK_EQ(static_cast<off_t>(GetOatMethodOffsetsOffsetFromOatHeader(method_offsets_.size())), 848265091e581c9f643b37e7966890911f09e223269Brian Carlstrom out.Seek(0, kSeekCurrent)); 849e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 850e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 851e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 852e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 853