oat_writer.cc revision 0571d357843c53e042f370f5f2c2e9aa3fe803a9
1e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom// Copyright 2011 Google Inc. All Rights Reserved. 2e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_writer.h" 4e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 5e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "class_linker.h" 6e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "class_loader.h" 7e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "file.h" 8e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "os.h" 9e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "stl_util.h" 10e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 11e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 12e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 13234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Create(File* file, 143320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const ClassLoader* class_loader, 153320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 16aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const std::vector<const DexFile*>& dex_files = ClassLoader::GetCompileTimeClassPath(class_loader); 173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom OatWriter oat_writer(dex_files, class_loader, compiler); 18234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes return oat_writer.Write(file); 19e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 20e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 213320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, 223320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const ClassLoader* class_loader, 233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const Compiler& compiler) { 243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom compiler_ = &compiler; 25e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_loader_ = class_loader; 26e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_files_ = &dex_files; 270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers oat_header_ = NULL; 280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers executable_offset_padding_length_ = 0; 29e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 30e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t offset = InitOatHeader(); 31e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatDexFiles(offset); 32e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatClasses(offset); 33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatMethods(offset); 34e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCode(offset); 35e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFiles(offset); 36e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 37e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); 38e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(dex_files_->size(), oat_classes_.size()); 39e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 40e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersOatWriter::~OatWriter() { 420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers delete oat_header_; 430571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_dex_files_); 440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_classes_); 450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers STLDeleteElements(&oat_methods_); 460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 48e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatHeader() { 49e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatHeader 50e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header_ = new OatHeader(dex_files_); 51e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t offset = sizeof(*oat_header_); 52e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 53e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatDexFiles(size_t offset) { 56e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatDexFiles 57e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 58e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 59e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 60e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom OatDexFile* oat_dex_file = new OatDexFile(*dex_file); 61e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_.push_back(oat_dex_file); 62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_dex_file->SizeOf(); 63e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 64e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 65e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 66e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatClasses(size_t offset) { 68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatClasses 69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatDexFiles to OatClasses 70e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 71e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // set offset in OatDexFile to OatClasses 72e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_[i]->classes_offset_ = offset; 73e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_dex_files_[i]->UpdateChecksum(*oat_header_); 74e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 75e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 76e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom OatClasses* oat_classes = new OatClasses(*dex_file); 77e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_classes_.push_back(oat_classes); 78e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_classes->SizeOf(); 79e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 80e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 81e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 82e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 83e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatMethods(size_t offset) { 84e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // create the OatMethods 85e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatClasses to OatMethods 86e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t class_index = 0; 87e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 88e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 89e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t class_def_index = 0; 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file->NumClassDefs(); 91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index++, class_index++) { 92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_classes_[i]->methods_offsets_[class_def_index] = offset; 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file->GetClassData(class_def); 950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t num_methods = 0; 960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data != NULL) { // ie not an empty class, such as a marker interface 970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(*dex_file, class_data); 980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_direct_methods = it.NumDirectMethods(); 990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t num_virtual_methods = it.NumVirtualMethods(); 1000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers num_methods = num_direct_methods + num_virtual_methods; 1010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 102e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom OatMethods* oat_methods = new OatMethods(num_methods); 103e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_methods_.push_back(oat_methods); 104e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset += oat_methods->SizeOf(); 105e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 106e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_classes_[i]->UpdateChecksum(*oat_header_); 107e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 108e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 109e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 110e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 111e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCode(size_t offset) { 112e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatHeader to executable code 113e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t old_offset = offset; 114e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // required to be on a new page boundary 115e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = RoundUp(offset, kPageSize); 116e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header_->SetExecutableOffset(offset); 117e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom executable_offset_padding_length_ = offset - old_offset; 118e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 119e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 120e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 121e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFiles(size_t offset) { 122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // calculate the offsets within OatMethods 123e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t oat_class_index = 0; 124e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != dex_files_->size(); ++i) { 125e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 126e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 127e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeDexFile(offset, oat_class_index, *dex_file); 128e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 129e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 130e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 131e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 132e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeDexFile(size_t offset, 133e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t& oat_class_index, 134e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file) { 135e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t class_def_index = 0; 136e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index < dex_file.NumClassDefs(); 137e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_def_index++, oat_class_index++) { 138e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 139e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom offset = InitOatCodeClassDef(offset, oat_class_index, dex_file, class_def); 140e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_methods_[oat_class_index]->UpdateChecksum(*oat_header_); 141e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 142e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 143e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 144e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 145e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::InitOatCodeClassDef(size_t offset, 146e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t oat_class_index, 147e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 148e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 149e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 1510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, such as a marker interface 152387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return offset; 153387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 1540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 155e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_EQ(oat_methods_[oat_class_index]->method_offsets_.size(), 1560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.NumDirectMethods() + it.NumVirtualMethods()); 1570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 1580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 1590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 160e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 1620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 1640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 1650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 1660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 1670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 1680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_method_index, is_static, true, 1690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.GetMemberIndex(), &dex_file); 1700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 1710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 1720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 1740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK_EQ(it.GetMemberAccessFlags() & kAccStatic, 0U); 1750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers offset = InitOatCodeMethod(offset, oat_class_index, class_def_method_index, false, false, 1760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.GetMemberIndex(), &dex_file); 1770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 1780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 1790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 181e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 182e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 183e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, 1850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, bool is_direct, 1860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile* dex_file) { 1873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledMethod if available 1883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t code_offset = 0; 1893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t frame_size_in_bytes = kStackAlignment; 1903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t core_spill_mask = 0; 1913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t fp_spill_mask = 0; 1923320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t mapping_table_offset = 0; 1933320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t vmap_table_offset = 0; 1943320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom // derived from CompiledInvokeStub if available 1953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t invoke_stub_offset = 0; 1963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledMethod* compiled_method = 1980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiler_->GetCompiledMethod(art::Compiler::MethodReference(dex_file, method_idx)); 1993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 2003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom offset = compiled_method->AlignCode(offset); 20106b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(offset, kArmAlignment); 2023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint8_t>& code = compiled_method->GetCode(); 2033320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t code_size = code.size() * sizeof(code[0]); 2043320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t thumb_offset = compiled_method->CodeDelta(); 2053320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom code_offset = (code_size == 0) ? 0 : offset + thumb_offset; 20655d782146917f9afabc98aedcab4b5874a74e55cjeffhao 20755d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate code arrays 208f479dccf294c256181c7ec2884d215424ff5a900jeffhao std::map<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 20955d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (code_iter != code_offsets_.end()) { 21055d782146917f9afabc98aedcab4b5874a74e55cjeffhao code_offset = code_iter->second; 21155d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 212f479dccf294c256181c7ec2884d215424ff5a900jeffhao code_offsets_.insert(std::pair<const std::vector<uint8_t>*, uint32_t>(&code, code_offset)); 21355d782146917f9afabc98aedcab4b5874a74e55cjeffhao offset += code_size; 21455d782146917f9afabc98aedcab4b5874a74e55cjeffhao oat_header_->UpdateChecksum(&code[0], code_size); 21555d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 2163320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); 2183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask = compiled_method->GetCoreSpillMask(); 2193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask = compiled_method->GetFpSpillMask(); 220e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2213320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2223320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom offset += sizeof(frame_size_in_bytes); 2233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom oat_header_->UpdateChecksum(&frame_size_in_bytes, sizeof(frame_size_in_bytes)); 2243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2253320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom offset += sizeof(core_spill_mask); 2263320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom oat_header_->UpdateChecksum(&core_spill_mask, sizeof(core_spill_mask)); 2273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom offset += sizeof(fp_spill_mask); 2293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom oat_header_->UpdateChecksum(&fp_spill_mask, sizeof(fp_spill_mask)); 2303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 2323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 2333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 2343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset = (mapping_table_size == 0) ? 0 : offset; 23555d782146917f9afabc98aedcab4b5874a74e55cjeffhao 23655d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate mapping tables 237f479dccf294c256181c7ec2884d215424ff5a900jeffhao std::map<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table); 23855d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (mapping_iter != mapping_table_offsets_.end()) { 23955d782146917f9afabc98aedcab4b5874a74e55cjeffhao mapping_table_offset = mapping_iter->second; 24055d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 241f479dccf294c256181c7ec2884d215424ff5a900jeffhao mapping_table_offsets_.insert(std::pair<const std::vector<uint32_t>*, uint32_t>(&mapping_table, mapping_table_offset)); 24255d782146917f9afabc98aedcab4b5874a74e55cjeffhao offset += mapping_table_size; 24355d782146917f9afabc98aedcab4b5874a74e55cjeffhao oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size); 24455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 2453320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 2473320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 2483320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset = (vmap_table_size == 0) ? 0 : offset; 24955d782146917f9afabc98aedcab4b5874a74e55cjeffhao 25055d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate vmap tables 251f479dccf294c256181c7ec2884d215424ff5a900jeffhao std::map<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table); 25255d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (vmap_iter != vmap_table_offsets_.end()) { 25355d782146917f9afabc98aedcab4b5874a74e55cjeffhao vmap_table_offset = vmap_iter->second; 25455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 255f479dccf294c256181c7ec2884d215424ff5a900jeffhao vmap_table_offsets_.insert(std::pair<const std::vector<uint16_t>*, uint32_t>(&vmap_table, vmap_table_offset)); 25655d782146917f9afabc98aedcab4b5874a74e55cjeffhao offset += vmap_table_size; 25755d782146917f9afabc98aedcab4b5874a74e55cjeffhao oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size); 25855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 2593320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 2603320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx)); 2620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 2633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 2643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); 26506b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(offset, kArmAlignment); 2663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 2673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 2683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom invoke_stub_offset = (invoke_stub_size == 0) ? 0 : offset; 26955d782146917f9afabc98aedcab4b5874a74e55cjeffhao 27055d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate invoke stubs 271f479dccf294c256181c7ec2884d215424ff5a900jeffhao std::map<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); 27255d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (stub_iter != code_offsets_.end()) { 27355d782146917f9afabc98aedcab4b5874a74e55cjeffhao invoke_stub_offset = stub_iter->second; 27455d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 275f479dccf294c256181c7ec2884d215424ff5a900jeffhao code_offsets_.insert(std::pair<const std::vector<uint8_t>*, uint32_t>(&invoke_stub, invoke_stub_offset)); 27655d782146917f9afabc98aedcab4b5874a74e55cjeffhao offset += invoke_stub_size; 27755d782146917f9afabc98aedcab4b5874a74e55cjeffhao oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); 27855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 2793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 2803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom oat_methods_[oat_class_index]->method_offsets_[class_def_method_index] 2823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom = OatMethodOffsets(code_offset, 2833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom frame_size_in_bytes, 2843320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom core_spill_mask, 2853320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom fp_spill_mask, 2863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom mapping_table_offset, 2873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom vmap_table_offset, 2883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom invoke_stub_offset); 2893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiler_->IsImage()) { 2910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassLinker* linker = Runtime::Current()->GetClassLinker(); 2920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DexCache* dex_cache = linker->FindDexCache(*dex_file); 2930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers Method* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader_, 2940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_direct); 2950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(method != NULL); 2960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFrameSizeInBytes(frame_size_in_bytes); 2970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetCoreSpillMask(core_spill_mask); 2980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetFpSpillMask(fp_spill_mask); 2990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatMappingTableOffset(mapping_table_offset); 3000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatCodeOffset(code_offset); 3010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatVmapTableOffset(vmap_table_offset); 3020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method->SetOatInvokeStubOffset(invoke_stub_offset); 3030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 304e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return offset; 305e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 306e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#define DCHECK_CODE_OFFSET() \ 3083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_EQ(static_cast<off_t>(code_offset), lseek(file->Fd(), 0, SEEK_CUR)) 3093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 310234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughesbool OatWriter::Write(File* file) { 311e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(oat_header_, sizeof(*oat_header_))) { 312234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat header to " << file->name(); 313e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 314e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 315e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 316234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes if (!WriteTables(file)) { 317234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat tables to " << file->name(); 318e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 319e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 320e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 321234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes size_t code_offset = WriteCode(file); 322e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 323234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code to " << file->name(); 324e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 325e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 326e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 327234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes code_offset = WriteCodeDexFiles(file, code_offset); 328e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 329234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(ERROR) << "Failed to write oat code for dex files to " << file->name(); 330e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 331e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 332e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 333e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 334e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 335e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 336e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::WriteTables(File* file) { 337e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_dex_files_.size(); ++i) { 338e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!oat_dex_files_[i]->Write(file)) { 339234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat dex information to " << file->name(); 340e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 341e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 342e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 343e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 344e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!oat_classes_[i]->Write(file)) { 345234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat classes information to " << file->name(); 346e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 347e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 348e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 349e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_methods_.size(); ++i) { 350e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!oat_methods_[i]->Write(file)) { 351234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write oat methods information to " << file->name(); 352e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 353e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 354e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 355e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 356e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 357e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 358e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCode(File* file) { 359e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom uint32_t code_offset = oat_header_->GetExecutableOffset(); 360e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom off_t new_offset = lseek(file->Fd(), executable_offset_padding_length_, SEEK_CUR); 361e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (static_cast<uint32_t>(new_offset) != code_offset) { 3623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to oat code section. Actual: " << new_offset 363234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes << " Expected: " << code_offset << " File: " << file->name(); 364e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 365e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 3663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 367e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 368e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 369e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 370e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeDexFiles(File* file, size_t code_offset) { 3710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t oat_class_index = 0; 372e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom for (size_t i = 0; i != oat_classes_.size(); ++i) { 373e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile* dex_file = (*dex_files_)[i]; 374e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(dex_file != NULL); 3750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeDexFile(file, code_offset, oat_class_index, *dex_file); 376e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 377e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 378e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 379e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 380e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 381e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 382e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeDexFile(File* file, size_t code_offset, size_t& oat_class_index, 3840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file) { 3850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); 3860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_index++, oat_class_index++) { 387e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 3880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeClassDef(file, code_offset, oat_class_index, dex_file, class_def); 389e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 390e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 391e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 392e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 393e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 394e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 395e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid OatWriter::ReportWriteFailure(const char* what, uint32_t method_idx, 3970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file, File* f) const { 3980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers PLOG(ERROR) << "Failed to write " << what << " for " << PrettyMethod(method_idx, dex_file) 3990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << " to " << f->name(); 400234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes} 401234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes 402e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::WriteCodeClassDef(File* file, 4030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t code_offset, size_t oat_class_index, 404e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile& dex_file, 405e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const DexFile::ClassDef& class_def) { 406e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 4070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 4080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // ie. an empty class such as a marker interface 409387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers return code_offset; 410387b699e3dc55309023ae2427a76a1ca1d51b0cdIan Rogers } 4110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 4120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 4130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 4140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 4150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 4170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 4180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 4190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Process methods 4200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index = 0; 4210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 4220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers bool is_static = (it.GetMemberAccessFlags() & kAccStatic) != 0; 4230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 4240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers is_static, it.GetMemberIndex(), dex_file); 425e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 426e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 427e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 4290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 430e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 4320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset = WriteCodeMethod(file, code_offset, oat_class_index, class_def_method_index, 4330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers false, it.GetMemberIndex(), dex_file); 434e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (code_offset == 0) { 435e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return 0; 436e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4370571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers class_def_method_index++; 4380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 439e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 440e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 441e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 442e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 4430571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogerssize_t OatWriter::WriteCodeMethod(File* file, size_t code_offset, size_t oat_class_index, 4440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers size_t class_def_method_index, bool is_static, 4450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx, const DexFile& dex_file) { 4460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledMethod* compiled_method = 4470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiler_->GetCompiledMethod(art::Compiler::MethodReference(&dex_file, method_idx)); 4480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 4490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t frame_size_in_bytes = 0; 4500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t core_spill_mask = 0; 4510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t fp_spill_mask = 0; 4520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 4530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers OatMethodOffsets method_offsets = 4540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers oat_methods_[oat_class_index]->method_offsets_[class_def_method_index]; 4550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 4560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 4570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_method != NULL) { // ie. not an abstract method 4583320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset); 459e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom uint32_t aligned_code_delta = aligned_code_offset - code_offset; 460e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (aligned_code_delta != 0) { 461e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 462e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 4633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset 464234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes << " Expected: " << aligned_code_offset << " File: " << file->name(); 465e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 466e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 467e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom code_offset += aligned_code_delta; 4683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 469e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 47006b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(code_offset, kArmAlignment); 4713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint8_t>& code = compiled_method->GetCode(); 4723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t code_size = code.size() * sizeof(code[0]); 47355d782146917f9afabc98aedcab4b5874a74e55cjeffhao 47455d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate code arrays 47555d782146917f9afabc98aedcab4b5874a74e55cjeffhao size_t offset = code_offset + compiled_method->CodeDelta(); 476f479dccf294c256181c7ec2884d215424ff5a900jeffhao std::map<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code); 4770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) { 4780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((code_size == 0 && method_offsets.code_offset_ == 0) 4790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || code_iter->second == method_offsets.code_offset_) 4800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 48155d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 4820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((code_size == 0 && method_offsets.code_offset_ == 0) 4830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || offset == method_offsets.code_offset_) 4840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 48555d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (!file->WriteFully(&code[0], code_size)) { 4860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("method code", method_idx, dex_file, file); 48755d782146917f9afabc98aedcab4b5874a74e55cjeffhao return false; 48855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 48955d782146917f9afabc98aedcab4b5874a74e55cjeffhao code_offset += code_size; 490e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 4913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 4920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); 4930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers core_spill_mask = compiled_method->GetCoreSpillMask(); 4940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers fp_spill_mask = compiled_method->GetFpSpillMask(); 4953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 4963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (!file->WriteFully(&frame_size_in_bytes, sizeof(frame_size_in_bytes))) { 4980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("method frame size", method_idx, dex_file, file); 4993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return false; 5003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom code_offset += sizeof(frame_size_in_bytes); 5023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (!file->WriteFully(&core_spill_mask, sizeof(core_spill_mask))) { 5030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("method core spill mask", method_idx, dex_file, file); 5043320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return false; 5053320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5063320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom code_offset += sizeof(core_spill_mask); 5073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (!file->WriteFully(&fp_spill_mask, sizeof(fp_spill_mask))) { 5080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("method fp spill mask", method_idx, dex_file, file); 5093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return false; 5103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom code_offset += sizeof(fp_spill_mask); 5123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 5133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_method != NULL) { 5143320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable(); 5153320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]); 51655d782146917f9afabc98aedcab4b5874a74e55cjeffhao 51755d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate mapping tables 5180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::map<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = 5190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers mapping_table_offsets_.find(&mapping_table); 5200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (mapping_iter != mapping_table_offsets_.end() && 5210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset != method_offsets.mapping_table_offset_) { 5220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 5230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || mapping_iter->second == method_offsets.mapping_table_offset_) 5240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 52555d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 5260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0) 5270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || code_offset == method_offsets.mapping_table_offset_) 5280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 52955d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (!file->WriteFully(&mapping_table[0], mapping_table_size)) { 5300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("mapping table", method_idx, dex_file, file); 53155d782146917f9afabc98aedcab4b5874a74e55cjeffhao return false; 53255d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 53355d782146917f9afabc98aedcab4b5874a74e55cjeffhao code_offset += mapping_table_size; 5343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 5363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 5373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable(); 5383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]); 53955d782146917f9afabc98aedcab4b5874a74e55cjeffhao 54055d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate vmap tables 5410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::map<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = 5420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers vmap_table_offsets_.find(&vmap_table); 5430571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (vmap_iter != vmap_table_offsets_.end() && 5440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset != method_offsets.vmap_table_offset_) { 5450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 5460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || vmap_iter->second == method_offsets.vmap_table_offset_) 5470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 54855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 5490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0) 5500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || code_offset == method_offsets.vmap_table_offset_) 5510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 55255d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (!file->WriteFully(&vmap_table[0], vmap_table_size)) { 5530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("vmap table", method_idx, dex_file, file); 55455d782146917f9afabc98aedcab4b5874a74e55cjeffhao return false; 55555d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 55655d782146917f9afabc98aedcab4b5874a74e55cjeffhao code_offset += vmap_table_size; 5573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5583320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 559e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 5600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 5610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); 5623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (compiled_invoke_stub != NULL) { 5633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset, 5643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom compiler_->GetInstructionSet()); 5653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom uint32_t aligned_code_delta = aligned_code_offset - code_offset; 5663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (aligned_code_delta != 0) { 5673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR); 5683320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (static_cast<uint32_t>(new_offset) != aligned_code_offset) { 5693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset 5703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom << " Expected: " << aligned_code_offset; 5713320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return false; 5723320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom code_offset += aligned_code_delta; 5743320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 5753320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 57606b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(code_offset, kArmAlignment); 5773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); 5783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom size_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); 57955d782146917f9afabc98aedcab4b5874a74e55cjeffhao 58055d782146917f9afabc98aedcab4b5874a74e55cjeffhao // Deduplicate invoke stubs 5810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::map<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = 5820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offsets_.find(&invoke_stub); 5830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (stub_iter != code_offsets_.end() && 5840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers code_offset != method_offsets.invoke_stub_offset_) { 5850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((invoke_stub_size == 0 && method_offsets.invoke_stub_offset_ == 0) 5860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || stub_iter->second == method_offsets.invoke_stub_offset_) 5870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 58855d782146917f9afabc98aedcab4b5874a74e55cjeffhao } else { 5890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK((invoke_stub_size == 0 && method_offsets.invoke_stub_offset_ == 0) 5900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers || code_offset == method_offsets.invoke_stub_offset_) 5910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers << PrettyMethod(method_idx, dex_file); 59255d782146917f9afabc98aedcab4b5874a74e55cjeffhao if (!file->WriteFully(&invoke_stub[0], invoke_stub_size)) { 5930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ReportWriteFailure("invoke stub code", method_idx, dex_file, file); 59455d782146917f9afabc98aedcab4b5874a74e55cjeffhao return false; 59555d782146917f9afabc98aedcab4b5874a74e55cjeffhao } 59655d782146917f9afabc98aedcab4b5874a74e55cjeffhao code_offset += invoke_stub_size; 5973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5983320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK_CODE_OFFSET(); 5993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 600e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return code_offset; 601e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 602e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 603e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatDexFile::OatDexFile(const DexFile& dex_file) { 604e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const std::string& location = dex_file.GetLocation(); 605e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_size_ = location.size(); 606e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_location_data_ = reinterpret_cast<const uint8_t*>(location.data()); 607e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_checksum_ = dex_file.GetHeader().checksum_; 6080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers classes_offset_ = 0; 609e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 610e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 611e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatDexFile::SizeOf() const { 612e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return sizeof(dex_file_location_size_) 613e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + dex_file_location_size_ 614e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + sizeof(dex_file_checksum_) 615e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom + sizeof(classes_offset_); 616e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 617e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 618e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatDexFile::UpdateChecksum(OatHeader& oat_header) const { 619e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); 620e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(dex_file_location_data_, dex_file_location_size_); 621e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&dex_file_checksum_, sizeof(dex_file_checksum_)); 622e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&classes_offset_, sizeof(classes_offset_)); 623e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 624e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 625e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::OatDexFile::Write(File* file) const { 626e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { 627234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location length to " << file->name(); 628e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 629e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 630e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(dex_file_location_data_, dex_file_location_size_)) { 631234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file location data to " << file->name(); 632e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 633e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 634e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&dex_file_checksum_, sizeof(dex_file_checksum_))) { 635234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write dex file checksum to " << file->name(); 636e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 637e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 638e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&classes_offset_, sizeof(classes_offset_))) { 639234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write classes offset to " << file->name(); 640e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 641e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 642e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 643e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 644e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 645e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatClasses::OatClasses(const DexFile& dex_file) { 646e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom methods_offsets_.resize(dex_file.NumClassDefs()); 647e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 648e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 649e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatClasses::SizeOf() const { 650e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return (sizeof(methods_offsets_[0]) * methods_offsets_.size()); 651e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 652e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 653e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatClasses::UpdateChecksum(OatHeader& oat_header) const { 654e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&methods_offsets_[0], SizeOf()); 655e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 656e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 657e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::OatClasses::Write(File* file) const { 658e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&methods_offsets_[0], SizeOf())) { 659234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write methods offsets to " << file->name(); 660e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 661e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 662e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 663e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 664e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 665e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromOatWriter::OatMethods::OatMethods(uint32_t methods_count) { 666e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom method_offsets_.resize(methods_count); 667e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 668e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 669e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromsize_t OatWriter::OatMethods::SizeOf() const { 670e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return (sizeof(method_offsets_[0]) * method_offsets_.size()); 671e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 672e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 673e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatWriter::OatMethods::UpdateChecksum(OatHeader& oat_header) const { 674e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_header.UpdateChecksum(&method_offsets_[0], SizeOf()); 675e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 676e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 677e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatWriter::OatMethods::Write(File* file) const { 678e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!file->WriteFully(&method_offsets_[0], SizeOf())) { 679234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes PLOG(ERROR) << "Failed to write method offsets to " << file->name(); 680e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 681e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 682e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 683e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 684e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 685e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 686