diff options
Diffstat (limited to 'compiler/oat_writer.cc')
| -rw-r--r-- | compiler/oat_writer.cc | 323 |
1 files changed, 203 insertions, 120 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 40a3f14f93..53ac77b40f 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -31,10 +31,12 @@ #include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" +#include "dwarf/method_debug_info.h" #include "gc/space/image_space.h" #include "gc/space/space.h" #include "handle_scope-inl.h" #include "image_writer.h" +#include "linker/output_stream.h" #include "linker/relative_patcher.h" #include "mirror/array.h" #include "mirror/class_loader.h" @@ -42,7 +44,6 @@ #include "mirror/object-inl.h" #include "oat_quick_method_header.h" #include "os.h" -#include "output_stream.h" #include "safe_map.h" #include "scoped_thread_state_change.h" #include "type_lookup_table.h" @@ -51,6 +52,97 @@ namespace art { +class OatWriter::OatClass { + public: + OatClass(size_t offset, + const dchecked_vector<CompiledMethod*>& compiled_methods, + uint32_t num_non_null_compiled_methods, + mirror::Class::Status status); + OatClass(OatClass&& src) = default; + size_t GetOatMethodOffsetsOffsetFromOatHeader(size_t class_def_method_index_) const; + size_t GetOatMethodOffsetsOffsetFromOatClass(size_t class_def_method_index_) const; + size_t SizeOf() const; + bool Write(OatWriter* oat_writer, OutputStream* out, const size_t file_offset) const; + + CompiledMethod* GetCompiledMethod(size_t class_def_method_index) const { + return compiled_methods_[class_def_method_index]; + } + + // Offset of start of OatClass from beginning of OatHeader. It is + // used to validate file position when writing. + size_t offset_; + + // CompiledMethods for each class_def_method_index, or null if no method is available. + dchecked_vector<CompiledMethod*> compiled_methods_; + + // Offset from OatClass::offset_ to the OatMethodOffsets for the + // class_def_method_index. If 0, it means the corresponding + // CompiledMethod entry in OatClass::compiled_methods_ should be + // null and that the OatClass::type_ should be kOatClassBitmap. + dchecked_vector<uint32_t> oat_method_offsets_offsets_from_oat_class_; + + // Data to write. + + static_assert(mirror::Class::Status::kStatusMax < (1 << 16), "class status won't fit in 16bits"); + int16_t status_; + + static_assert(OatClassType::kOatClassMax < (1 << 16), "oat_class type won't fit in 16bits"); + uint16_t type_; + + uint32_t method_bitmap_size_; + + // bit vector indexed by ClassDef method index. When + // OatClassType::type_ is kOatClassBitmap, a set bit indicates the + // method has an OatMethodOffsets in methods_offsets_, otherwise + // the entry was ommited to save space. If OatClassType::type_ is + // not is kOatClassBitmap, the bitmap will be null. + std::unique_ptr<BitVector> method_bitmap_; + + // OatMethodOffsets and OatMethodHeaders for each CompiledMethod + // present in the OatClass. Note that some may be missing if + // OatClass::compiled_methods_ contains null values (and + // oat_method_offsets_offsets_from_oat_class_ should contain 0 + // values in this case). + dchecked_vector<OatMethodOffsets> method_offsets_; + dchecked_vector<OatQuickMethodHeader> method_headers_; + + private: + size_t GetMethodOffsetsRawSize() const { + return method_offsets_.size() * sizeof(method_offsets_[0]); + } + + DISALLOW_COPY_AND_ASSIGN(OatClass); +}; + +class OatWriter::OatDexFile { + public: + OatDexFile(size_t offset, const DexFile& dex_file); + OatDexFile(OatDexFile&& src) = default; + + size_t SizeOf() const; + bool Write(OatWriter* oat_writer, OutputStream* out, const size_t file_offset) const; + + // Offset of start of OatDexFile from beginning of OatHeader. It is + // used to validate file position when writing. + size_t offset_; + + // Data to write. + uint32_t dex_file_location_size_; + const uint8_t* dex_file_location_data_; + uint32_t dex_file_location_checksum_; + uint32_t dex_file_offset_; + uint32_t lookup_table_offset_; + TypeLookupTable* lookup_table_; // Owned by the dex file. + dchecked_vector<uint32_t> class_offsets_; + + private: + size_t GetClassOffsetsRawSize() const { + return class_offsets_.size() * sizeof(class_offsets_[0]); + } + + DISALLOW_COPY_AND_ASSIGN(OatDexFile); +}; + #define DCHECK_OFFSET() \ DCHECK_EQ(static_cast<off_t>(file_offset + relative_offset), out->Seek(0, kSeekCurrent)) \ << "file_offset=" << file_offset << " relative_offset=" << relative_offset @@ -105,14 +197,14 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, size_oat_dex_file_location_data_(0), size_oat_dex_file_location_checksum_(0), size_oat_dex_file_offset_(0), - size_oat_dex_file_methods_offsets_(0), + size_oat_dex_file_lookup_table_offset_(0), + size_oat_dex_file_class_offsets_(0), + size_oat_lookup_table_alignment_(0), + size_oat_lookup_table_(0), size_oat_class_type_(0), size_oat_class_status_(0), size_oat_class_method_bitmaps_(0), size_oat_class_method_offsets_(0), - size_oat_lookup_table_alignment_(0), - size_oat_lookup_table_offset_(0), - size_oat_lookup_table_(0), method_offset_map_() { CHECK(key_value_store != nullptr); if (compiling_boot_image) { @@ -179,9 +271,6 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, } OatWriter::~OatWriter() { - delete oat_header_; - STLDeleteElements(&oat_dex_files_); - STLDeleteElements(&oat_classes_); } struct OatWriter::GcMapDataAccess { @@ -325,6 +414,11 @@ class OatWriter::InitOatClassesMethodVisitor : public DexMethodVisitor { : DexMethodVisitor(writer, offset), compiled_methods_(), num_non_null_compiled_methods_(0u) { + size_t num_classes = 0u; + for (const OatDexFile& oat_dex_file : writer_->oat_dex_files_) { + num_classes += oat_dex_file.class_offsets_.size(); + } + writer_->oat_classes_.reserve(num_classes); compiled_methods_.reserve(256u); } @@ -363,16 +457,16 @@ class OatWriter::InitOatClassesMethodVisitor : public DexMethodVisitor { status = mirror::Class::kStatusNotReady; } - OatClass* oat_class = new OatClass(offset_, compiled_methods_, - num_non_null_compiled_methods_, status); - writer_->oat_classes_.push_back(oat_class); - oat_class->UpdateChecksum(writer_->oat_header_); - offset_ += oat_class->SizeOf(); + writer_->oat_classes_.emplace_back(offset_, + compiled_methods_, + num_non_null_compiled_methods_, + status); + offset_ += writer_->oat_classes_.back().SizeOf(); return DexMethodVisitor::EndClass(); } private: - std::vector<CompiledMethod*> compiled_methods_; + dchecked_vector<CompiledMethod*> compiled_methods_; size_t num_non_null_compiled_methods_; }; @@ -395,7 +489,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) SHARED_REQUIRES(Locks::mutator_lock_) { - OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; + OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); if (compiled_method != nullptr) { @@ -485,7 +579,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { // Record debug information for this function if we are doing that. const uint32_t quick_code_start = quick_code_offset - writer_->oat_header_->GetExecutableOffset() - thumb_offset; - writer_->method_info_.push_back(DebugInfo { + writer_->method_info_.push_back(dwarf::MethodDebugInfo { dex_file_, class_def_index_, it.GetMemberIndex(), @@ -582,7 +676,7 @@ class OatWriter::InitMapMethodVisitor : public OatDexMethodVisitor { bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it ATTRIBUTE_UNUSED) SHARED_REQUIRES(Locks::mutator_lock_) { - OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; + OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); if (compiled_method != nullptr) { @@ -599,7 +693,6 @@ class OatWriter::InitMapMethodVisitor : public OatDexMethodVisitor { DataAccess::SetOffset(oat_class, method_offsets_index_, offset_); dedupe_map_.PutBefore(lb, map.data(), offset_); offset_ += map_size; - writer_->oat_header_->UpdateChecksum(&map[0], map_size); } } ++method_offsets_index_; @@ -623,7 +716,7 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) SHARED_REQUIRES(Locks::mutator_lock_) { - OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; + OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); OatMethodOffsets offsets(0u); @@ -640,8 +733,12 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { StackHandleScope<1> hs(soa.Self()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache( Thread::Current(), *dex_file_))); - ArtMethod* method = linker->ResolveMethod( - *dex_file_, it.GetMemberIndex(), dex_cache, NullHandle<mirror::ClassLoader>(), nullptr, + ArtMethod* method = linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>( + *dex_file_, + it.GetMemberIndex(), + dex_cache, + ScopedNullHandle<mirror::ClassLoader>(), + nullptr, invoke_type); if (method == nullptr) { LOG(INTERNAL_FATAL) << "Unexpected failure to resolve a method: " @@ -710,7 +807,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) SHARED_REQUIRES(Locks::mutator_lock_) { - OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; + OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; const CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); // No thread suspension since dex_cache_ that may get invalidated if that occurs. @@ -747,8 +844,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { << PrettyMethod(it.GetMemberIndex(), *dex_file_); const OatQuickMethodHeader& method_header = oat_class->method_headers_[method_offsets_index_]; - writer_->oat_header_->UpdateChecksum(&method_header, sizeof(method_header)); - if (!out->WriteFully(&method_header, sizeof(method_header))) { + if (!writer_->WriteData(out, &method_header, sizeof(method_header))) { ReportWriteFailure("method header", it); return false; } @@ -785,8 +881,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { } } - writer_->oat_header_->UpdateChecksum(quick_code.data(), code_size); - if (!out->WriteFully(quick_code.data(), code_size)) { + if (!writer_->WriteData(out, quick_code.data(), code_size)) { ReportWriteFailure("method code", it); return false; } @@ -940,7 +1035,7 @@ class OatWriter::WriteMapMethodVisitor : public OatDexMethodVisitor { } bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) { - OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; + OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; const CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); if (compiled_method != nullptr) { // ie. not an abstract method @@ -958,7 +1053,7 @@ class OatWriter::WriteMapMethodVisitor : public OatDexMethodVisitor { << map_size << " " << map_offset << " " << offset_ << " " << PrettyMethod(it.GetMemberIndex(), *dex_file_) << " for " << DataAccess::Name(); if (map_size != 0u && map_offset == offset_) { - if (UNLIKELY(!out->WriteFully(&map[0], map_size))) { + if (UNLIKELY(!writer_->WriteData(out, map.data(), map_size))) { ReportWriteFailure(it); return false; } @@ -1023,12 +1118,12 @@ bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) { } size_t OatWriter::InitOatHeader() { - oat_header_ = OatHeader::Create(compiler_driver_->GetInstructionSet(), - compiler_driver_->GetInstructionSetFeatures(), - dex_files_, - image_file_location_oat_checksum_, - image_file_location_oat_begin_, - key_value_store_); + oat_header_.reset(OatHeader::Create(compiler_driver_->GetInstructionSet(), + compiler_driver_->GetInstructionSetFeatures(), + dchecked_integral_cast<uint32_t>(dex_files_->size()), + key_value_store_)); + oat_header_->SetImageFileLocationOatChecksum(image_file_location_oat_checksum_); + oat_header_->SetImageFileLocationOatDataBegin(image_file_location_oat_begin_); return oat_header_->GetHeaderSize(); } @@ -1038,9 +1133,8 @@ size_t OatWriter::InitOatDexFiles(size_t offset) { for (size_t i = 0; i != dex_files_->size(); ++i) { const DexFile* dex_file = (*dex_files_)[i]; CHECK(dex_file != nullptr); - OatDexFile* oat_dex_file = new OatDexFile(offset, *dex_file); - oat_dex_files_.push_back(oat_dex_file); - offset += oat_dex_file->SizeOf(); + oat_dex_files_.emplace_back(offset, *dex_file); + offset += oat_dex_files_.back().SizeOf(); } return offset; } @@ -1054,12 +1148,12 @@ size_t OatWriter::InitDexFiles(size_t offset) { size_dex_file_alignment_ += offset - original_offset; // set offset in OatDexFile to DexFile - oat_dex_files_[i]->dex_file_offset_ = offset; + oat_dex_files_[i].dex_file_offset_ = offset; const DexFile* dex_file = (*dex_files_)[i]; // Initialize type lookup table - oat_dex_files_[i]->lookup_table_ = dex_file->GetTypeLookupTable(); + oat_dex_files_[i].lookup_table_ = dex_file->GetTypeLookupTable(); offset += dex_file->GetHeader().file_size_; } @@ -1067,14 +1161,14 @@ size_t OatWriter::InitDexFiles(size_t offset) { } size_t OatWriter::InitLookupTables(size_t offset) { - for (OatDexFile* oat_dex_file : oat_dex_files_) { - if (oat_dex_file->lookup_table_ != nullptr) { + for (OatDexFile& oat_dex_file : oat_dex_files_) { + if (oat_dex_file.lookup_table_ != nullptr) { uint32_t aligned_offset = RoundUp(offset, 4); - oat_dex_file->lookup_table_offset_ = aligned_offset; + oat_dex_file.lookup_table_offset_ = aligned_offset; size_oat_lookup_table_alignment_ += aligned_offset - offset; - offset = aligned_offset + oat_dex_file->lookup_table_->RawDataLength(); + offset = aligned_offset + oat_dex_file.lookup_table_->RawDataLength(); } else { - oat_dex_file->lookup_table_offset_ = 0; + oat_dex_file.lookup_table_offset_ = 0; } } return offset; @@ -1089,13 +1183,12 @@ size_t OatWriter::InitOatClasses(size_t offset) { // Update oat_dex_files_. auto oat_class_it = oat_classes_.begin(); - for (OatDexFile* oat_dex_file : oat_dex_files_) { - for (uint32_t& method_offset : oat_dex_file->methods_offsets_) { + for (OatDexFile& oat_dex_file : oat_dex_files_) { + for (uint32_t& class_offset : oat_dex_file.class_offsets_) { DCHECK(oat_class_it != oat_classes_.end()); - method_offset = (*oat_class_it)->offset_; + class_offset = oat_class_it->offset_; ++oat_class_it; } - oat_dex_file->UpdateChecksum(oat_header_); } CHECK(oat_class_it == oat_classes_.end()); @@ -1179,17 +1272,14 @@ size_t OatWriter::InitOatCodeDexFiles(size_t offset) { } bool OatWriter::WriteRodata(OutputStream* out) { - const off_t raw_file_offset = out->Seek(0, kSeekCurrent); - if (raw_file_offset == (off_t) -1) { - LOG(ERROR) << "Failed to get file offset in " << out->GetLocation(); + if (!GetOatDataOffset(out)) { return false; } - const size_t file_offset = static_cast<size_t>(raw_file_offset); - oat_data_offset_ = file_offset; + const size_t file_offset = oat_data_offset_; // Reserve space for header. It will be written last - after updating the checksum. size_t header_size = oat_header_->GetHeaderSize(); - if (out->Seek(header_size, kSeekCurrent) == (off_t) -1) { + if (out->Seek(header_size, kSeekCurrent) == static_cast<off_t>(-1)) { PLOG(ERROR) << "Failed to reserve space for oat header in " << out->GetLocation(); return false; } @@ -1202,7 +1292,7 @@ bool OatWriter::WriteRodata(OutputStream* out) { } off_t tables_end_offset = out->Seek(0, kSeekCurrent); - if (tables_end_offset == (off_t) -1) { + if (tables_end_offset == static_cast<off_t>(-1)) { LOG(ERROR) << "Failed to seek to oat code position in " << out->GetLocation(); return false; } @@ -1247,7 +1337,7 @@ bool OatWriter::WriteCode(OutputStream* out) { } const off_t oat_end_file_offset = out->Seek(0, kSeekCurrent); - if (oat_end_file_offset == (off_t) -1) { + if (oat_end_file_offset == static_cast<off_t>(-1)) { LOG(ERROR) << "Failed to get oat end file offset in " << out->GetLocation(); return false; } @@ -1283,14 +1373,14 @@ bool OatWriter::WriteCode(OutputStream* out) { DO_STAT(size_oat_dex_file_location_data_); DO_STAT(size_oat_dex_file_location_checksum_); DO_STAT(size_oat_dex_file_offset_); - DO_STAT(size_oat_dex_file_methods_offsets_); + DO_STAT(size_oat_dex_file_lookup_table_offset_); + DO_STAT(size_oat_dex_file_class_offsets_); + DO_STAT(size_oat_lookup_table_alignment_); + DO_STAT(size_oat_lookup_table_); DO_STAT(size_oat_class_type_); DO_STAT(size_oat_class_status_); DO_STAT(size_oat_class_method_bitmaps_); DO_STAT(size_oat_class_method_offsets_); - DO_STAT(size_oat_lookup_table_alignment_); - DO_STAT(size_oat_lookup_table_offset_); - DO_STAT(size_oat_lookup_table_); #undef DO_STAT VLOG(compiler) << "size_total=" << PrettySize(size_total) << " (" << size_total << "B)"; \ @@ -1301,17 +1391,20 @@ bool OatWriter::WriteCode(OutputStream* out) { CHECK_EQ(file_offset + size_, static_cast<size_t>(oat_end_file_offset)); CHECK_EQ(size_, relative_offset); + // Finalize the header checksum. + oat_header_->UpdateChecksumWithHeaderData(); + // Write the header now that the checksum is final. - if (out->Seek(file_offset, kSeekSet) == (off_t) -1) { + if (out->Seek(file_offset, kSeekSet) == static_cast<off_t>(-1)) { PLOG(ERROR) << "Failed to seek to oat header position in " << out->GetLocation(); return false; } DCHECK_EQ(file_offset, static_cast<size_t>(out->Seek(0, kSeekCurrent))); - if (!out->WriteFully(oat_header_, header_size)) { + if (!out->WriteFully(oat_header_.get(), header_size)) { PLOG(ERROR) << "Failed to write oat header to " << out->GetLocation(); return false; } - if (out->Seek(oat_end_file_offset, kSeekSet) == (off_t) -1) { + if (out->Seek(oat_end_file_offset, kSeekSet) == static_cast<off_t>(-1)) { PLOG(ERROR) << "Failed to seek to end after writing oat header to " << out->GetLocation(); return false; } @@ -1322,13 +1415,13 @@ bool OatWriter::WriteCode(OutputStream* out) { bool OatWriter::WriteTables(OutputStream* out, const size_t file_offset) { for (size_t i = 0; i != oat_dex_files_.size(); ++i) { - if (!oat_dex_files_[i]->Write(this, out, file_offset)) { + if (!oat_dex_files_[i].Write(this, out, file_offset)) { PLOG(ERROR) << "Failed to write oat dex information to " << out->GetLocation(); return false; } } for (size_t i = 0; i != oat_dex_files_.size(); ++i) { - uint32_t expected_offset = file_offset + oat_dex_files_[i]->dex_file_offset_; + uint32_t expected_offset = file_offset + oat_dex_files_[i].dex_file_offset_; off_t actual_offset = out->Seek(expected_offset, kSeekSet); if (static_cast<uint32_t>(actual_offset) != expected_offset) { const DexFile* dex_file = (*dex_files_)[i]; @@ -1348,7 +1441,7 @@ bool OatWriter::WriteTables(OutputStream* out, const size_t file_offset) { return false; } for (size_t i = 0; i != oat_classes_.size(); ++i) { - if (!oat_classes_[i]->Write(this, out, file_offset)) { + if (!oat_classes_[i].Write(this, out, file_offset)) { PLOG(ERROR) << "Failed to write oat methods information to " << out->GetLocation(); return false; } @@ -1358,8 +1451,8 @@ bool OatWriter::WriteTables(OutputStream* out, const size_t file_offset) { bool OatWriter::WriteLookupTables(OutputStream* out, const size_t file_offset) { for (size_t i = 0; i < oat_dex_files_.size(); ++i) { - const uint32_t lookup_table_offset = oat_dex_files_[i]->lookup_table_offset_; - const TypeLookupTable* table = oat_dex_files_[i]->lookup_table_; + const uint32_t lookup_table_offset = oat_dex_files_[i].lookup_table_offset_; + const TypeLookupTable* table = oat_dex_files_[i].lookup_table_; DCHECK_EQ(lookup_table_offset == 0, table == nullptr); if (lookup_table_offset == 0) { continue; @@ -1373,7 +1466,7 @@ bool OatWriter::WriteLookupTables(OutputStream* out, const size_t file_offset) { return false; } if (table != nullptr) { - if (!out->WriteFully(table->RawData(), table->RawDataLength())) { + if (!WriteData(out, table->RawData(), table->RawDataLength())) { const DexFile* dex_file = (*dex_files_)[i]; PLOG(ERROR) << "Failed to write lookup table for " << dex_file->GetLocation() << " to " << out->GetLocation(); @@ -1422,7 +1515,7 @@ size_t OatWriter::WriteCode(OutputStream* out, const size_t file_offset, size_t uint32_t alignment_padding = aligned_offset - relative_offset; \ out->Seek(alignment_padding, kSeekCurrent); \ size_trampoline_alignment_ += alignment_padding; \ - if (!out->WriteFully(&(*field)[0], field->size())) { \ + if (!WriteData(out, field->data(), field->size())) { \ PLOG(ERROR) << "Failed to write " # field " to " << out->GetLocation(); \ return false; \ } \ @@ -1464,6 +1557,17 @@ size_t OatWriter::WriteCodeDexFiles(OutputStream* out, return relative_offset; } +bool OatWriter::GetOatDataOffset(OutputStream* out) { + // Get the elf file offset of the oat file. + const off_t raw_file_offset = out->Seek(0, kSeekCurrent); + if (raw_file_offset == static_cast<off_t>(-1)) { + LOG(ERROR) << "Failed to get file offset in " << out->GetLocation(); + return false; + } + oat_data_offset_ = static_cast<size_t>(raw_file_offset); + return true; +} + bool OatWriter::WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta) { static const uint8_t kPadding[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u @@ -1476,6 +1580,11 @@ bool OatWriter::WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delt return true; } +bool OatWriter::WriteData(OutputStream* out, const void* data, size_t size) { + oat_header_->UpdateChecksum(data, size); + return out->WriteFully(data, size); +} + std::pair<bool, uint32_t> OatWriter::MethodOffsetMap::FindMethodOffset(MethodReference ref) { auto it = map.find(ref); if (it == map.end()) { @@ -1493,7 +1602,7 @@ OatWriter::OatDexFile::OatDexFile(size_t offset, const DexFile& dex_file) { dex_file_location_checksum_ = dex_file.GetLocationChecksum(); dex_file_offset_ = 0; lookup_table_offset_ = 0; - methods_offsets_.resize(dex_file.NumClassDefs()); + class_offsets_.resize(dex_file.NumClassDefs()); } size_t OatWriter::OatDexFile::SizeOf() const { @@ -1502,63 +1611,50 @@ size_t OatWriter::OatDexFile::SizeOf() const { + sizeof(dex_file_location_checksum_) + sizeof(dex_file_offset_) + sizeof(lookup_table_offset_) - + (sizeof(methods_offsets_[0]) * methods_offsets_.size()); -} - -void OatWriter::OatDexFile::UpdateChecksum(OatHeader* oat_header) const { - oat_header->UpdateChecksum(&dex_file_location_size_, sizeof(dex_file_location_size_)); - oat_header->UpdateChecksum(dex_file_location_data_, dex_file_location_size_); - oat_header->UpdateChecksum(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_)); - oat_header->UpdateChecksum(&dex_file_offset_, sizeof(dex_file_offset_)); - oat_header->UpdateChecksum(&lookup_table_offset_, sizeof(lookup_table_offset_)); - if (lookup_table_ != nullptr) { - oat_header->UpdateChecksum(lookup_table_->RawData(), lookup_table_->RawDataLength()); - } - oat_header->UpdateChecksum(&methods_offsets_[0], - sizeof(methods_offsets_[0]) * methods_offsets_.size()); + + (sizeof(class_offsets_[0]) * class_offsets_.size()); } bool OatWriter::OatDexFile::Write(OatWriter* oat_writer, OutputStream* out, const size_t file_offset) const { DCHECK_OFFSET_(); - if (!out->WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) { + if (!oat_writer->WriteData(out, &dex_file_location_size_, sizeof(dex_file_location_size_))) { PLOG(ERROR) << "Failed to write dex file location length to " << out->GetLocation(); return false; } oat_writer->size_oat_dex_file_location_size_ += sizeof(dex_file_location_size_); - if (!out->WriteFully(dex_file_location_data_, dex_file_location_size_)) { + if (!oat_writer->WriteData(out, dex_file_location_data_, dex_file_location_size_)) { PLOG(ERROR) << "Failed to write dex file location data to " << out->GetLocation(); return false; } oat_writer->size_oat_dex_file_location_data_ += dex_file_location_size_; - if (!out->WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) { + if (!oat_writer->WriteData(out, + &dex_file_location_checksum_, + sizeof(dex_file_location_checksum_))) { PLOG(ERROR) << "Failed to write dex file location checksum to " << out->GetLocation(); return false; } oat_writer->size_oat_dex_file_location_checksum_ += sizeof(dex_file_location_checksum_); - if (!out->WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) { + if (!oat_writer->WriteData(out, &dex_file_offset_, sizeof(dex_file_offset_))) { PLOG(ERROR) << "Failed to write dex file offset to " << out->GetLocation(); return false; } oat_writer->size_oat_dex_file_offset_ += sizeof(dex_file_offset_); - if (!out->WriteFully(&lookup_table_offset_, sizeof(lookup_table_offset_))) { + if (!oat_writer->WriteData(out, &lookup_table_offset_, sizeof(lookup_table_offset_))) { PLOG(ERROR) << "Failed to write lookup table offset to " << out->GetLocation(); return false; } - oat_writer->size_oat_lookup_table_offset_ += sizeof(lookup_table_offset_); - if (!out->WriteFully(&methods_offsets_[0], - sizeof(methods_offsets_[0]) * methods_offsets_.size())) { + oat_writer->size_oat_dex_file_lookup_table_offset_ += sizeof(lookup_table_offset_); + if (!oat_writer->WriteData(out, class_offsets_.data(), GetClassOffsetsRawSize())) { PLOG(ERROR) << "Failed to write methods offsets to " << out->GetLocation(); return false; } - oat_writer->size_oat_dex_file_methods_offsets_ += - sizeof(methods_offsets_[0]) * methods_offsets_.size(); + oat_writer->size_oat_dex_file_class_offsets_ += GetClassOffsetsRawSize(); return true; } OatWriter::OatClass::OatClass(size_t offset, - const std::vector<CompiledMethod*>& compiled_methods, + const dchecked_vector<CompiledMethod*>& compiled_methods, uint32_t num_non_null_compiled_methods, mirror::Class::Status status) : compiled_methods_(compiled_methods) { @@ -1588,7 +1684,7 @@ OatWriter::OatClass::OatClass(size_t offset, uint32_t oat_method_offsets_offset_from_oat_class = sizeof(type_) + sizeof(status_); if (type_ == kOatClassSomeCompiled) { - method_bitmap_ = new BitVector(num_methods, false, Allocator::GetMallocAllocator()); + method_bitmap_.reset(new BitVector(num_methods, false, Allocator::GetMallocAllocator())); method_bitmap_size_ = method_bitmap_->GetSizeOf(); oat_method_offsets_offset_from_oat_class += sizeof(method_bitmap_size_); oat_method_offsets_offset_from_oat_class += method_bitmap_size_; @@ -1611,10 +1707,6 @@ OatWriter::OatClass::OatClass(size_t offset, } } -OatWriter::OatClass::~OatClass() { - delete method_bitmap_; -} - size_t OatWriter::OatClass::GetOatMethodOffsetsOffsetFromOatHeader( size_t class_def_method_index_) const { uint32_t method_offset = GetOatMethodOffsetsOffsetFromOatClass(class_def_method_index_); @@ -1637,51 +1729,42 @@ size_t OatWriter::OatClass::SizeOf() const { + (sizeof(method_offsets_[0]) * method_offsets_.size()); } -void OatWriter::OatClass::UpdateChecksum(OatHeader* oat_header) const { - oat_header->UpdateChecksum(&status_, sizeof(status_)); - oat_header->UpdateChecksum(&type_, sizeof(type_)); - if (method_bitmap_size_ != 0) { - CHECK_EQ(kOatClassSomeCompiled, type_); - oat_header->UpdateChecksum(&method_bitmap_size_, sizeof(method_bitmap_size_)); - oat_header->UpdateChecksum(method_bitmap_->GetRawStorage(), method_bitmap_size_); - } - oat_header->UpdateChecksum(&method_offsets_[0], - sizeof(method_offsets_[0]) * method_offsets_.size()); -} - bool OatWriter::OatClass::Write(OatWriter* oat_writer, OutputStream* out, const size_t file_offset) const { DCHECK_OFFSET_(); - if (!out->WriteFully(&status_, sizeof(status_))) { + if (!oat_writer->WriteData(out, &status_, sizeof(status_))) { PLOG(ERROR) << "Failed to write class status to " << out->GetLocation(); return false; } oat_writer->size_oat_class_status_ += sizeof(status_); - if (!out->WriteFully(&type_, sizeof(type_))) { + + if (!oat_writer->WriteData(out, &type_, sizeof(type_))) { PLOG(ERROR) << "Failed to write oat class type to " << out->GetLocation(); return false; } oat_writer->size_oat_class_type_ += sizeof(type_); + if (method_bitmap_size_ != 0) { CHECK_EQ(kOatClassSomeCompiled, type_); - if (!out->WriteFully(&method_bitmap_size_, sizeof(method_bitmap_size_))) { + if (!oat_writer->WriteData(out, &method_bitmap_size_, sizeof(method_bitmap_size_))) { PLOG(ERROR) << "Failed to write method bitmap size to " << out->GetLocation(); return false; } oat_writer->size_oat_class_method_bitmaps_ += sizeof(method_bitmap_size_); - if (!out->WriteFully(method_bitmap_->GetRawStorage(), method_bitmap_size_)) { + + if (!oat_writer->WriteData(out, method_bitmap_->GetRawStorage(), method_bitmap_size_)) { PLOG(ERROR) << "Failed to write method bitmap to " << out->GetLocation(); return false; } oat_writer->size_oat_class_method_bitmaps_ += method_bitmap_size_; } - if (!out->WriteFully(&method_offsets_[0], - sizeof(method_offsets_[0]) * method_offsets_.size())) { + + if (!oat_writer->WriteData(out, method_offsets_.data(), GetMethodOffsetsRawSize())) { PLOG(ERROR) << "Failed to write method offsets to " << out->GetLocation(); return false; } - oat_writer->size_oat_class_method_offsets_ += sizeof(method_offsets_[0]) * method_offsets_.size(); + oat_writer->size_oat_class_method_offsets_ += GetMethodOffsetsRawSize(); return true; } |