oat_writer.cc revision 08f753d5859936f8d3524e9e4faa6cee353873ea
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" 2781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom#include "space.h" 28e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "stl_util.h" 29e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 30e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 31e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 32234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Create(File* file, 3300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader, 3410037c866b04550fc5461058c398c2e3e509381ajeffhao const std::vector<const DexFile*>& dex_files, 3581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom uint32_t image_file_location_checksum, 3681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 3881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom OatWriter oat_writer(dex_files, 3981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_checksum, 4081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location, 4181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom class_loader, 4281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom compiler); 43234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes return oat_writer.Write(file); 44e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 45e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 463320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, 4781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom uint32_t image_file_location_checksum, 4881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::string& image_file_location, 4900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader, 503320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom compiler_ = &compiler; 52e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_loader_ = class_loader; 5381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_checksum_ = image_file_location_checksum; 5481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_ = image_file_location; 55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_files_ = &dex_files; 560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers oat_header_ = NULL; 570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers executable_offset_padding_length_ = 0; 58e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom size_t offset = InitOatHeader(); 60e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatDexFiles(offset); 6189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = InitDexFiles(offset); 62389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset = InitOatClasses(offset); 63e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCode(offset); 64e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFiles(offset); 65e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 66e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); 67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersOatWriter::~OatWriter() { 700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers delete oat_header_; 710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_dex_files_); 72389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom STLDeleteElements(&oat_classes_); 730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 7581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromsize_t OatWriter::InitOatHeader() { 76e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatHeader 7781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom oat_header_ = new OatHeader(compiler_->GetInstructionSet(), 7881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom dex_files_, 7981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_checksum_, 8081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_); 81e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t offset = sizeof(*oat_header_); 8281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom offset += image_file_location_.size(); 83e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 84e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 85e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 86e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatDexFiles(size_t offset) { 87e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatDexFiles 88e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 89e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom OatDexFile* oat_dex_file = new OatDexFile(*dex_file); 92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_.push_back(oat_dex_file); 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_dex_file->SizeOf(); 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 96e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 97e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 9889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstromsize_t OatWriter::InitDexFiles(size_t offset) { 9989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // calculate the offsets within OatDexFiles to the DexFiles 10089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 10189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // dex files are required to be 4 byte aligned 10289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset = RoundUp(offset, 4); 10389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 10489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom // set offset in OatDexFile to DexFile 10589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_dex_files_[i]->dex_file_offset_ = offset; 10689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 10789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 10889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom offset += dex_file->GetHeader().file_size_; 10989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 11089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return offset; 11189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom} 11289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom 113389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::InitOatClasses(size_t offset) { 114389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // create the OatClasses 115389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom // calculate the offsets within OatDexFiles to OatClasses 116e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 117e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 118e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t class_def_index = 0; 119e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file->NumClassDefs(); 120c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers class_def_index++) { 1216e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->methods_offsets_[class_def_index] = offset; 122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 123e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file->GetClassData(class_def); 1240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t num_methods = 0; 1250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data != NULL) { // ie not an empty class, such as a marker interface 1260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(*dex_file, class_data); 1270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_direct_methods = it.NumDirectMethods(); 1280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_virtual_methods = it.NumVirtualMethods(); 1290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers num_methods = num_direct_methods + num_virtual_methods; 1300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1310755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 1320755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CompiledClass* compiled_class = 13311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledClass(Compiler::MethodReference(dex_file, class_def_index)); 1340755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom Class::Status status = 1350755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom (compiled_class != NULL) ? compiled_class->GetStatus() : Class::kStatusNotReady; 1360755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 1370755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom OatClass* oat_class = new OatClass(status, num_methods); 138389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_.push_back(oat_class); 139389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom offset += oat_class->SizeOf(); 140e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1416e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_dex_files_[i]->UpdateChecksum(*oat_header_); 142e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 143e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 144e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 145e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 146e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCode(size_t offset) { 147e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatHeader to executable code 148e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t old_offset = offset; 149e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // required to be on a new page boundary 150e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = RoundUp(offset, kPageSize); 151e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header_->SetExecutableOffset(offset); 152e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom executable_offset_padding_length_ = offset - old_offset; 153e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 154e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 155e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 156e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFiles(size_t offset) { 157e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t oat_class_index = 0; 158e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 159e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 160e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 161e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFile(offset, oat_class_index, *dex_file); 162e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 164e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 165e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 166e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFile(size_t offset, 167e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t& oat_class_index, 168e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file) { 169ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes for (size_t class_def_index = 0; 170e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file.NumClassDefs(); 171e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index++, oat_class_index++) { 172e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 173c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers offset = InitOatCodeClassDef(offset, oat_class_index, class_def_index, dex_file, class_def); 174389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->UpdateChecksum(*oat_header_); 175e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 176e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 177e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 178e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 179e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeClassDef(size_t offset, 180c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers size_t oat_class_index, size_t class_def_index, 181e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 182e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 183e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 1850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, such as a marker interface 186387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return offset; 187387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 1880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 189389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom CHECK_EQ(oat_classes_[oat_class_index]->method_offsets_.size(), 1900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.NumDirectMethods() + it.NumVirtualMethods()); 1910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 1920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 1930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 194e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 1960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 197e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 1990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 2000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 201c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 20208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 20308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 20408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 209c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 21008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, 21108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers is_native, it.GetMethodInvokeType(class_def), it.GetMemberIndex(), 21208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers &dex_file); 2130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 217e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 218e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 219e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2201bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughessize_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, 2211bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t __attribute__((unused)) class_def_index, 2221bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes size_t class_def_method_index, 2231bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes bool __attribute__((unused)) is_native, 22408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType type, 2251bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes uint32_t method_idx, const DexFile* dex_file) { 2263320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledMethod if available 2273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t code_offset = 0; 2283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t frame_size_in_bytes = kStackAlignment; 2293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t core_spill_mask = 0; 2303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t fp_spill_mask = 0; 2313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t mapping_table_offset = 0; 2323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t vmap_table_offset = 0; 233e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint32_t gc_map_offset = 0; 2343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledInvokeStub if available 2353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t invoke_stub_offset = 0; 236fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#if defined(ART_USE_LLVM_COMPILER) 237971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_offset = 0; 238fd2ec5473d9c63b15dbc28c8a5996c83120cb8aeBrian Carlstrom#endif 2393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledMethod* compiled_method = 24111d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file, method_idx)); 2423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 243971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = compiled_method->AlignCode(offset); 244971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 245971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 246971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 247971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 248971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_method->CodeDelta(); 249971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = offset + sizeof(code_size) + thumb_offset; 250971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 251971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 252971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 253971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end()) { 254971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset = code_iter->second; 25555d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 256971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&code, code_offset); 257971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(code_size); // code size is prepended before code 258971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += code_size; 259971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&code[0], code_size); 260971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 261971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); 262971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien core_spill_mask = compiled_method->GetCoreSpillMask(); 263971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien fp_spill_mask = compiled_method->GetFpSpillMask(); 264971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 265971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 266971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 267971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = (mapping_table_size == 0) ? 0 : offset; 268971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 269971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 270971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table); 271971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end()) { 272971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offset = mapping_iter->second; 273971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 274971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.Put(&mapping_table, mapping_table_offset); 275971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += mapping_table_size; 276971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size); 277971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 278ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 279971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 280971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 281971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = (vmap_table_size == 0) ? 0 : offset; 282e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 283971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 284971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table); 285971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end()) { 286971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offset = vmap_iter->second; 287971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 288971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.Put(&vmap_table, vmap_table_offset); 289971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += vmap_table_size; 290971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size); 291971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 292e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 293971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap(); 294971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 295971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = (gc_map_size == 0) ? 0 : offset; 296971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 297971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#if !defined(NDEBUG) && !defined(ART_USE_LLVM_COMPILER) 298971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // We expect GC maps except when the class hasn't been verified or the method is native 299971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CompiledClass* compiled_class = 300971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiler_->GetCompiledClass(Compiler::MethodReference(dex_file, class_def_index)); 301971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien Class::Status status = 302971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien (compiled_class != NULL) ? compiled_class->GetStatus() : Class::kStatusNotReady; 303971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(gc_map_size != 0 || is_native || status < Class::kStatusVerified) 304971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " << (status < Class::kStatusVerified) << " " << status << " " << PrettyMethod(method_idx, *dex_file); 305c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers#endif 306c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers 307971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 308971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = gc_map_offsets_.find(&gc_map); 309971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end()) { 310971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offset = gc_map_iter->second; 311971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 312971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.Put(&gc_map, gc_map_offset); 313971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += gc_map_size; 314971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&gc_map[0], gc_map_size); 315e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 3163320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx)); 31908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(type == kStatic, 32008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers shorty); 3213320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 322971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 323971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 324971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 325971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 326971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 327971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_invoke_stub->CodeDelta(); 328971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset; 329971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 330971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 331971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); 332971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 333971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = stub_iter->second; 33455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 335971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&invoke_stub, invoke_stub_offset); 336971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code 337971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += invoke_stub_size; 338971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); 33955d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 3403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3427a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 34308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (type == kStatic) { 3447a2a23a44d27f769718e28327af671f4e486c49aLogan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 3457a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub != NULL) { 346971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 347971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 348971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 349971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 350971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 351971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_proxy_stub->CodeDelta(); 352971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = offset + sizeof(proxy_stub_size) + thumb_offset; 353971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 354971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 355971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&proxy_stub); 356971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 357971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = stub_iter->second; 358971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 359971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&proxy_stub, proxy_stub_offset); 360971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(proxy_stub_size); // proxy stub size is prepended before code 361971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += proxy_stub_size; 362971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&proxy_stub[0], proxy_stub_size); 363971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 3647a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3657a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3667a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#endif 3677a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 368389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index] 3693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom = OatMethodOffsets(code_offset, 3703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes, 3713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask, 3723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask, 3733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset, 3743320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset, 375e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom gc_map_offset, 376ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien invoke_stub_offset 377ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#if defined(ART_USE_LLVM_COMPILER) 378971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien , proxy_stub_offset 379ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#endif 380ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien ); 3813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiler_->IsImage()) { 3830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DexCache* dex_cache = linker->FindDexCache(*dex_file); 38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Unchecked as we hold mutator_lock_ on entry. 38600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Method* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, 38808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers soa.Decode<ClassLoader*>(class_loader_), type); 3890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(method != NULL); 3900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFrameSizeInBytes(frame_size_in_bytes); 3910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetCoreSpillMask(core_spill_mask); 3920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFpSpillMask(fp_spill_mask); 3930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatMappingTableOffset(mapping_table_offset); 3941984651929744dd603fd082e23eacd877b9bc177Ian Rogers // Don't overwrite static method trampoline 3951984651929744dd603fd082e23eacd877b9bc177Ian Rogers if (!method->IsStatic() || method->IsConstructor() || 3961984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->GetDeclaringClass()->IsInitialized()) { 3971984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetOatCodeOffset(code_offset); 3981984651929744dd603fd082e23eacd877b9bc177Ian Rogers } else { 3991984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetCode(Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()); 4001984651929744dd603fd082e23eacd877b9bc177Ian Rogers } 4010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatVmapTableOffset(vmap_table_offset); 402e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom method->SetOatGcMapOffset(gc_map_offset); 4030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatInvokeStubOffset(invoke_stub_offset); 4040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4058b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 406e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 407e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 408e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 4093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#define DCHECK_CODE_OFFSET() \ 4102a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes DCHECK_EQ(static_cast<off_t>(code_offset), lseek(file->Fd(), 0, SEEK_CUR)) 4113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 412234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Write(File* file) { 413e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(oat_header_, sizeof(*oat_header_))) { 414234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat header to " << file->name(); 415e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 416e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 417e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 41881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom if (!file->WriteFully(image_file_location_.data(), 41981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_.size())) { 42081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom PLOG(ERROR) << "Failed to write oat header image file location to " << file->name(); 42181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom return false; 42281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom } 42381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 424234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes if (!WriteTables(file)) { 425234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat tables to " << file->name(); 426e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 427e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 428e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 429234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes size_t code_offset = WriteCode(file); 430e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 431234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code to " << file->name(); 432e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 433e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 434e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 435234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes code_offset = WriteCodeDexFiles(file, code_offset); 436e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 437234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code for dex files to " << file->name(); 438e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 439e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 440e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 441e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 442e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 443e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 444e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::WriteTables(File* file) { 445e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 446e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!oat_dex_files_[i]->Write(file)) { 447234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat dex information to " << file->name(); 448e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 449e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 450e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 45189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 45289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom uint32_t expected_offset = oat_dex_files_[i]->dex_file_offset_; 4532a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes off_t actual_offset = lseek(file->Fd(), expected_offset, SEEK_SET); 45489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (static_cast<uint32_t>(actual_offset) != expected_offset) { 45589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 45689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to seek to dex file section. Actual: " << actual_offset 45789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom << " Expected: " << expected_offset << " File: " << dex_file->GetLocation(); 45889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 45989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 46089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 46189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (!file->WriteFully(&dex_file->GetHeader(), dex_file->GetHeader().file_size_)) { 46289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to write dex file " << dex_file->GetLocation() << " to " << file->name(); 46389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 46489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 46589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 466389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 467389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom if (!oat_classes_[i]->Write(file)) { 468234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat methods information to " << file->name(); 469e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 470e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 471e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 472e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 473e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 474e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 475e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCode(File* file) { 476e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom uint32_t code_offset = oat_header_->GetExecutableOffset(); 4772a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes off_t new_offset = lseek(file->Fd(), executable_offset_padding_length_, SEEK_CUR); 478e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (static_cast<uint32_t>(new_offset) != code_offset) { 4793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to oat code section. Actual: " << new_offset 480234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes << " Expected: " << code_offset << " File: " << file->name(); 481e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 482e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 484e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 485e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 486e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 487e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeDexFiles(File* file, size_t code_offset) { 4880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t oat_class_index = 0; 4896e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 490e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 491e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 4920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeDexFile(file, code_offset, oat_class_index, *dex_file); 493e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 494e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 495e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 496e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 497e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 498e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 499e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeDexFile(File* file, size_t code_offset, size_t& oat_class_index, 5010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file) { 5020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); 5030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_index++, oat_class_index++) { 504e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 5050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeClassDef(file, code_offset, oat_class_index, dex_file, class_def); 506e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 507e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 508e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 509e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 510e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 511e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 512e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid OatWriter::ReportWriteFailure(const char* what, uint32_t method_idx, 5140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file, File* f) const { 5150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers PLOG(ERROR) << "Failed to write " << what << " for " << PrettyMethod(method_idx, dex_file) 5160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << " to " << f->name(); 517234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes} 518234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 519e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeClassDef(File* file, 5200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t code_offset, size_t oat_class_index, 521e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 522e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 523e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 5240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 5250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // ie. an empty class such as a marker interface 526387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return code_offset; 527387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 5280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 5290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 5300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 5310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 5340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5350571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 5370571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 5380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 5390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 5400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 5410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_static, it.GetMemberIndex(), dex_file); 542e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 543e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 544e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 547e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 5490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 5500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers false, it.GetMemberIndex(), dex_file); 551e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 552e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 553e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 556e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 557e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 558e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 559e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeMethod(File* file, size_t code_offset, size_t oat_class_index, 5610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, 5620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile& dex_file) { 5630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 56411d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file, method_idx)); 5650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers OatMethodOffsets method_offsets = 567389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index]; 5680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_method != NULL) { // ie. not an abstract method 571971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset); 572971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 573971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 574971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 575971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 576971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset 577971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset << " File: " << file->name(); 578971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 579f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 580971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 581f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 582971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 583971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 584971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 585971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 586971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 587971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 588971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 589971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(code_size) + compiled_method->CodeDelta(); 590971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 591971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) { 592971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(code_iter->second == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 593971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 594971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 595971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&code_size, sizeof(code_size))) { 596971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("method code size", method_idx, dex_file, file); 597971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 59855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 599971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(code_size); 600ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 601971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&code[0], code_size)) { 602971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("method code", method_idx, dex_file, file); 603971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 60455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 605971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += code_size; 606971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 607971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 608971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 609971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 610971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 611971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 612971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 613971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = 614971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.find(&mapping_table); 615971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end() && 616971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.mapping_table_offset_) { 617971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 618971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || mapping_iter->second == method_offsets.mapping_table_offset_) 619971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 620971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 621971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 622971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.mapping_table_offset_) 623971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 624971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&mapping_table[0], mapping_table_size)) { 625971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("mapping table", method_idx, dex_file, file); 626971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 627e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 628971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += mapping_table_size; 629971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 630971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 631971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 632971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 633971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 634971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 635971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 636971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = 637971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.find(&vmap_table); 638971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end() && 639971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.vmap_table_offset_) { 640971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 641971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || vmap_iter->second == method_offsets.vmap_table_offset_) 642971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 643971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 644971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 645971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.vmap_table_offset_) 646971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 647971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&vmap_table[0], vmap_table_size)) { 648971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("vmap table", method_idx, dex_file, file); 649971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 650971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 651971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += vmap_table_size; 652e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 653971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 654971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 655971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap(); 656971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 657971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 658971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 659971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = 660971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.find(&gc_map); 661971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end() && 662971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.gc_map_offset_) { 663971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 664971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || gc_map_iter->second == method_offsets.gc_map_offset_) 665971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 666971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 667971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 668971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.gc_map_offset_) 669971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 670971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&gc_map[0], gc_map_size)) { 671971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("GC map", method_idx, dex_file, file); 672971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 673971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 674971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += gc_map_size; 675971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 676971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 677e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 6780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 6790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 6803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 681971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 682971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiler_->GetInstructionSet()); 683971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 684971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 685971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 686971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 687971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset 688971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset; 689971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 690971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 691971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 692971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 693971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 694971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 695971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 696971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 697971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 698971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 699971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 700971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta(); 701971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 702971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&invoke_stub); 703971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.invoke_stub_offset_) { 704971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 705971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 706971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 707971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) { 708971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("invoke stub code size", method_idx, dex_file, file); 709971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 710971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 711971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(invoke_stub_size); 712971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 713971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&invoke_stub[0], invoke_stub_size)) { 714971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("invoke stub code", method_idx, dex_file, file); 715971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 716971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 717971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += invoke_stub_size; 718971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 719971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 720971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 721971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 722971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#if defined(ART_USE_LLVM_COMPILER) 72308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (is_static) { 724971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 725971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (compiled_proxy_stub != NULL) { 726ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 727ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien compiler_->GetInstructionSet()); 728ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 729971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(aligned_code_delta < 48u); 730ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (aligned_code_delta != 0) { 731ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 732ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 733971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align proxy stub code. Actual: " << new_offset 734ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien << " Expected: " << aligned_code_offset; 735ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 736ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 737ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien code_offset += aligned_code_delta; 738ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 7393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 740ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 741971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 742971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 743971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 744ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 745971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 746971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(proxy_stub_size) + compiled_proxy_stub->CodeDelta(); 747a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 748971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&proxy_stub); 749971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.proxy_stub_offset_) { 750971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 751ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } else { 752971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 753971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&proxy_stub_size, sizeof(proxy_stub_size))) { 754971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("proxy stub code size", method_idx, dex_file, file); 755ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 756ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 757971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(proxy_stub_size); 758ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 759971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&proxy_stub[0], proxy_stub_size)) { 760971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("proxy stub code", method_idx, dex_file, file); 761ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 762ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 763971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += proxy_stub_size; 764971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 765f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 766f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 7673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 7683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 769971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#endif 7708b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 771e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 772e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 773e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 774e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatDexFile::OatDexFile(const DexFile& dex_file) { 775955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string& location(dex_file.GetLocation()); 776e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_size_ = location.size(); 777e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_data_ = reinterpret_cast<const uint8_t*>(location.data()); 7785b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom dex_file_location_checksum_ = dex_file.GetLocationChecksum(); 77989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom dex_file_offset_ = 0; 7806e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom methods_offsets_.resize(dex_file.NumClassDefs()); 781e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 782e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 783e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatDexFile::SizeOf() const { 784e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return sizeof(dex_file_location_size_) 785e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + dex_file_location_size_ 7865b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom + sizeof(dex_file_location_checksum_) 78789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom + sizeof(dex_file_offset_) 7886e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom + (sizeof(methods_offsets_[0]) * methods_offsets_.size()); 789e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 790e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 791e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatDexFile::UpdateChecksum(OatHeader& oat_header) const { 792e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); 793e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(dex_file_location_data_, dex_file_location_size_); 7945b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_)); 79589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_header.UpdateChecksum(&dex_file_offset_, sizeof(dex_file_offset_)); 7966e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_header.UpdateChecksum(&methods_offsets_[0], 7976e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size()); 798e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 799e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 800e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::OatDexFile::Write(File* file) const { 801e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { 802234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location length to " << file->name(); 803e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 804e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 805e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(dex_file_location_data_, dex_file_location_size_)) { 806234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location data to " << file->name(); 807e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 808e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 8095b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom if (!file->WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) { 8105b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom PLOG(ERROR) << "Failed to write dex file location checksum to " << file->name(); 811e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 812e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 81389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (!file->WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) { 81489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to write dex file offset to " << file->name(); 81589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 81689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 8176e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom if (!file->WriteFully(&methods_offsets_[0], 8186e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size())) { 819234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write methods offsets to " << file->name(); 820e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 821e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 822e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 823e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 824e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 8250755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromOatWriter::OatClass::OatClass(Class::Status status, uint32_t methods_count) { 8260755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom status_ = status; 827e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom method_offsets_.resize(methods_count); 828e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 829e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 830389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::OatClass::SizeOf() const { 8310755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return sizeof(status_) 8320755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom + (sizeof(method_offsets_[0]) * method_offsets_.size()); 833e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 834e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 835389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromvoid OatWriter::OatClass::UpdateChecksum(OatHeader& oat_header) const { 8360755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&status_, sizeof(status_)); 8370755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&method_offsets_[0], 8380755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size()); 839e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 840e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 841389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrombool OatWriter::OatClass::Write(File* file) const { 8420755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (!file->WriteFully(&status_, sizeof(status_))) { 8430755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom PLOG(ERROR) << "Failed to write class status to " << file->name(); 8440755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return false; 8450755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 8460755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (!file->WriteFully(&method_offsets_[0], 8470755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size())) { 848234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write method offsets to " << file->name(); 849e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 850e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 851e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 852e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 853e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 854e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 855