oat_writer.cc revision 28db0129e5d7ef642cf8845c86c0e11832817085
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 21e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "class_linker.h" 22e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "class_loader.h" 23e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "file.h" 24e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "os.h" 25a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 2600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 277469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h" 28e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "stl_util.h" 29ec0142313a470edecf52b4f034433404b7264358jeffhao#include "verifier/method_verifier.h" 30e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 31e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 32e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 33234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Create(File* file, 3400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader, 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 class_loader, 4581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom compiler); 46234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes return oat_writer.Write(file); 47e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 48e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 493320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, 5028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_checksum, 5128db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_begin, 5281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 5300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader, 543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 553320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom compiler_ = &compiler; 56e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_loader_ = class_loader; 5728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_ = image_file_location_oat_checksum; 5828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin_ = image_file_location_oat_begin; 5981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_ = image_file_location; 60e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_files_ = &dex_files; 610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers oat_header_ = NULL; 620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers executable_offset_padding_length_ = 0; 63e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 6481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom size_t offset = InitOatHeader(); 65e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatDexFiles(offset); 6689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = InitDexFiles(offset); 67389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset = InitOatClasses(offset); 68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCode(offset); 69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFiles(offset); 70e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 71e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); 72e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 73e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersOatWriter::~OatWriter() { 750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers delete oat_header_; 760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_dex_files_); 77389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom STLDeleteElements(&oat_classes_); 780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 8081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromsize_t OatWriter::InitOatHeader() { 81e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatHeader 8281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom oat_header_ = new OatHeader(compiler_->GetInstructionSet(), 8381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom dex_files_, 8428db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_, 8528db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_begin_, 8681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_); 87e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t offset = sizeof(*oat_header_); 8881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom offset += image_file_location_.size(); 89e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatDexFiles(size_t offset) { 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatDexFiles 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 96e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 97e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom OatDexFile* oat_dex_file = new OatDexFile(*dex_file); 98e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_.push_back(oat_dex_file); 99e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_dex_file->SizeOf(); 100e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 101e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 102e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 103e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 10489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstromsize_t OatWriter::InitDexFiles(size_t offset) { 10589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // calculate the offsets within OatDexFiles to the DexFiles 10689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 10789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // dex files are required to be 4 byte aligned 10889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = RoundUp(offset, 4); 10989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 11089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // set offset in OatDexFile to DexFile 11189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_dex_files_[i]->dex_file_offset_ = offset; 11289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 11389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 11489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset += dex_file->GetHeader().file_size_; 11589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 11689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return offset; 11789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom} 11889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 119389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::InitOatClasses(size_t offset) { 120389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // create the OatClasses 121389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // calculate the offsets within OatDexFiles to OatClasses 122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 123e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 124e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t class_def_index = 0; 125e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file->NumClassDefs(); 126c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers class_def_index++) { 1276e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->methods_offsets_[class_def_index] = offset; 128e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 129e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file->GetClassData(class_def); 1300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t num_methods = 0; 1310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data != NULL) { // ie not an empty class, such as a marker interface 1320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(*dex_file, class_data); 1330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_direct_methods = it.NumDirectMethods(); 1340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_virtual_methods = it.NumVirtualMethods(); 1350571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers num_methods = num_direct_methods + num_virtual_methods; 1360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1370755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 138ec0142313a470edecf52b4f034433404b7264358jeffhao Compiler::ClassReference class_ref = Compiler::ClassReference(dex_file, class_def_index); 139ec0142313a470edecf52b4f034433404b7264358jeffhao CompiledClass* compiled_class = compiler_->GetCompiledClass(class_ref); 140ec0142313a470edecf52b4f034433404b7264358jeffhao Class::Status status; 141ec0142313a470edecf52b4f034433404b7264358jeffhao if (compiled_class != NULL) { 142ec0142313a470edecf52b4f034433404b7264358jeffhao status = compiled_class->GetStatus(); 143ec0142313a470edecf52b4f034433404b7264358jeffhao } else if (verifier::MethodVerifier::IsClassRejected(class_ref)) { 144ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusError; 145ec0142313a470edecf52b4f034433404b7264358jeffhao } else { 146ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusNotReady; 147ec0142313a470edecf52b4f034433404b7264358jeffhao } 1480755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 1490755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom OatClass* oat_class = new OatClass(status, num_methods); 150389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_.push_back(oat_class); 151389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset += oat_class->SizeOf(); 152e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1536e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->UpdateChecksum(*oat_header_); 154e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 155e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 156e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 157e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 158e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCode(size_t offset) { 159e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatHeader to executable code 160e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t old_offset = offset; 161e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // required to be on a new page boundary 162e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = RoundUp(offset, kPageSize); 163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header_->SetExecutableOffset(offset); 164e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom executable_offset_padding_length_ = offset - old_offset; 165e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 166e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 167e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 168e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFiles(size_t offset) { 169e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t oat_class_index = 0; 170e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 171e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 172e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 173e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFile(offset, oat_class_index, *dex_file); 174e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 175e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 176e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 177e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 178e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFile(size_t offset, 179e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t& oat_class_index, 180e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file) { 181ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes for (size_t class_def_index = 0; 182e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file.NumClassDefs(); 183e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index++, oat_class_index++) { 184e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 185c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers offset = InitOatCodeClassDef(offset, oat_class_index, class_def_index, dex_file, class_def); 186389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->UpdateChecksum(*oat_header_); 187e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 188e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 189e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 190e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 191e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeClassDef(size_t offset, 192c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers size_t oat_class_index, size_t class_def_index, 193e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 194e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 195e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 1970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, such as a marker interface 198387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return offset; 199387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 2000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 201389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom CHECK_EQ(oat_classes_[oat_class_index]->method_offsets_.size(), 2020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.NumDirectMethods() + it.NumVirtualMethods()); 2030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 2040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 2050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 206e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 2080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 209e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 2110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 2120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 213c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 21408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 21508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 21608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 221c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 22208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 22308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 22408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 229e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 230e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 231e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughessize_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, 2331bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t __attribute__((unused)) class_def_index, 2341bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t class_def_method_index, 2351bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes bool __attribute__((unused)) is_native, 23608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType type, 2371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes uint32_t method_idx, const DexFile* dex_file) { 2383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledMethod if available 2393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t code_offset = 0; 2403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t frame_size_in_bytes = kStackAlignment; 2413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t core_spill_mask = 0; 2423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t fp_spill_mask = 0; 2433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t mapping_table_offset = 0; 2443320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t vmap_table_offset = 0; 245e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint32_t gc_map_offset = 0; 2463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledInvokeStub if available 2473320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t invoke_stub_offset = 0; 248fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#if defined(ART_USE_LLVM_COMPILER) 249971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_offset = 0; 250fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#endif 2513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledMethod* compiled_method = 25311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file, method_idx)); 2543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 255971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = compiled_method->AlignCode(offset); 256971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 257971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 258971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 259971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 260971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_method->CodeDelta(); 261971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = offset + sizeof(code_size) + thumb_offset; 262971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 263971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 264971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 265971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end()) { 266971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = code_iter->second; 26755d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 268971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&code, code_offset); 269971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(code_size); // code size is prepended before code 270971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += code_size; 271971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&code[0], code_size); 272971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 273971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); 274971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien core_spill_mask = compiled_method->GetCoreSpillMask(); 275971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien fp_spill_mask = compiled_method->GetFpSpillMask(); 276971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 277971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 278971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 279971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = (mapping_table_size == 0) ? 0 : offset; 280971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 281971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 282971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table); 283971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end()) { 284971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = mapping_iter->second; 285971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 286971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.Put(&mapping_table, mapping_table_offset); 287971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += mapping_table_size; 288971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size); 289971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 290ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 291971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 292971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 293971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = (vmap_table_size == 0) ? 0 : offset; 294e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 295971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 296971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table); 297971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end()) { 298971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = vmap_iter->second; 299971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 300971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.Put(&vmap_table, vmap_table_offset); 301971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += vmap_table_size; 302971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size); 303971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 304e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 3050c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const std::vector<uint8_t>& gc_map = compiled_method->GetNativeGcMap(); 306971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 307971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = (gc_map_size == 0) ? 0 : offset; 308971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 309971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#if !defined(NDEBUG) && !defined(ART_USE_LLVM_COMPILER) 310971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // We expect GC maps except when the class hasn't been verified or the method is native 311ec0142313a470edecf52b4f034433404b7264358jeffhao Compiler::ClassReference class_ref = Compiler::ClassReference(dex_file, class_def_index); 312ec0142313a470edecf52b4f034433404b7264358jeffhao CompiledClass* compiled_class = compiler_->GetCompiledClass(class_ref); 313ec0142313a470edecf52b4f034433404b7264358jeffhao Class::Status status; 314ec0142313a470edecf52b4f034433404b7264358jeffhao if (compiled_class != NULL) { 315ec0142313a470edecf52b4f034433404b7264358jeffhao status = compiled_class->GetStatus(); 316ec0142313a470edecf52b4f034433404b7264358jeffhao } else if (verifier::MethodVerifier::IsClassRejected(class_ref)) { 317ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusError; 318ec0142313a470edecf52b4f034433404b7264358jeffhao } else { 319ec0142313a470edecf52b4f034433404b7264358jeffhao status = Class::kStatusNotReady; 320ec0142313a470edecf52b4f034433404b7264358jeffhao } 321971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(gc_map_size != 0 || is_native || status < Class::kStatusVerified) 322971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " << (status < Class::kStatusVerified) << " " << status << " " << PrettyMethod(method_idx, *dex_file); 323c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers#endif 324c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers 325971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 326971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = gc_map_offsets_.find(&gc_map); 327971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end()) { 328971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = gc_map_iter->second; 329971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 330971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.Put(&gc_map, gc_map_offset); 331971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += gc_map_size; 332971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&gc_map[0], gc_map_size); 333e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 3343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx)); 33708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(type == kStatic, 33808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers shorty); 3393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 340971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 341971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 342971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 343971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 344971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 345971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_invoke_stub->CodeDelta(); 346971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset; 347971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 348971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 349971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); 350971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 351971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = stub_iter->second; 35255d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 353971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&invoke_stub, invoke_stub_offset); 354971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code 355971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += invoke_stub_size; 356971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); 35755d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 3583320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3607a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 36199bc2176824556730c948f17cbdb7993b17fcb6eLogan Chien if (type != kStatic) { 3627a2a23a44d27f769718e28327af671f4e486c49aLogan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 3637a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub != NULL) { 364971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 365971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 366971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 367971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 368971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 369971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_proxy_stub->CodeDelta(); 370971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = offset + sizeof(proxy_stub_size) + thumb_offset; 371971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 372971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 373971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&proxy_stub); 374971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 375971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = stub_iter->second; 376971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 377971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&proxy_stub, proxy_stub_offset); 378971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(proxy_stub_size); // proxy stub size is prepended before code 379971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += proxy_stub_size; 380971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&proxy_stub[0], proxy_stub_size); 381971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 3827a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3837a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3847a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#endif 3857a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 386389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index] 3873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom = OatMethodOffsets(code_offset, 3883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes, 3893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask, 3903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask, 3913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset, 3923320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset, 393e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom gc_map_offset, 394ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien invoke_stub_offset 395ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#if defined(ART_USE_LLVM_COMPILER) 396971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien , proxy_stub_offset 397ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#endif 398ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien ); 3993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiler_->IsImage()) { 4010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassLinker* linker = Runtime::Current()->GetClassLinker(); 4020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DexCache* dex_cache = linker->FindDexCache(*dex_file); 40300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Unchecked as we hold mutator_lock_ on entry. 40400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 40566f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, 406c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao soa.Decode<ClassLoader*>(class_loader_), NULL, type); 4070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(method != NULL); 4080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFrameSizeInBytes(frame_size_in_bytes); 4090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetCoreSpillMask(core_spill_mask); 4100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFpSpillMask(fp_spill_mask); 4110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatMappingTableOffset(mapping_table_offset); 4121984651929744dd603fd082e23eacd877b9bc177Ian Rogers // Don't overwrite static method trampoline 4131984651929744dd603fd082e23eacd877b9bc177Ian Rogers if (!method->IsStatic() || method->IsConstructor() || 4141984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->GetDeclaringClass()->IsInitialized()) { 4151984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetOatCodeOffset(code_offset); 4161984651929744dd603fd082e23eacd877b9bc177Ian Rogers } else { 4171984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetCode(Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()); 4181984651929744dd603fd082e23eacd877b9bc177Ian Rogers } 4190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatVmapTableOffset(vmap_table_offset); 4200c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers method->SetOatNativeGcMapOffset(gc_map_offset); 4210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatInvokeStubOffset(invoke_stub_offset); 4220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4238b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 424e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 425e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 426e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 4273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#define DCHECK_CODE_OFFSET() \ 4282a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes DCHECK_EQ(static_cast<off_t>(code_offset), lseek(file->Fd(), 0, SEEK_CUR)) 4293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 430234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Write(File* file) { 431e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(oat_header_, sizeof(*oat_header_))) { 432234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat header to " << file->name(); 433e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 434e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 435e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 43681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom if (!file->WriteFully(image_file_location_.data(), 43781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_.size())) { 43881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom PLOG(ERROR) << "Failed to write oat header image file location to " << file->name(); 43981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom return false; 44081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom } 44181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 442234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes if (!WriteTables(file)) { 443234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat tables to " << file->name(); 444e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 445e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 446e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 447234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes size_t code_offset = WriteCode(file); 448e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 449234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code to " << file->name(); 450e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 451e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 452e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 453234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes code_offset = WriteCodeDexFiles(file, code_offset); 454e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 455234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code for dex files to " << file->name(); 456e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 457e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 458e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 459e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 460e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 461e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 462e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::WriteTables(File* file) { 463e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 464e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!oat_dex_files_[i]->Write(file)) { 465234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat dex information to " << file->name(); 466e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 467e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 468e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 46989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 47089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom uint32_t expected_offset = oat_dex_files_[i]->dex_file_offset_; 4712a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes off_t actual_offset = lseek(file->Fd(), expected_offset, SEEK_SET); 47289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (static_cast<uint32_t>(actual_offset) != expected_offset) { 47389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 47489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to seek to dex file section. Actual: " << actual_offset 47589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom << " Expected: " << expected_offset << " File: " << dex_file->GetLocation(); 47689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 47789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 47889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 47989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (!file->WriteFully(&dex_file->GetHeader(), dex_file->GetHeader().file_size_)) { 48089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to write dex file " << dex_file->GetLocation() << " to " << file->name(); 48189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 48289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 48389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 484389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 485389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom if (!oat_classes_[i]->Write(file)) { 486234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat methods information to " << file->name(); 487e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 488e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 489e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 490e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 491e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 492e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 493e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCode(File* file) { 494e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom uint32_t code_offset = oat_header_->GetExecutableOffset(); 4952a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes off_t new_offset = lseek(file->Fd(), executable_offset_padding_length_, SEEK_CUR); 496e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (static_cast<uint32_t>(new_offset) != code_offset) { 4973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to oat code section. Actual: " << new_offset 498234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes << " Expected: " << code_offset << " File: " << file->name(); 499e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 500e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 502e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 503e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 504e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 505e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeDexFiles(File* file, size_t code_offset) { 5060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t oat_class_index = 0; 5076e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 508e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 509e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 5100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeDexFile(file, code_offset, oat_class_index, *dex_file); 511e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 512e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 513e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 514e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 515e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 516e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 517e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeDexFile(File* file, size_t code_offset, size_t& oat_class_index, 5190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file) { 5200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); 5210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_index++, oat_class_index++) { 522e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 5230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeClassDef(file, code_offset, oat_class_index, dex_file, class_def); 524e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 525e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 526e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 527e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 528e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 529e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 530e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid OatWriter::ReportWriteFailure(const char* what, uint32_t method_idx, 5320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file, File* f) const { 5330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers PLOG(ERROR) << "Failed to write " << what << " for " << PrettyMethod(method_idx, dex_file) 5340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << " to " << f->name(); 535234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes} 536234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 537e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeClassDef(File* file, 5380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t code_offset, size_t oat_class_index, 539e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 540e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 541e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 5420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 5430571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // ie. an empty class such as a marker interface 544387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return code_offset; 545387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 5460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 5470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 5480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 5490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 5520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 5550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 5560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 5570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 5580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 5590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_static, it.GetMemberIndex(), dex_file); 560e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 561e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 562e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 565e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 5670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 5680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers false, it.GetMemberIndex(), dex_file); 569e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 570e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 571e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 574e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 575e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 576e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 577e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeMethod(File* file, size_t code_offset, size_t oat_class_index, 5790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, 5800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile& dex_file) { 5810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 58211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file, method_idx)); 5830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers OatMethodOffsets method_offsets = 585389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index]; 5860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_method != NULL) { // ie. not an abstract method 589971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset); 590971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 591971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 592971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 593971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 594971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset 595971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset << " File: " << file->name(); 596971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 597f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 598971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 599f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 600971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 601971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 602971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 603971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 604971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 605971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 606971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 607971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(code_size) + compiled_method->CodeDelta(); 608971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 609971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) { 610971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(code_iter->second == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 611971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 612971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 613971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&code_size, sizeof(code_size))) { 614971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("method code size", method_idx, dex_file, file); 615971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 61655d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 617971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(code_size); 618ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 619971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&code[0], code_size)) { 620971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("method code", method_idx, dex_file, file); 621971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 62255d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 623971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += code_size; 624971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 625971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 626971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 627971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 628971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 629971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 630971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 631971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = 632971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.find(&mapping_table); 633971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end() && 634971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.mapping_table_offset_) { 635971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 636971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || mapping_iter->second == method_offsets.mapping_table_offset_) 637971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 638971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 639971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 640971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.mapping_table_offset_) 641971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 642971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&mapping_table[0], mapping_table_size)) { 643971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("mapping table", method_idx, dex_file, file); 644971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 645e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 646971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += mapping_table_size; 647971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 648971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 649971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 650971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 651971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 652971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 653971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 654971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = 655971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.find(&vmap_table); 656971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end() && 657971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.vmap_table_offset_) { 658971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 659971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || vmap_iter->second == method_offsets.vmap_table_offset_) 660971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 661971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 662971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 663971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.vmap_table_offset_) 664971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 665971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&vmap_table[0], vmap_table_size)) { 666971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("vmap table", method_idx, dex_file, file); 667971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 668971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 669971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += vmap_table_size; 670e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 671971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 672971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 6730c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const std::vector<uint8_t>& gc_map = compiled_method->GetNativeGcMap(); 674971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 675971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 676971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 677971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = 678971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.find(&gc_map); 679971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end() && 680971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.gc_map_offset_) { 681971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 682971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || gc_map_iter->second == method_offsets.gc_map_offset_) 683971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 684971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 685971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 686971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.gc_map_offset_) 687971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 688971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&gc_map[0], gc_map_size)) { 689971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("GC map", method_idx, dex_file, file); 690971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 691971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 692971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += gc_map_size; 693971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 694971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 695e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 6960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 6970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 6983320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 699971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 700971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiler_->GetInstructionSet()); 701971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 702971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 703971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 704971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 705971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset 706971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset; 707971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 708971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 709971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 710971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 711971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 712971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 713971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 714971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 715971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 716971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 717971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 718971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta(); 719971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 720971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&invoke_stub); 721971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.invoke_stub_offset_) { 722971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 723971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 724971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 725971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) { 726971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("invoke stub code size", method_idx, dex_file, file); 727971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 728971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 729971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(invoke_stub_size); 730971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 731971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&invoke_stub[0], invoke_stub_size)) { 732971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("invoke stub code", method_idx, dex_file, file); 733971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 734971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 735971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += invoke_stub_size; 736971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 737971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 738971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 739971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 740971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#if defined(ART_USE_LLVM_COMPILER) 74199bc2176824556730c948f17cbdb7993b17fcb6eLogan Chien if (!is_static) { 742971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 743971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (compiled_proxy_stub != NULL) { 744ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 745ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien compiler_->GetInstructionSet()); 746ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 747971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(aligned_code_delta < 48u); 748ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (aligned_code_delta != 0) { 749ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 750ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 751971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align proxy stub code. Actual: " << new_offset 752ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien << " Expected: " << aligned_code_offset; 753ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 754ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 755ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien code_offset += aligned_code_delta; 756ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 7573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 758ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 759971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 760971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 761971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 762ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 763971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 764971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(proxy_stub_size) + compiled_proxy_stub->CodeDelta(); 765a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 766971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&proxy_stub); 767971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.proxy_stub_offset_) { 768971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 769ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } else { 770971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 771971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&proxy_stub_size, sizeof(proxy_stub_size))) { 772971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("proxy stub code size", method_idx, dex_file, file); 773ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 774ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 775971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(proxy_stub_size); 776ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 777971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&proxy_stub[0], proxy_stub_size)) { 778971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("proxy stub code", method_idx, dex_file, file); 779ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 780ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 781971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += proxy_stub_size; 782971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 783f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 784f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 7853320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 7863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 787971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#endif 7888b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 789e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 790e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 791e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 792e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatDexFile::OatDexFile(const DexFile& dex_file) { 793955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string& location(dex_file.GetLocation()); 794e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_size_ = location.size(); 795e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_data_ = reinterpret_cast<const uint8_t*>(location.data()); 7965b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom dex_file_location_checksum_ = dex_file.GetLocationChecksum(); 79789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom dex_file_offset_ = 0; 7986e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom methods_offsets_.resize(dex_file.NumClassDefs()); 799e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 800e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 801e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatDexFile::SizeOf() const { 802e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return sizeof(dex_file_location_size_) 803e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + dex_file_location_size_ 8045b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom + sizeof(dex_file_location_checksum_) 80589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom + sizeof(dex_file_offset_) 8066e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom + (sizeof(methods_offsets_[0]) * methods_offsets_.size()); 807e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 808e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 809e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatDexFile::UpdateChecksum(OatHeader& oat_header) const { 810e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); 811e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(dex_file_location_data_, dex_file_location_size_); 8125b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_)); 81389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_header.UpdateChecksum(&dex_file_offset_, sizeof(dex_file_offset_)); 8146e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_header.UpdateChecksum(&methods_offsets_[0], 8156e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size()); 816e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 817e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 818e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::OatDexFile::Write(File* file) const { 819e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { 820234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location length to " << file->name(); 821e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 822e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 823e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(dex_file_location_data_, dex_file_location_size_)) { 824234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location data to " << file->name(); 825e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 826e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 8275b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom if (!file->WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) { 8285b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom PLOG(ERROR) << "Failed to write dex file location checksum to " << file->name(); 829e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 830e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 83189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (!file->WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) { 83289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to write dex file offset to " << file->name(); 83389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 83489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 8356e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom if (!file->WriteFully(&methods_offsets_[0], 8366e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size())) { 837234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write methods offsets to " << file->name(); 838e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 839e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 840e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 841e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 842e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 8430755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromOatWriter::OatClass::OatClass(Class::Status status, uint32_t methods_count) { 8440755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom status_ = status; 845e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom method_offsets_.resize(methods_count); 846e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 847e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 848389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::OatClass::SizeOf() const { 8490755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return sizeof(status_) 8500755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom + (sizeof(method_offsets_[0]) * method_offsets_.size()); 851e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 852e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 853389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromvoid OatWriter::OatClass::UpdateChecksum(OatHeader& oat_header) const { 8540755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&status_, sizeof(status_)); 8550755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&method_offsets_[0], 8560755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size()); 857e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 858e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 859389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrombool OatWriter::OatClass::Write(File* file) const { 8600755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (!file->WriteFully(&status_, sizeof(status_))) { 8610755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom PLOG(ERROR) << "Failed to write class status to " << file->name(); 8620755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return false; 8630755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 8640755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (!file->WriteFully(&method_offsets_[0], 8650755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size())) { 866234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write method offsets to " << file->name(); 867e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 868e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 869e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 870e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 871e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 872e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 873