diff options
Diffstat (limited to 'compiler/oat_writer.cc')
-rw-r--r-- | compiler/oat_writer.cc | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 2114fe921d..bbc9c3e325 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -155,12 +155,15 @@ struct OatWriter::MappingTableDataAccess { } static uint32_t GetOffset(OatClass* oat_class, size_t method_offsets_index) ALWAYS_INLINE { - return oat_class->method_offsets_[method_offsets_index].mapping_table_offset_; + uint32_t offset = oat_class->method_headers_[method_offsets_index].mapping_table_offset_; + return offset == 0u ? 0u : + (oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset; } static void SetOffset(OatClass* oat_class, size_t method_offsets_index, uint32_t offset) ALWAYS_INLINE { - oat_class->method_offsets_[method_offsets_index].mapping_table_offset_ = offset; + oat_class->method_headers_[method_offsets_index].mapping_table_offset_ = + (oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset; } static const char* Name() ALWAYS_INLINE { @@ -174,12 +177,15 @@ struct OatWriter::VmapTableDataAccess { } static uint32_t GetOffset(OatClass* oat_class, size_t method_offsets_index) ALWAYS_INLINE { - return oat_class->method_offsets_[method_offsets_index].vmap_table_offset_; + uint32_t offset = oat_class->method_headers_[method_offsets_index].vmap_table_offset_; + return offset == 0u ? 0u : + (oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset; } static void SetOffset(OatClass* oat_class, size_t method_offsets_index, uint32_t offset) ALWAYS_INLINE { - oat_class->method_offsets_[method_offsets_index].vmap_table_offset_ = offset; + oat_class->method_headers_[method_offsets_index].vmap_table_offset_ = + (oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset; } static const char* Name() ALWAYS_INLINE { @@ -368,17 +374,22 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { } } + DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size()); + OatMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_]; + method_header->code_size_ = code_size; + // Deduplicate code arrays. - auto code_iter = dedupe_map_.find(quick_code); + auto code_iter = dedupe_map_.find(compiled_method); if (code_iter != dedupe_map_.end()) { quick_code_offset = code_iter->second; + FixupMethodHeader(method_header, quick_code_offset - thumb_offset); } else { - dedupe_map_.Put(quick_code, quick_code_offset); - OatMethodHeader method_header(code_size); - offset_ += sizeof(method_header); // Method header is prepended before code. - writer_->oat_header_->UpdateChecksum(&method_header, sizeof(method_header)); - offset_ += code_size; + dedupe_map_.Put(compiled_method, quick_code_offset); + FixupMethodHeader(method_header, quick_code_offset - thumb_offset); + writer_->oat_header_->UpdateChecksum(method_header, sizeof(*method_header)); + offset_ += sizeof(*method_header); // Method header is prepended before code. writer_->oat_header_->UpdateChecksum(&(*quick_code)[0], code_size); + offset_ += code_size; } } frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); @@ -420,9 +431,22 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { } private: + static void FixupMethodHeader(OatMethodHeader* method_header, uint32_t code_offset) { + // The code offset was 0 when the mapping/vmap table offset was set, so it's set + // to 0-offset and we need to adjust it by code_offset. + if (method_header->mapping_table_offset_ != 0u) { + method_header->mapping_table_offset_ += code_offset; + DCHECK_LT(method_header->mapping_table_offset_, code_offset); + } + if (method_header->vmap_table_offset_ != 0u) { + method_header->vmap_table_offset_ += code_offset; + DCHECK_LT(method_header->vmap_table_offset_, code_offset); + } + } + // Deduplication is already done on a pointer basis by the compiler driver, // so we can simply compare the pointers to find out if things are duplicated. - SafeMap<const std::vector<uint8_t>*, uint32_t> dedupe_map_; + SafeMap<const CompiledMethod*, uint32_t, CodeOffsetsKeyComparator> dedupe_map_; }; template <typename DataAccess> @@ -477,7 +501,7 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { OatClass* oat_class = writer_->oat_classes_[oat_class_index_]; CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); - OatMethodOffsets offsets(0u, kStackAlignment, 0u, 0u, 0u, 0u, 0u); + OatMethodOffsets offsets(0u, kStackAlignment, 0u, 0u, 0u); if (compiled_method != nullptr) { DCHECK_LT(method_offsets_index_, oat_class->method_offsets_.size()); offsets = oat_class->method_offsets_[method_offsets_index_]; @@ -511,8 +535,6 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { offsets.frame_size_in_bytes_ = callee_save_method->GetFrameSizeInBytes() + sirt_size; offsets.core_spill_mask_ = callee_save_method->GetCoreSpillMask(); offsets.fp_spill_mask_ = callee_save_method->GetFpSpillMask(); - DCHECK_EQ(offsets.mapping_table_offset_, 0u); - DCHECK_EQ(offsets.vmap_table_offset_, 0u); DCHECK_EQ(offsets.gc_map_offset_, 0u); } @@ -528,10 +550,8 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { method->SetFrameSizeInBytes(offsets.frame_size_in_bytes_); method->SetCoreSpillMask(offsets.core_spill_mask_); method->SetFpSpillMask(offsets.fp_spill_mask_); - method->SetOatMappingTableOffset(offsets.mapping_table_offset_); // Portable code offsets are set by ElfWriterMclinker::FixupCompiledCodeOffset after linking. method->SetQuickOatCodeOffset(offsets.code_offset_); - method->SetOatVmapTableOffset(offsets.vmap_table_offset_); method->SetOatNativeGcMapOffset(offsets.gc_map_offset_); return true; @@ -584,7 +604,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { offset_ + sizeof(OatMethodHeader) + compiled_method->CodeDelta()) << PrettyMethod(it.GetMemberIndex(), *dex_file_); if (method_offsets.code_offset_ >= offset_) { - OatMethodHeader method_header(code_size); + const OatMethodHeader& method_header = oat_class->method_headers_[method_offsets_index_]; if (!out->WriteFully(&method_header, sizeof(method_header))) { ReportWriteFailure("method header", it); return false; @@ -1153,6 +1173,7 @@ OatWriter::OatClass::OatClass(size_t offset, status_ = status; method_offsets_.resize(num_non_null_compiled_methods); + method_headers_.resize(num_non_null_compiled_methods); uint32_t oat_method_offsets_offset_from_oat_class = sizeof(type_) + sizeof(status_); if (type_ == kOatClassSomeCompiled) { |