diff options
author | Vladimir Marko <vmarko@google.com> | 2015-04-02 19:51:49 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-02 19:51:49 +0000 |
commit | 3795e94a8bd42a1de3a98935f45399f1805a9f6e (patch) | |
tree | 8e87fa800ee73791d70e5c2cad87ea8dc09deab6 | |
parent | 93c65adb3d7bd1d3815715df433d185219045230 (diff) | |
parent | 71b0ddf988208c9f77e7d2c1e75066cc3fe20c61 (diff) | |
download | android_art-3795e94a8bd42a1de3a98935f45399f1805a9f6e.tar.gz android_art-3795e94a8bd42a1de3a98935f45399f1805a9f6e.tar.bz2 android_art-3795e94a8bd42a1de3a98935f45399f1805a9f6e.zip |
Merge "Split RelativePatcher::ReserveSpace() into two."
-rw-r--r-- | compiler/linker/arm/relative_patcher_arm_base.cc | 29 | ||||
-rw-r--r-- | compiler/linker/arm/relative_patcher_arm_base.h | 1 | ||||
-rw-r--r-- | compiler/linker/arm64/relative_patcher_arm64.cc | 25 | ||||
-rw-r--r-- | compiler/linker/arm64/relative_patcher_arm64.h | 1 | ||||
-rw-r--r-- | compiler/linker/relative_patcher.cc | 4 | ||||
-rw-r--r-- | compiler/linker/relative_patcher.h | 6 | ||||
-rw-r--r-- | compiler/linker/relative_patcher_test.h | 2 | ||||
-rw-r--r-- | compiler/linker/x86/relative_patcher_x86_base.cc | 4 | ||||
-rw-r--r-- | compiler/linker/x86/relative_patcher_x86_base.h | 1 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 3 |
10 files changed, 51 insertions, 25 deletions
diff --git a/compiler/linker/arm/relative_patcher_arm_base.cc b/compiler/linker/arm/relative_patcher_arm_base.cc index 2eae2a8001..ceace824ea 100644 --- a/compiler/linker/arm/relative_patcher_arm_base.cc +++ b/compiler/linker/arm/relative_patcher_arm_base.cc @@ -29,6 +29,21 @@ uint32_t ArmBaseRelativePatcher::ReserveSpace(uint32_t offset, return ReserveSpaceInternal(offset, compiled_method, method_ref, 0u); } +uint32_t ArmBaseRelativePatcher::ReserveSpaceEnd(uint32_t offset) { + // NOTE: The final thunk can be reserved from InitCodeMethodVisitor::EndClass() while it + // may be written early by WriteCodeMethodVisitor::VisitMethod() for a deduplicated chunk + // of code. To avoid any alignment discrepancies for the final chunk, we always align the + // offset after reserving of writing any chunk. + uint32_t aligned_offset = CompiledMethod::AlignCode(offset, instruction_set_); + bool needs_thunk = ReserveSpaceProcessPatches(aligned_offset, MethodReference(nullptr, 0u), + aligned_offset); + if (needs_thunk) { + thunk_locations_.push_back(aligned_offset); + offset = CompiledMethod::AlignCode(aligned_offset + thunk_code_.size(), instruction_set_); + } + return offset; +} + uint32_t ArmBaseRelativePatcher::WriteThunks(OutputStream* out, uint32_t offset) { if (current_thunk_to_write_ == thunk_locations_.size()) { return offset; @@ -69,20 +84,6 @@ uint32_t ArmBaseRelativePatcher::ReserveSpaceInternal(uint32_t offset, const CompiledMethod* compiled_method, MethodReference method_ref, uint32_t max_extra_space) { - // NOTE: The final thunk can be reserved from InitCodeMethodVisitor::EndClass() while it - // may be written early by WriteCodeMethodVisitor::VisitMethod() for a deduplicated chunk - // of code. To avoid any alignment discrepancies for the final chunk, we always align the - // offset after reserving of writing any chunk. - if (UNLIKELY(compiled_method == nullptr)) { - uint32_t aligned_offset = CompiledMethod::AlignCode(offset, instruction_set_); - DCHECK(method_ref.dex_file == nullptr && method_ref.dex_method_index == 0u); - bool needs_thunk = ReserveSpaceProcessPatches(aligned_offset, method_ref, aligned_offset); - if (needs_thunk) { - thunk_locations_.push_back(aligned_offset); - offset = CompiledMethod::AlignCode(aligned_offset + thunk_code_.size(), instruction_set_); - } - return offset; - } DCHECK(compiled_method->GetQuickCode() != nullptr); uint32_t quick_code_size = compiled_method->GetQuickCode()->size(); uint32_t quick_code_offset = compiled_method->AlignCode(offset) + sizeof(OatQuickMethodHeader); diff --git a/compiler/linker/arm/relative_patcher_arm_base.h b/compiler/linker/arm/relative_patcher_arm_base.h index 78bc941d2d..f80dd962ce 100644 --- a/compiler/linker/arm/relative_patcher_arm_base.h +++ b/compiler/linker/arm/relative_patcher_arm_base.h @@ -29,6 +29,7 @@ class ArmBaseRelativePatcher : public RelativePatcher { public: uint32_t ReserveSpace(uint32_t offset, const CompiledMethod* compiled_method, MethodReference method_ref) OVERRIDE; + uint32_t ReserveSpaceEnd(uint32_t offset) OVERRIDE; uint32_t WriteThunks(OutputStream* out, uint32_t offset) OVERRIDE; protected: diff --git a/compiler/linker/arm64/relative_patcher_arm64.cc b/compiler/linker/arm64/relative_patcher_arm64.cc index b61b3d8e44..1cbe481321 100644 --- a/compiler/linker/arm64/relative_patcher_arm64.cc +++ b/compiler/linker/arm64/relative_patcher_arm64.cc @@ -58,12 +58,11 @@ uint32_t Arm64RelativePatcher::ReserveSpace(uint32_t offset, // Count the number of ADRP insns as the upper bound on the number of thunks needed // and use it to reserve space for other linker patches. size_t num_adrp = 0u; - if (LIKELY(compiled_method != nullptr)) { - for (const LinkerPatch& patch : compiled_method->GetPatches()) { - if (patch.Type() == kLinkerPatchDexCacheArray && - patch.LiteralOffset() == patch.PcInsnOffset()) { // ADRP patch - ++num_adrp; - } + DCHECK(compiled_method != nullptr); + for (const LinkerPatch& patch : compiled_method->GetPatches()) { + if (patch.Type() == kLinkerPatchDexCacheArray && + patch.LiteralOffset() == patch.PcInsnOffset()) { // ADRP patch + ++num_adrp; } } offset = ReserveSpaceInternal(offset, compiled_method, method_ref, kAdrpThunkSize * num_adrp); @@ -90,6 +89,20 @@ uint32_t Arm64RelativePatcher::ReserveSpace(uint32_t offset, return offset; } +uint32_t Arm64RelativePatcher::ReserveSpaceEnd(uint32_t offset) { + if (!fix_cortex_a53_843419_) { + DCHECK(adrp_thunk_locations_.empty()); + } else { + // Add thunks for the last method if any. + if (reserved_adrp_thunks_ != adrp_thunk_locations_.size()) { + size_t num_adrp_thunks = adrp_thunk_locations_.size() - reserved_adrp_thunks_; + offset = CompiledMethod::AlignCode(offset, kArm64) + kAdrpThunkSize * num_adrp_thunks; + reserved_adrp_thunks_ = adrp_thunk_locations_.size(); + } + } + return ArmBaseRelativePatcher::ReserveSpaceEnd(offset); +} + uint32_t Arm64RelativePatcher::WriteThunks(OutputStream* out, uint32_t offset) { if (fix_cortex_a53_843419_) { if (!current_method_thunks_.empty()) { diff --git a/compiler/linker/arm64/relative_patcher_arm64.h b/compiler/linker/arm64/relative_patcher_arm64.h index b2a1da50d3..2d07e75c85 100644 --- a/compiler/linker/arm64/relative_patcher_arm64.h +++ b/compiler/linker/arm64/relative_patcher_arm64.h @@ -30,6 +30,7 @@ class Arm64RelativePatcher FINAL : public ArmBaseRelativePatcher { uint32_t ReserveSpace(uint32_t offset, const CompiledMethod* compiled_method, MethodReference method_ref) OVERRIDE; + uint32_t ReserveSpaceEnd(uint32_t offset) OVERRIDE; uint32_t WriteThunks(OutputStream* out, uint32_t offset) OVERRIDE; void PatchCall(std::vector<uint8_t>* code, uint32_t literal_offset, uint32_t patch_offset, uint32_t target_offset) OVERRIDE; diff --git a/compiler/linker/relative_patcher.cc b/compiler/linker/relative_patcher.cc index 71f38b408a..8ee87aa339 100644 --- a/compiler/linker/relative_patcher.cc +++ b/compiler/linker/relative_patcher.cc @@ -38,6 +38,10 @@ std::unique_ptr<RelativePatcher> RelativePatcher::Create( return offset; // No space reserved; no patches expected. } + uint32_t ReserveSpaceEnd(uint32_t offset) OVERRIDE { + return offset; // No space reserved; no patches expected. + } + uint32_t WriteThunks(OutputStream* out ATTRIBUTE_UNUSED, uint32_t offset) OVERRIDE { return offset; // No thunks added; no patches expected. } diff --git a/compiler/linker/relative_patcher.h b/compiler/linker/relative_patcher.h index 7a78254787..8a9f3f8364 100644 --- a/compiler/linker/relative_patcher.h +++ b/compiler/linker/relative_patcher.h @@ -82,11 +82,13 @@ class RelativePatcher { return size_misc_thunks_; } - // Reserve space for relative call thunks if needed, return adjusted offset. After all methods - // of a class have been processed it's called one last time with compiled_method == nullptr. + // Reserve space for thunks if needed before a method, return adjusted offset. virtual uint32_t ReserveSpace(uint32_t offset, const CompiledMethod* compiled_method, MethodReference method_ref) = 0; + // Reserve space for thunks if needed after the last method, return adjusted offset. + virtual uint32_t ReserveSpaceEnd(uint32_t offset) = 0; + // Write relative call thunks if needed, return adjusted offset. virtual uint32_t WriteThunks(OutputStream* out, uint32_t offset) = 0; diff --git a/compiler/linker/relative_patcher_test.h b/compiler/linker/relative_patcher_test.h index dede42e71a..08167b3309 100644 --- a/compiler/linker/relative_patcher_test.h +++ b/compiler/linker/relative_patcher_test.h @@ -98,7 +98,7 @@ class RelativePatcherTest : public testing::Test { method_offset_map_.map.Put(compiled_method_refs_[idx], quick_code_offset); ++idx; } - offset = patcher_->ReserveSpace(offset, nullptr, MethodReference(nullptr, 0u)); + offset = patcher_->ReserveSpaceEnd(offset); uint32_t output_size = offset; output_.reserve(output_size); diff --git a/compiler/linker/x86/relative_patcher_x86_base.cc b/compiler/linker/x86/relative_patcher_x86_base.cc index ea3472d232..bc285a7849 100644 --- a/compiler/linker/x86/relative_patcher_x86_base.cc +++ b/compiler/linker/x86/relative_patcher_x86_base.cc @@ -26,6 +26,10 @@ uint32_t X86BaseRelativePatcher::ReserveSpace( return offset; // No space reserved; no limit on relative call distance. } +uint32_t X86BaseRelativePatcher::ReserveSpaceEnd(uint32_t offset) { + return offset; // No space reserved; no limit on relative call distance. +} + uint32_t X86BaseRelativePatcher::WriteThunks(OutputStream* out ATTRIBUTE_UNUSED, uint32_t offset) { return offset; // No thunks added; no limit on relative call distance. } diff --git a/compiler/linker/x86/relative_patcher_x86_base.h b/compiler/linker/x86/relative_patcher_x86_base.h index 1f38cf2996..9200709398 100644 --- a/compiler/linker/x86/relative_patcher_x86_base.h +++ b/compiler/linker/x86/relative_patcher_x86_base.h @@ -27,6 +27,7 @@ class X86BaseRelativePatcher : public RelativePatcher { uint32_t ReserveSpace(uint32_t offset, const CompiledMethod* compiled_method, MethodReference method_ref) OVERRIDE; + uint32_t ReserveSpaceEnd(uint32_t offset) OVERRIDE; uint32_t WriteThunks(OutputStream* out, uint32_t offset) OVERRIDE; void PatchCall(std::vector<uint8_t>* code, uint32_t literal_offset, uint32_t patch_offset, uint32_t target_offset) OVERRIDE; diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 19013cf7a1..7120920773 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -357,8 +357,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { bool EndClass() { OatDexMethodVisitor::EndClass(); if (oat_class_index_ == writer_->oat_classes_.size()) { - offset_ = writer_->relative_patcher_->ReserveSpace(offset_, nullptr, - MethodReference(nullptr, 0u)); + offset_ = writer_->relative_patcher_->ReserveSpaceEnd(offset_); } return true; } |