oat_writer.cc revision 00f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abac
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()) { 2010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 202c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 203c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, is_native, 204c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers is_static, true, it.GetMemberIndex(), &dex_file); 2050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 2060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 2070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 2080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 2090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK_EQ(it.GetMemberAccessFlags() & kAccStatic, 0U); 210c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0; 211c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_index, class_def_method_index, is_native, 212c20a83e440557924dacaf8ec519e086865aaf5a5Ian Rogers false, false, it.GetMemberIndex(), &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, 2241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes bool is_static, bool is_direct, 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)); 3190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 3203320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 321971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 322971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 323971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 324971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 325971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 326971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_invoke_stub->CodeDelta(); 327971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset; 328971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 329971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 330971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); 331971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 332971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien invoke_stub_offset = stub_iter->second; 33355d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 334971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&invoke_stub, invoke_stub_offset); 335971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code 336971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += invoke_stub_size; 337971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); 33855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 3393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 3403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3417a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 3427a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (!is_static) { 3437a2a23a44d27f769718e28327af671f4e486c49aLogan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 3447a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub != NULL) { 345971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 346971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(offset, kArmAlignment); 347971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 348971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 349971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 350971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t thumb_offset = compiled_proxy_stub->CodeDelta(); 351971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = offset + sizeof(proxy_stub_size) + thumb_offset; 352971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 353971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 354971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&proxy_stub); 355971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end()) { 356971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien proxy_stub_offset = stub_iter->second; 357971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 358971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.Put(&proxy_stub, proxy_stub_offset); 359971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += sizeof(proxy_stub_size); // proxy stub size is prepended before code 360971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien offset += proxy_stub_size; 361971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien oat_header_->UpdateChecksum(&proxy_stub[0], proxy_stub_size); 362971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 3637a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3647a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3657a2a23a44d27f769718e28327af671f4e486c49aLogan Chien#endif 3667a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 367389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index] 3683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom = OatMethodOffsets(code_offset, 3693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes, 3703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask, 3713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask, 3723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset, 3733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset, 374e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom gc_map_offset, 375ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien invoke_stub_offset 376ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#if defined(ART_USE_LLVM_COMPILER) 377971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien , proxy_stub_offset 378ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien#endif 379ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien ); 3803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiler_->IsImage()) { 3820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DexCache* dex_cache = linker->FindDexCache(*dex_file); 38400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Unchecked as we hold mutator_lock_ on entry. 38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 38600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Method* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, 38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Decode<ClassLoader*>(class_loader_), is_direct); 3880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(method != NULL); 3890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFrameSizeInBytes(frame_size_in_bytes); 3900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetCoreSpillMask(core_spill_mask); 3910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFpSpillMask(fp_spill_mask); 3920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatMappingTableOffset(mapping_table_offset); 3931984651929744dd603fd082e23eacd877b9bc177Ian Rogers // Don't overwrite static method trampoline 3941984651929744dd603fd082e23eacd877b9bc177Ian Rogers if (!method->IsStatic() || method->IsConstructor() || 3951984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->GetDeclaringClass()->IsInitialized()) { 3961984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetOatCodeOffset(code_offset); 3971984651929744dd603fd082e23eacd877b9bc177Ian Rogers } else { 3981984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetCode(Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()); 3991984651929744dd603fd082e23eacd877b9bc177Ian Rogers } 4000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatVmapTableOffset(vmap_table_offset); 401e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom method->SetOatGcMapOffset(gc_map_offset); 4020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatInvokeStubOffset(invoke_stub_offset); 4030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4048b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 405e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 406e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 407e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 4083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#define DCHECK_CODE_OFFSET() \ 4092a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes DCHECK_EQ(static_cast<off_t>(code_offset), lseek(file->Fd(), 0, SEEK_CUR)) 4103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 411234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Write(File* file) { 412e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(oat_header_, sizeof(*oat_header_))) { 413234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat header to " << file->name(); 414e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 415e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 416e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 41781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom if (!file->WriteFully(image_file_location_.data(), 41881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom image_file_location_.size())) { 41981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom PLOG(ERROR) << "Failed to write oat header image file location to " << file->name(); 42081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom return false; 42181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom } 42281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 423234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes if (!WriteTables(file)) { 424234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat tables to " << file->name(); 425e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 426e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 427e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 428234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes size_t code_offset = WriteCode(file); 429e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 430234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code to " << file->name(); 431e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 432e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 433e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 434234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes code_offset = WriteCodeDexFiles(file, code_offset); 435e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 436234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code for dex files to " << file->name(); 437e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 438e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 439e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 440e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 441e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 442e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 443e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::WriteTables(File* file) { 444e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 445e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!oat_dex_files_[i]->Write(file)) { 446234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat dex information to " << file->name(); 447e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 448e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 449e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 45089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 45189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom uint32_t expected_offset = oat_dex_files_[i]->dex_file_offset_; 4522a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes off_t actual_offset = lseek(file->Fd(), expected_offset, SEEK_SET); 45389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (static_cast<uint32_t>(actual_offset) != expected_offset) { 45489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 45589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to seek to dex file section. Actual: " << actual_offset 45689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom << " Expected: " << expected_offset << " File: " << dex_file->GetLocation(); 45789521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 45889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 45989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 46089521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (!file->WriteFully(&dex_file->GetHeader(), dex_file->GetHeader().file_size_)) { 46189521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to write dex file " << dex_file->GetLocation() << " to " << file->name(); 46289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 46389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 46489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 465389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 466389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom if (!oat_classes_[i]->Write(file)) { 467234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat methods information to " << file->name(); 468e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 469e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 470e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 471e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 472e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 473e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 474e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCode(File* file) { 475e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom uint32_t code_offset = oat_header_->GetExecutableOffset(); 4762a2ff56f2197b031ced66450e340f656c281c85fElliott Hughes off_t new_offset = lseek(file->Fd(), executable_offset_padding_length_, SEEK_CUR); 477e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (static_cast<uint32_t>(new_offset) != code_offset) { 4783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to oat code section. Actual: " << new_offset 479234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes << " Expected: " << code_offset << " File: " << file->name(); 480e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 481e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 483e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 484e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 485e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 486e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeDexFiles(File* file, size_t code_offset) { 4870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t oat_class_index = 0; 4886e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 489e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 490e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 4910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeDexFile(file, code_offset, oat_class_index, *dex_file); 492e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 493e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 494e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 495e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 496e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 497e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 498e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 4990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeDexFile(File* file, size_t code_offset, size_t& oat_class_index, 5000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file) { 5010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); 5020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_index++, oat_class_index++) { 503e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 5040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeClassDef(file, code_offset, oat_class_index, dex_file, class_def); 505e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 506e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 507e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 508e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 509e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 510e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 511e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid OatWriter::ReportWriteFailure(const char* what, uint32_t method_idx, 5130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file, File* f) const { 5140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers PLOG(ERROR) << "Failed to write " << what << " for " << PrettyMethod(method_idx, dex_file) 5150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << " to " << f->name(); 516234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes} 517234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 518e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeClassDef(File* file, 5190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t code_offset, size_t oat_class_index, 520e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 521e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 522e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 5230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 5240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // ie. an empty class such as a marker interface 525387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return code_offset; 526387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 5270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 5280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 5290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 5300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 5330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5350571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 5360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 5370571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 5380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 5390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 5400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_static, it.GetMemberIndex(), dex_file); 541e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 542e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 543e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 546e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 5480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 5490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers false, it.GetMemberIndex(), dex_file); 550e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 551e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 552e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 5540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 555e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 556e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 557e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 558e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeMethod(File* file, size_t code_offset, size_t oat_class_index, 5600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, 5610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile& dex_file) { 5620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 56311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file, method_idx)); 5640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers OatMethodOffsets method_offsets = 566389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrom oat_classes_[oat_class_index]->method_offsets_[class_def_method_index]; 5670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 5690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_method != NULL) { // ie. not an abstract method 570971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset); 571971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 572971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 573971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 574971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 575971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset 576971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset << " File: " << file->name(); 577971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 578f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 579971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 580f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 581971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 582971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 583971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& code = compiled_method->GetCode(); 584971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t code_size = code.size() * sizeof(code[0]); 585971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(code_size, 0U); 586971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 587971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate code arrays 588971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(code_size) + compiled_method->CodeDelta(); 589971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 590971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) { 591971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(code_iter->second == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 592971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 593971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file); 594971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&code_size, sizeof(code_size))) { 595971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("method code size", method_idx, dex_file, file); 596971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 59755d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 598971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(code_size); 599ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 600971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&code[0], code_size)) { 601971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("method code", method_idx, dex_file, file); 602971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 60355d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 604971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += code_size; 605971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 606971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 607971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 608971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 609971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 610971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 611971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate mapping tables 612971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = 613971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien mapping_table_offsets_.find(&mapping_table); 614971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (mapping_iter != mapping_table_offsets_.end() && 615971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.mapping_table_offset_) { 616971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 617971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || mapping_iter->second == method_offsets.mapping_table_offset_) 618971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 619971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 620971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 621971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.mapping_table_offset_) 622971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 623971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&mapping_table[0], mapping_table_size)) { 624971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("mapping table", method_idx, dex_file, file); 625971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 626e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 627971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += mapping_table_size; 628971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 629971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 630971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 631971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 632971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 633971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 634971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate vmap tables 635971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = 636971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien vmap_table_offsets_.find(&vmap_table); 637971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (vmap_iter != vmap_table_offsets_.end() && 638971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.vmap_table_offset_) { 639971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 640971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || vmap_iter->second == method_offsets.vmap_table_offset_) 641971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 642971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 643971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 644971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.vmap_table_offset_) 645971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 646971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&vmap_table[0], vmap_table_size)) { 647971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("vmap table", method_idx, dex_file, file); 648971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 649971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 650971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += vmap_table_size; 651e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 652971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 653971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 654971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap(); 655971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]); 656971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 657971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate GC maps 658971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = 659971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien gc_map_offsets_.find(&gc_map); 660971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (gc_map_iter != gc_map_offsets_.end() && 661971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset != method_offsets.gc_map_offset_) { 662971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 663971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || gc_map_iter->second == method_offsets.gc_map_offset_) 664971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 665971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 666971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0) 667971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien || code_offset == method_offsets.gc_map_offset_) 668971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << PrettyMethod(method_idx, dex_file); 669971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&gc_map[0], gc_map_size)) { 670971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("GC map", method_idx, dex_file, file); 671971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 672971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 673971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += gc_map_size; 674971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 675971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 676e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 6770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 6780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 6793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 680971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 681971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien compiler_->GetInstructionSet()); 682971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 683971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (aligned_code_delta != 0) { 684971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 685971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 686971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset 687971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien << " Expected: " << aligned_code_offset; 688971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 689971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 690971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += aligned_code_delta; 691971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 692971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 693971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 694971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 695971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 696971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(invoke_stub_size, 0U); 697971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 698971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate invoke stubs 699971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta(); 700971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 701971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&invoke_stub); 702971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.invoke_stub_offset_) { 703971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 704971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } else { 705971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); 706971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) { 707971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("invoke stub code size", method_idx, dex_file, file); 708971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 709971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 710971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(invoke_stub_size); 711971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 712971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&invoke_stub[0], invoke_stub_size)) { 713971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("invoke stub code", method_idx, dex_file, file); 714971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien return 0; 715971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 716971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += invoke_stub_size; 717971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 718971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 719971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien } 720971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien 721971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#if defined(ART_USE_LLVM_COMPILER) 722971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!is_static) { 723971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty); 724971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (compiled_proxy_stub != NULL) { 725ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 726ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien compiler_->GetInstructionSet()); 727ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien uint32_t aligned_code_delta = aligned_code_offset - code_offset; 728971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK(aligned_code_delta < 48u); 729ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (aligned_code_delta != 0) { 730ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 731ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 732971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien PLOG(ERROR) << "Failed to seek to align proxy stub code. Actual: " << new_offset 733ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien << " Expected: " << aligned_code_offset; 734ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 735ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 736ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien code_offset += aligned_code_delta; 737ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 7383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 739ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_ALIGNED(code_offset, kArmAlignment); 740971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode(); 741971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]); 742971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien CHECK_NE(proxy_stub_size, 0U); 743ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien 744971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien // Deduplicate proxy stubs 745971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien size_t offset = code_offset + sizeof(proxy_stub_size) + compiled_proxy_stub->CodeDelta(); 746a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 747971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offsets_.find(&proxy_stub); 748971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (stub_iter != code_offsets_.end() && offset != method_offsets.proxy_stub_offset_) { 749971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(stub_iter->second == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 750ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } else { 751971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK(offset == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file); 752971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&proxy_stub_size, sizeof(proxy_stub_size))) { 753971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("proxy stub code size", method_idx, dex_file, file); 754ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 755ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 756971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += sizeof(proxy_stub_size); 757ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien DCHECK_CODE_OFFSET(); 758971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien if (!file->WriteFully(&proxy_stub[0], proxy_stub_size)) { 759971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien ReportWriteFailure("proxy stub code", method_idx, dex_file, file); 760ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien return 0; 761ccb7bf1271560783adccddb2ab74c53d0efd3fd1Logan Chien } 762971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien code_offset += proxy_stub_size; 763971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien DCHECK_CODE_OFFSET(); 764f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom } 765f8bbb8448c733e9e3ad43aad69774c37888329b1Brian Carlstrom DCHECK_CODE_OFFSET(); 7663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 7673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 768971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien#endif 7698b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 770e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 771e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 772e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 773e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatDexFile::OatDexFile(const DexFile& dex_file) { 774955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string& location(dex_file.GetLocation()); 775e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_size_ = location.size(); 776e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_data_ = reinterpret_cast<const uint8_t*>(location.data()); 7775b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom dex_file_location_checksum_ = dex_file.GetLocationChecksum(); 77889521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom dex_file_offset_ = 0; 7796e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom methods_offsets_.resize(dex_file.NumClassDefs()); 780e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 781e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 782e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatDexFile::SizeOf() const { 783e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return sizeof(dex_file_location_size_) 784e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + dex_file_location_size_ 7855b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom + sizeof(dex_file_location_checksum_) 78689521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom + sizeof(dex_file_offset_) 7876e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom + (sizeof(methods_offsets_[0]) * methods_offsets_.size()); 788e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 789e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 790e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatDexFile::UpdateChecksum(OatHeader& oat_header) const { 791e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); 792e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(dex_file_location_data_, dex_file_location_size_); 7935b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_)); 79489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom oat_header.UpdateChecksum(&dex_file_offset_, sizeof(dex_file_offset_)); 7956e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom oat_header.UpdateChecksum(&methods_offsets_[0], 7966e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size()); 797e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 798e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 799e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::OatDexFile::Write(File* file) const { 800e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { 801234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location length to " << file->name(); 802e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 803e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 804e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(dex_file_location_data_, dex_file_location_size_)) { 805234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location data to " << file->name(); 806e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 807e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 8085b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom if (!file->WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) { 8095b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom PLOG(ERROR) << "Failed to write dex file location checksum to " << file->name(); 810e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 811e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 81289521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom if (!file->WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) { 81389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom PLOG(ERROR) << "Failed to write dex file offset to " << file->name(); 81489521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom return false; 81589521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom } 8166e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom if (!file->WriteFully(&methods_offsets_[0], 8176e3b1d900cc456a2717944f1f562a2f4df000705Brian Carlstrom sizeof(methods_offsets_[0]) * methods_offsets_.size())) { 818234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write methods offsets to " << file->name(); 819e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 820e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 821e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 822e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 823e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 8240755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromOatWriter::OatClass::OatClass(Class::Status status, uint32_t methods_count) { 8250755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom status_ = status; 826e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom method_offsets_.resize(methods_count); 827e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 828e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 829389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromsize_t OatWriter::OatClass::SizeOf() const { 8300755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return sizeof(status_) 8310755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom + (sizeof(method_offsets_[0]) * method_offsets_.size()); 832e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 833e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 834389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstromvoid OatWriter::OatClass::UpdateChecksum(OatHeader& oat_header) const { 8350755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&status_, sizeof(status_)); 8360755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom oat_header.UpdateChecksum(&method_offsets_[0], 8370755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size()); 838e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 839e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 840389efb00642100fa1c50bd47d1b8267541f9710fBrian Carlstrombool OatWriter::OatClass::Write(File* file) const { 8410755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (!file->WriteFully(&status_, sizeof(status_))) { 8420755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom PLOG(ERROR) << "Failed to write class status to " << file->name(); 8430755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return false; 8440755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 8450755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (!file->WriteFully(&method_offsets_[0], 8460755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom sizeof(method_offsets_[0]) * method_offsets_.size())) { 847234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write method offsets to " << file->name(); 848e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 849e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 850e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 851e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 852e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 853e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 854