diff options
-rw-r--r-- | dex2oat/driver/compiler_driver-inl.h | 6 | ||||
-rw-r--r-- | dex2oat/driver/compiler_driver.h | 4 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer.cc | 101 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer.h | 5 | ||||
-rw-r--r-- | dex2oat/utils/atomic_dex_ref_map.h | 11 |
5 files changed, 68 insertions, 59 deletions
diff --git a/dex2oat/driver/compiler_driver-inl.h b/dex2oat/driver/compiler_driver-inl.h index a928b6dd02..e416770f91 100644 --- a/dex2oat/driver/compiler_driver-inl.h +++ b/dex2oat/driver/compiler_driver-inl.h @@ -29,6 +29,7 @@ #include "mirror/dex_cache-inl.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" +#include "utils/atomic_dex_ref_map-inl.h" namespace art { @@ -99,6 +100,11 @@ inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( return std::make_pair(fast_get, fast_put); } +inline const CompilerDriver::CompiledMethodArray* CompilerDriver::GetCompiledMethods( + const DexFile* dex_file) const { + return compiled_methods_.GetArray(dex_file); +} + } // namespace art #endif // ART_DEX2OAT_DRIVER_COMPILER_DRIVER_INL_H_ diff --git a/dex2oat/driver/compiler_driver.h b/dex2oat/driver/compiler_driver.h index db03ab672e..06c81fb7b7 100644 --- a/dex2oat/driver/compiler_driver.h +++ b/dex2oat/driver/compiler_driver.h @@ -135,7 +135,11 @@ class CompilerDriver { ClassStatus GetClassStatus(const ClassReference& ref) const; bool GetCompiledClass(const ClassReference& ref, ClassStatus* status) const; + using CompiledMethodArray = dchecked_vector<Atomic<CompiledMethod*>>; + const CompiledMethodArray* GetCompiledMethods(const DexFile* dex_file) const; + CompiledMethod* GetCompiledMethod(MethodReference ref) const; + // Add a compiled method. void AddCompiledMethod(const MethodReference& method_ref, CompiledMethod* const compiled_method); CompiledMethod* RemoveCompiledMethod(const MethodReference& method_ref); diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 82e7f607ea..20787ddc8f 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -602,6 +602,11 @@ void OatWriter::PrepareLayout(MultiOatRelativePatcher* relative_patcher) { CHECK_EQ(instruction_set, oat_header_->GetInstructionSet()); { + TimingLogger::ScopedTiming split("InitBssAndRelRoData", timings_); + InitBssAndRelRoData(); + } + + { TimingLogger::ScopedTiming split("InitBssLayout", timings_); InitBssLayout(instruction_set); } @@ -732,88 +737,84 @@ static bool HasCompiledCode(const CompiledMethod* method) { return method != nullptr && !method->GetQuickCode().empty(); } -class OatWriter::InitBssLayoutMethodVisitor : public DexMethodVisitor { - public: - explicit InitBssLayoutMethodVisitor(OatWriter* writer) - : DexMethodVisitor(writer, /* offset */ 0u) {} - - bool VisitMethod([[maybe_unused]] size_t class_def_method_index, - const ClassAccessor::Method& method) override { - // Look for patches with .bss references and prepare maps with placeholders for their offsets. - CompiledMethod* compiled_method = writer_->compiler_driver_->GetCompiledMethod( - MethodReference(dex_file_, method.GetIndex())); - if (HasCompiledCode(compiled_method)) { +void OatWriter::InitBssAndRelRoData() { + for (const DexFile* dex_file : *dex_files_) { + const dchecked_vector<Atomic<CompiledMethod*>>* compiled_methods = + compiler_driver_->GetCompiledMethods(dex_file); + if (compiled_methods == nullptr) { + continue; + } + for (const Atomic<CompiledMethod*>& entry : *compiled_methods) { + CompiledMethod* compiled_method = entry.load(std::memory_order_relaxed); + if (compiled_method == nullptr) { + continue; + } + DCHECK_IMPLIES(!compiled_method->GetPatches().empty(), HasCompiledCode(compiled_method)); for (const LinkerPatch& patch : compiled_method->GetPatches()) { if (patch.GetType() == LinkerPatch::Type::kBootImageRelRo) { - writer_->boot_image_rel_ro_entries_.Overwrite(patch.BootImageOffset(), - /* placeholder */ 0u); + boot_image_rel_ro_entries_.Overwrite(patch.BootImageOffset(), /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kMethodAppImageRelRo) { MethodReference target_method = patch.TargetMethod(); - writer_->app_image_rel_ro_method_entries_.Overwrite(target_method, /* placeholder */ 0u); + app_image_rel_ro_method_entries_.Overwrite(target_method, /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kMethodBssEntry) { MethodReference target_method = patch.TargetMethod(); AddBssReference(target_method, target_method.dex_file->NumMethodIds(), - &writer_->bss_method_entry_references_); - writer_->bss_method_entries_.Overwrite(target_method, /* placeholder */ 0u); + &bss_method_entry_references_); + bss_method_entries_.Overwrite(target_method, /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kTypeAppImageRelRo) { - writer_->app_image_rel_ro_type_entries_.Overwrite(patch.TargetType(), - /* placeholder */ 0u); + app_image_rel_ro_type_entries_.Overwrite(patch.TargetType(), /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kTypeBssEntry) { TypeReference target_type = patch.TargetType(); AddBssReference(target_type, target_type.dex_file->NumTypeIds(), - &writer_->bss_type_entry_references_); - writer_->bss_type_entries_.Overwrite(target_type, /* placeholder */ 0u); + &bss_type_entry_references_); + bss_type_entries_.Overwrite(target_type, /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kPublicTypeBssEntry) { TypeReference target_type = patch.TargetType(); AddBssReference(target_type, target_type.dex_file->NumTypeIds(), - &writer_->bss_public_type_entry_references_); - writer_->bss_public_type_entries_.Overwrite(target_type, /* placeholder */ 0u); + &bss_public_type_entry_references_); + bss_public_type_entries_.Overwrite(target_type, /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kPackageTypeBssEntry) { TypeReference target_type = patch.TargetType(); AddBssReference(target_type, target_type.dex_file->NumTypeIds(), - &writer_->bss_package_type_entry_references_); - writer_->bss_package_type_entries_.Overwrite(target_type, /* placeholder */ 0u); + &bss_package_type_entry_references_); + bss_package_type_entries_.Overwrite(target_type, /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kStringBssEntry) { StringReference target_string = patch.TargetString(); AddBssReference(target_string, target_string.dex_file->NumStringIds(), - &writer_->bss_string_entry_references_); - writer_->bss_string_entries_.Overwrite(target_string, /* placeholder */ 0u); + &bss_string_entry_references_); + bss_string_entries_.Overwrite(target_string, /* placeholder */ 0u); } else if (patch.GetType() == LinkerPatch::Type::kMethodTypeBssEntry) { ProtoReference target_proto = patch.TargetProto(); AddBssReference(target_proto, target_proto.dex_file->NumProtoIds(), - &writer_->bss_method_type_entry_references_); - writer_->bss_method_type_entries_.Overwrite(target_proto, /* placeholder */ 0u); + &bss_method_type_entry_references_); + bss_method_type_entries_.Overwrite(target_proto, /* placeholder */ 0u); } } - } else { - DCHECK(compiled_method == nullptr || compiled_method->GetPatches().empty()); } - return true; } +} - private: - void AddBssReference(const DexFileReference& ref, - size_t number_of_indexes, - /*inout*/ SafeMap<const DexFile*, BitVector>* references) { - DCHECK(ContainsElement(*writer_->dex_files_, ref.dex_file) || - ContainsElement(Runtime::Current()->GetClassLinker()->GetBootClassPath(), ref.dex_file)); - DCHECK_LT(ref.index, number_of_indexes); - - auto refs_it = references->find(ref.dex_file); - if (refs_it == references->end()) { - refs_it = references->Put( - ref.dex_file, - BitVector(number_of_indexes, /* expandable */ false, Allocator::GetCallocAllocator())); - } - refs_it->second.SetBit(ref.index); +inline void OatWriter::AddBssReference(const DexFileReference& ref, + size_t number_of_indexes, + /*inout*/ SafeMap<const DexFile*, BitVector>* references) { + DCHECK(ContainsElement(*dex_files_, ref.dex_file) || + ContainsElement(Runtime::Current()->GetClassLinker()->GetBootClassPath(), ref.dex_file)); + DCHECK_LT(ref.index, number_of_indexes); + + auto refs_it = references->find(ref.dex_file); + if (refs_it == references->end()) { + refs_it = references->Put( + ref.dex_file, + BitVector(number_of_indexes, /* expandable */ false, Allocator::GetCallocAllocator())); } -}; + refs_it->second.SetBit(ref.index); +} class OatWriter::InitOatClassesMethodVisitor : public DexMethodVisitor { public: @@ -2432,12 +2433,6 @@ size_t OatWriter::InitDataImgRelRoLayout(size_t offset) { } void OatWriter::InitBssLayout(InstructionSet instruction_set) { - { - InitBssLayoutMethodVisitor visitor(this); - bool success = VisitDexMethods(&visitor); - DCHECK(success); - } - DCHECK_EQ(bss_size_, 0u); if (bss_method_entries_.empty() && bss_type_entries_.empty() && diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h index 5166887963..5a775fa517 100644 --- a/dex2oat/linker/oat_writer.h +++ b/dex2oat/linker/oat_writer.h @@ -261,7 +261,6 @@ class OatWriter { // to actually write it. class DexMethodVisitor; class OatDexMethodVisitor; - class InitBssLayoutMethodVisitor; class InitOatClassesMethodVisitor; class LayoutCodeMethodVisitor; class LayoutReserveOffsetCodeMethodVisitor; @@ -302,7 +301,11 @@ class OatWriter { size_t InitOatCode(size_t offset); size_t InitOatCodeDexFiles(size_t offset); size_t InitDataImgRelRoLayout(size_t offset); + void InitBssAndRelRoData(); void InitBssLayout(InstructionSet instruction_set); + void AddBssReference(const DexFileReference& ref, + size_t number_of_indexes, + /*inout*/ SafeMap<const DexFile*, BitVector>* references); size_t WriteClassOffsets(OutputStream* out, size_t file_offset, size_t relative_offset); size_t WriteClasses(OutputStream* out, size_t file_offset, size_t relative_offset); diff --git a/dex2oat/utils/atomic_dex_ref_map.h b/dex2oat/utils/atomic_dex_ref_map.h index 8f25b8b3ec..59ecd3c504 100644 --- a/dex2oat/utils/atomic_dex_ref_map.h +++ b/dex2oat/utils/atomic_dex_ref_map.h @@ -31,6 +31,9 @@ class DexFile; template <typename DexFileReferenceType, typename Value> class AtomicDexRefMap { public: + // Verified methods. The method array is fixed to avoid needing a lock to extend it. + using ElementArray = dchecked_vector<Atomic<Value>>; + AtomicDexRefMap() {} ~AtomicDexRefMap() {} @@ -68,14 +71,12 @@ class AtomicDexRefMap { void ClearEntries(); - private: - // Verified methods. The method array is fixed to avoid needing a lock to extend it. - using ElementArray = dchecked_vector<Atomic<Value>>; - using DexFileArrays = SafeMap<const DexFile*, ElementArray>; - const ElementArray* GetArray(const DexFile* dex_file) const; ElementArray* GetArray(const DexFile* dex_file); + private: + using DexFileArrays = SafeMap<const DexFile*, ElementArray>; + static size_t NumberOfDexIndices(const DexFile* dex_file); DexFileArrays arrays_; |