From 48886c2ee655a16224870fee52dc8721a52babcf Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Fri, 6 Jan 2017 11:45:47 +0000 Subject: Remove HLoadClass::LoadKind::kDexCachePcRelative. Test: m test-art-host Test: m test-art-target-run-test-552-checker-sharpening Bug: 30627598 Change-Id: Ic809b0f3a8ed0bd4dc7ab67aa64866f9cdff9bdb --- compiler/optimizing/nodes.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'compiler/optimizing/nodes.cc') diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index a6084ebcbb..e1411f6685 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2459,7 +2459,7 @@ bool HLoadClass::InstructionDataEquals(const HInstruction* other) const { case LoadKind::kJitTableAddress: return AsMirrorInternal(GetAddress()) == AsMirrorInternal(other_load_class->GetAddress()); default: - DCHECK(HasTypeReference(GetLoadKind()) || HasDexCacheReference(GetLoadKind())); + DCHECK(HasTypeReference(GetLoadKind())); return IsSameDexFile(GetDexFile(), other_load_class->GetDexFile()); } } @@ -2492,8 +2492,6 @@ std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs) { return os << "BootImageAddress"; case HLoadClass::LoadKind::kJitTableAddress: return os << "JitTableAddress"; - case HLoadClass::LoadKind::kDexCachePcRelative: - return os << "DexCachePcRelative"; case HLoadClass::LoadKind::kDexCacheViaMethod: return os << "DexCacheViaMethod"; default: -- cgit v1.2.3-59-g8ed1b From 6bec91c7d4670905cd67440991ec76fd54d0f000 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Mon, 9 Jan 2017 15:03:12 +0000 Subject: Store resolved types for AOT code in .bss. Test: m test-art-host Test: m test-art-target on Nexus 9. Test: Nexus 9 boots. Test: Build aosp_mips64-eng. Bug: 30627598 Bug: 34193123 Change-Id: I8ec60a98eb488cb46ae3ea56341f5709dad4f623 --- compiler/compiled_method.h | 21 +++++- compiler/linker/arm64/relative_patcher_arm64.cc | 1 + compiler/oat_writer.cc | 20 ++++++ compiler/oat_writer.h | 6 ++ compiler/optimizing/code_generator_arm.cc | 69 +++++++++++++----- compiler/optimizing/code_generator_arm.h | 5 +- compiler/optimizing/code_generator_arm64.cc | 84 ++++++++++++++++------ compiler/optimizing/code_generator_arm64.h | 4 +- compiler/optimizing/code_generator_arm_vixl.cc | 58 ++++++++++----- compiler/optimizing/code_generator_arm_vixl.h | 5 +- compiler/optimizing/code_generator_mips.cc | 77 +++++++++++++------- compiler/optimizing/code_generator_mips.h | 5 +- compiler/optimizing/code_generator_mips64.cc | 63 +++++++++++----- compiler/optimizing/code_generator_mips64.h | 5 +- compiler/optimizing/code_generator_x86.cc | 73 +++++++++++++------ compiler/optimizing/code_generator_x86.h | 3 +- compiler/optimizing/code_generator_x86_64.cc | 54 ++++++++++---- compiler/optimizing/code_generator_x86_64.h | 3 +- compiler/optimizing/nodes.cc | 6 +- compiler/optimizing/nodes.h | 31 +++++--- compiler/optimizing/pc_relative_fixups_mips.cc | 3 +- compiler/optimizing/pc_relative_fixups_x86.cc | 3 +- compiler/optimizing/sharpening.cc | 18 ++--- runtime/class_linker.cc | 1 + runtime/entrypoints/entrypoint_utils-inl.h | 5 -- runtime/entrypoints/entrypoint_utils.cc | 39 ++++++++-- runtime/entrypoints/entrypoint_utils.h | 8 ++- .../quick/quick_dexcache_entrypoints.cc | 68 ++++++++++++------ test/552-checker-sharpening/src/Main.java | 30 ++++---- test/Android.run-test.mk | 8 ++- 30 files changed, 557 insertions(+), 219 deletions(-) (limited to 'compiler/optimizing/nodes.cc') diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h index bbf9eee0e5..e2a0942724 100644 --- a/compiler/compiled_method.h +++ b/compiler/compiled_method.h @@ -176,6 +176,7 @@ class LinkerPatch { kCallRelative, // NOTE: Actual patching is instruction_set-dependent. kType, kTypeRelative, // NOTE: Actual patching is instruction_set-dependent. + kTypeBssEntry, // NOTE: Actual patching is instruction_set-dependent. kString, kStringRelative, // NOTE: Actual patching is instruction_set-dependent. kStringBssEntry, // NOTE: Actual patching is instruction_set-dependent. @@ -228,6 +229,16 @@ class LinkerPatch { return patch; } + static LinkerPatch TypeBssEntryPatch(size_t literal_offset, + const DexFile* target_dex_file, + uint32_t pc_insn_offset, + uint32_t target_type_idx) { + LinkerPatch patch(literal_offset, Type::kTypeBssEntry, target_dex_file); + patch.type_idx_ = target_type_idx; + patch.pc_insn_offset_ = pc_insn_offset; + return patch; + } + static LinkerPatch StringPatch(size_t literal_offset, const DexFile* target_dex_file, uint32_t target_string_idx) { @@ -282,6 +293,7 @@ class LinkerPatch { switch (GetType()) { case Type::kCallRelative: case Type::kTypeRelative: + case Type::kTypeBssEntry: case Type::kStringRelative: case Type::kStringBssEntry: case Type::kDexCacheArray: @@ -299,12 +311,16 @@ class LinkerPatch { } const DexFile* TargetTypeDexFile() const { - DCHECK(patch_type_ == Type::kType || patch_type_ == Type::kTypeRelative); + DCHECK(patch_type_ == Type::kType || + patch_type_ == Type::kTypeRelative || + patch_type_ == Type::kTypeBssEntry); return target_dex_file_; } dex::TypeIndex TargetTypeIndex() const { - DCHECK(patch_type_ == Type::kType || patch_type_ == Type::kTypeRelative); + DCHECK(patch_type_ == Type::kType || + patch_type_ == Type::kTypeRelative || + patch_type_ == Type::kTypeBssEntry); return dex::TypeIndex(type_idx_); } @@ -334,6 +350,7 @@ class LinkerPatch { uint32_t PcInsnOffset() const { DCHECK(patch_type_ == Type::kTypeRelative || + patch_type_ == Type::kTypeBssEntry || patch_type_ == Type::kStringRelative || patch_type_ == Type::kStringBssEntry || patch_type_ == Type::kDexCacheArray); diff --git a/compiler/linker/arm64/relative_patcher_arm64.cc b/compiler/linker/arm64/relative_patcher_arm64.cc index 4a9de7f3d1..79e1785e91 100644 --- a/compiler/linker/arm64/relative_patcher_arm64.cc +++ b/compiler/linker/arm64/relative_patcher_arm64.cc @@ -224,6 +224,7 @@ void Arm64RelativePatcher::PatchPcRelativeReference(std::vector* code, } else { // LDR/STR 32-bit or 64-bit with imm12 == 0 (unset). DCHECK(patch.GetType() == LinkerPatch::Type::kDexCacheArray || + patch.GetType() == LinkerPatch::Type::kTypeBssEntry || patch.GetType() == LinkerPatch::Type::kStringBssEntry) << patch.GetType(); DCHECK_EQ(insn & 0xbfbffc00, 0xb9000000) << std::hex << insn; } diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index a9da09c82c..8f5684b4d0 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -296,6 +296,7 @@ OatWriter::OatWriter(bool compiling_boot_image, TimingLogger* timings, ProfileCo bss_start_(0u), bss_size_(0u), bss_roots_offset_(0u), + bss_type_entries_(), bss_string_entries_(), oat_data_offset_(0u), oat_header_(nullptr), @@ -847,6 +848,10 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { if (!patch.IsPcRelative()) { writer_->absolute_patch_locations_.push_back(base_loc + patch.LiteralOffset()); } + if (patch.GetType() == LinkerPatch::Type::kTypeBssEntry) { + TypeReference ref(patch.TargetTypeDexFile(), patch.TargetTypeIndex()); + writer_->bss_type_entries_.Overwrite(ref, /* placeholder */ 0u); + } if (patch.GetType() == LinkerPatch::Type::kStringBssEntry) { StringReference ref(patch.TargetStringDexFile(), patch.TargetStringIndex()); writer_->bss_string_entries_.Overwrite(ref, /* placeholder */ 0u); @@ -1185,6 +1190,15 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { target_offset); break; } + case LinkerPatch::Type::kTypeBssEntry: { + TypeReference ref(patch.TargetTypeDexFile(), patch.TargetTypeIndex()); + uint32_t target_offset = writer_->bss_type_entries_.Get(ref); + writer_->relative_patcher_->PatchPcRelativeReference(&patched_code_, + patch, + offset_ + literal_offset, + target_offset); + break; + } case LinkerPatch::Type::kCall: { uint32_t target_offset = GetTargetOffset(patch); PatchCodeAddress(&patched_code_, literal_offset, target_offset); @@ -1633,6 +1647,12 @@ void OatWriter::InitBssLayout(InstructionSet instruction_set) { bss_roots_offset_ = bss_size_; + // Prepare offsets for .bss Class entries. + for (auto& entry : bss_type_entries_) { + DCHECK_EQ(entry.second, 0u); + entry.second = bss_start_ + bss_size_; + bss_size_ += sizeof(GcRoot); + } // Prepare offsets for .bss String entries. for (auto& entry : bss_string_entries_) { DCHECK_EQ(entry.second, 0u); diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h index 8d087f4f91..db84166ad3 100644 --- a/compiler/oat_writer.h +++ b/compiler/oat_writer.h @@ -31,6 +31,7 @@ #include "os.h" #include "safe_map.h" #include "string_reference.h" +#include "utils/type_reference.h" namespace art { @@ -372,6 +373,11 @@ class OatWriter { // The offset of the GC roots in .bss section. size_t bss_roots_offset_; + // Map for allocating Class entries in .bss. Indexed by TypeReference for the source + // type in the dex file with the "type value comparator" for deduplication. The value + // is the target offset for patching, starting at `bss_start_ + bss_roots_offset_`. + SafeMap bss_type_entries_; + // Map for allocating String entries in .bss. Indexed by StringReference for the source // string in the dex file with the "string value comparator" for deduplication. The value // is the target offset for patching, starting at `bss_start_ + bss_roots_offset_`. diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 6c9e83e8f7..80ebaa4f59 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -371,22 +371,23 @@ class LoadClassSlowPathARM : public SlowPathCodeARM { HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCodeARM(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCodeARM(at), cls_(cls), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { - LocationSummary* locations = at_->GetLocations(); + LocationSummary* locations = instruction_->GetLocations(); CodeGeneratorARM* arm_codegen = down_cast(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ LoadImmediate(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); + dex::TypeIndex type_index = cls_->GetTypeIndex(); + __ LoadImmediate(calling_convention.GetRegisterAt(0), type_index.index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; - arm_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); + arm_codegen->InvokeRuntime(entrypoint, instruction_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes(); } else { @@ -400,6 +401,23 @@ class LoadClassSlowPathARM : public SlowPathCodeARM { arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0)); } RestoreLiveRegisters(codegen, locations); + // For HLoadClass/kBssEntry, store the resolved Class to the BSS entry. + DCHECK_EQ(instruction_->IsLoadClass(), cls_ == instruction_); + if (cls_ == instruction_ && cls_->GetLoadKind() == HLoadClass::LoadKind::kBssEntry) { + DCHECK(out.IsValid()); + // TODO: Change art_quick_initialize_type/art_quick_initialize_static_storage to + // kSaveEverything and use a temporary for the .bss entry address in the fast path, + // so that we can avoid another calculation here. + CodeGeneratorARM::PcRelativePatchInfo* labels = + arm_codegen->NewPcRelativeTypePatch(cls_->GetDexFile(), type_index); + __ BindTrackedLabel(&labels->movw_label); + __ movw(IP, /* placeholder */ 0u); + __ BindTrackedLabel(&labels->movt_label); + __ movt(IP, /* placeholder */ 0u); + __ BindTrackedLabel(&labels->add_pc_label); + __ add(IP, IP, ShifterOperand(PC)); + __ str(locations->Out().AsRegister(), Address(IP)); + } __ b(GetExitLabel()); } @@ -409,10 +427,6 @@ class LoadClassSlowPathARM : public SlowPathCodeARM { // The class this slow path will load. HLoadClass* const cls_; - // The instruction where this slow path is happening. - // (Might be the load class or an initialization check). - HInstruction* const at_; - // The dex PC of `at_`. const uint32_t dex_pc_; @@ -430,7 +444,7 @@ class LoadStringSlowPathARM : public SlowPathCodeARM { LocationSummary* locations = instruction_->GetLocations(); DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(locations->Out().reg())); HLoadString* load = instruction_->AsLoadString(); - const uint32_t string_index = load->GetStringIndex().index_; + const dex::StringIndex string_index = load->GetStringIndex(); Register out = locations->Out().AsRegister(); Register temp = locations->GetTemp(0).AsRegister(); constexpr bool call_saves_everything_except_r0 = (!kUseReadBarrier || kUseBakerReadBarrier); @@ -449,7 +463,7 @@ class LoadStringSlowPathARM : public SlowPathCodeARM { __ mov(entry_address, ShifterOperand(temp)); } - __ LoadImmediate(calling_convention.GetRegisterAt(0), string_index); + __ LoadImmediate(calling_convention.GetRegisterAt(0), string_index.index_); arm_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes(); @@ -5716,7 +5730,11 @@ HLoadClass::LoadKind CodeGeneratorARM::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; + case HLoadClass::LoadKind::kBssEntry: + DCHECK(!Runtime::Current()->UseJitCompilation()); + break; case HLoadClass::LoadKind::kJitTableAddress: + DCHECK(Runtime::Current()->UseJitCompilation()); break; case HLoadClass::LoadKind::kDexCacheViaMethod: break; @@ -5781,12 +5799,14 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { break; } case HLoadClass::LoadKind::kBootImageLinkTimeAddress: { + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); DCHECK_EQ(read_barrier_option, kWithoutReadBarrier); __ LoadLiteral(out, codegen_->DeduplicateBootImageTypeLiteral(cls->GetDexFile(), cls->GetTypeIndex())); break; } case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: { + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); DCHECK_EQ(read_barrier_option, kWithoutReadBarrier); CodeGeneratorARM::PcRelativePatchInfo* labels = codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); @@ -5805,6 +5825,20 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { __ LoadLiteral(out, codegen_->DeduplicateBootImageAddressLiteral(address)); break; } + case HLoadClass::LoadKind::kBssEntry: { + DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); + CodeGeneratorARM::PcRelativePatchInfo* labels = + codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); + __ BindTrackedLabel(&labels->movw_label); + __ movw(out, /* placeholder */ 0u); + __ BindTrackedLabel(&labels->movt_label); + __ movt(out, /* placeholder */ 0u); + __ BindTrackedLabel(&labels->add_pc_label); + __ add(out, out, ShifterOperand(PC)); + GenerateGcRootFieldLoad(cls, out_loc, out, 0, kCompilerReadBarrierOption); + generate_null_check = true; + break; + } case HLoadClass::LoadKind::kJitTableAddress: { __ LoadLiteral(out, codegen_->DeduplicateJitClassLiteral(cls->GetDexFile(), cls->GetTypeIndex(), @@ -5923,6 +5957,7 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) NO_THREAD_S switch (load_kind) { case HLoadString::LoadKind::kBootImageLinkTimeAddress: { + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); __ LoadLiteral(out, codegen_->DeduplicateBootImageStringLiteral(load->GetDexFile(), load->GetStringIndex())); return; // No dex cache slow path. @@ -5930,7 +5965,7 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) NO_THREAD_S case HLoadString::LoadKind::kBootImageLinkTimePcRelative: { DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorARM::PcRelativePatchInfo* labels = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); __ BindTrackedLabel(&labels->movw_label); __ movw(out, /* placeholder */ 0u); __ BindTrackedLabel(&labels->movt_label); @@ -5950,7 +5985,7 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) NO_THREAD_S DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); Register temp = locations->GetTemp(0).AsRegister(); CodeGeneratorARM::PcRelativePatchInfo* labels = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); __ BindTrackedLabel(&labels->movw_label); __ movw(temp, /* placeholder */ 0u); __ BindTrackedLabel(&labels->movt_label); @@ -7256,8 +7291,8 @@ void CodeGeneratorARM::GenerateVirtualCall(HInvokeVirtual* invoke, Location temp } CodeGeneratorARM::PcRelativePatchInfo* CodeGeneratorARM::NewPcRelativeStringPatch( - const DexFile& dex_file, uint32_t string_index) { - return NewPcRelativePatch(dex_file, string_index, &pc_relative_string_patches_); + const DexFile& dex_file, dex::StringIndex string_index) { + return NewPcRelativePatch(dex_file, string_index.index_, &pc_relative_string_patches_); } CodeGeneratorARM::PcRelativePatchInfo* CodeGeneratorARM::NewPcRelativeTypePatch( @@ -7357,9 +7392,13 @@ void CodeGeneratorARM::EmitLinkerPatches(ArenaVector* linker_patche target_string.string_index.index_)); } if (!GetCompilerOptions().IsBootImage()) { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } else { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } @@ -7372,8 +7411,6 @@ void CodeGeneratorARM::EmitLinkerPatches(ArenaVector* linker_patche target_type.dex_file, target_type.type_index.index_)); } - EmitPcRelativeLinkerPatches(pc_relative_type_patches_, - linker_patches); for (const auto& entry : boot_image_address_patches_) { DCHECK(GetCompilerOptions().GetIncludePatchInformation()); Literal* literal = entry.second; diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index d5968e0764..1fff55eeef 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -481,7 +481,8 @@ class CodeGeneratorARM : public CodeGenerator { Label add_pc_label; }; - PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, uint32_t string_index); + PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, + dex::StringIndex string_index); PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index); PcRelativePatchInfo* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); @@ -635,7 +636,7 @@ class CodeGeneratorARM : public CodeGenerator { ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. TypeToLiteralMap boot_image_type_patches_; - // PC-relative type patch info. + // PC-relative type patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. Uint32ToLiteralMap boot_image_address_patches_; diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 8c4503d2d0..6b1180bb13 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -276,22 +276,23 @@ class LoadClassSlowPathARM64 : public SlowPathCodeARM64 { HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCodeARM64(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCodeARM64(at), cls_(cls), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { - LocationSummary* locations = at_->GetLocations(); + LocationSummary* locations = instruction_->GetLocations(); CodeGeneratorARM64* arm64_codegen = down_cast(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ Mov(calling_convention.GetRegisterAt(0).W(), cls_->GetTypeIndex().index_); + dex::TypeIndex type_index = cls_->GetTypeIndex(); + __ Mov(calling_convention.GetRegisterAt(0).W(), type_index.index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; - arm64_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); + arm64_codegen->InvokeRuntime(entrypoint, instruction_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes(); } else { @@ -302,11 +303,32 @@ class LoadClassSlowPathARM64 : public SlowPathCodeARM64 { Location out = locations->Out(); if (out.IsValid()) { DCHECK(out.IsRegister() && !locations->GetLiveRegisters()->ContainsCoreRegister(out.reg())); - Primitive::Type type = at_->GetType(); + Primitive::Type type = instruction_->GetType(); arm64_codegen->MoveLocation(out, calling_convention.GetReturnLocation(type), type); } - RestoreLiveRegisters(codegen, locations); + // For HLoadClass/kBssEntry, store the resolved Class to the BSS entry. + DCHECK_EQ(instruction_->IsLoadClass(), cls_ == instruction_); + if (cls_ == instruction_ && cls_->GetLoadKind() == HLoadClass::LoadKind::kBssEntry) { + DCHECK(out.IsValid()); + UseScratchRegisterScope temps(arm64_codegen->GetVIXLAssembler()); + Register temp = temps.AcquireX(); + const DexFile& dex_file = cls_->GetDexFile(); + // TODO: Change art_quick_initialize_type/art_quick_initialize_static_storage to + // kSaveEverything and use a temporary for the ADRP in the fast path, so that we + // can avoid the ADRP here. + vixl::aarch64::Label* adrp_label = + arm64_codegen->NewPcRelativeTypePatch(dex_file, type_index); + arm64_codegen->EmitAdrpPlaceholder(adrp_label, temp); + vixl::aarch64::Label* strp_label = + arm64_codegen->NewPcRelativeTypePatch(dex_file, type_index, adrp_label); + { + SingleEmissionCheckScope guard(arm64_codegen->GetVIXLAssembler()); + __ Bind(strp_label); + __ str(RegisterFrom(locations->Out(), Primitive::kPrimNot), + MemOperand(temp, /* offset placeholder */ 0)); + } + } __ B(GetExitLabel()); } @@ -316,10 +338,6 @@ class LoadClassSlowPathARM64 : public SlowPathCodeARM64 { // The class this slow path will load. HLoadClass* const cls_; - // The instruction where this slow path is happening. - // (Might be the load class or an initialization check). - HInstruction* const at_; - // The dex PC of `at_`. const uint32_t dex_pc_; @@ -349,8 +367,8 @@ class LoadStringSlowPathARM64 : public SlowPathCodeARM64 { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex().index_; - __ Mov(calling_convention.GetRegisterAt(0).W(), string_index); + const dex::StringIndex string_index = instruction_->AsLoadString()->GetStringIndex(); + __ Mov(calling_convention.GetRegisterAt(0).W(), string_index.index_); arm64_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes(); Primitive::Type type = instruction_->GetType(); @@ -4090,9 +4108,10 @@ void InstructionCodeGeneratorARM64::VisitInvokePolymorphic(HInvokePolymorphic* i vixl::aarch64::Label* CodeGeneratorARM64::NewPcRelativeStringPatch( const DexFile& dex_file, - uint32_t string_index, + dex::StringIndex string_index, vixl::aarch64::Label* adrp_label) { - return NewPcRelativePatch(dex_file, string_index, adrp_label, &pc_relative_string_patches_); + return + NewPcRelativePatch(dex_file, string_index.index_, adrp_label, &pc_relative_string_patches_); } vixl::aarch64::Label* CodeGeneratorARM64::NewPcRelativeTypePatch( @@ -4224,9 +4243,13 @@ void CodeGeneratorARM64::EmitLinkerPatches(ArenaVector* linker_patc target_string.string_index.index_)); } if (!GetCompilerOptions().IsBootImage()) { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } else { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } @@ -4237,8 +4260,6 @@ void CodeGeneratorARM64::EmitLinkerPatches(ArenaVector* linker_patc target_type.dex_file, target_type.type_index.index_)); } - EmitPcRelativeLinkerPatches(pc_relative_type_patches_, - linker_patches); for (const auto& entry : boot_image_address_patches_) { DCHECK(GetCompilerOptions().GetIncludePatchInformation()); vixl::aarch64::Literal* literal = entry.second; @@ -4306,6 +4327,9 @@ HLoadClass::LoadKind CodeGeneratorARM64::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; + case HLoadClass::LoadKind::kBssEntry: + DCHECK(!Runtime::Current()->UseJitCompilation()); + break; case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); break; @@ -4395,6 +4419,26 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) { __ Ldr(out.W(), codegen_->DeduplicateBootImageAddressLiteral(cls->GetAddress())); break; } + case HLoadClass::LoadKind::kBssEntry: { + // Add ADRP with its PC-relative Class .bss entry patch. + const DexFile& dex_file = cls->GetDexFile(); + dex::TypeIndex type_index = cls->GetTypeIndex(); + DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); + vixl::aarch64::Label* adrp_label = codegen_->NewPcRelativeTypePatch(dex_file, type_index); + codegen_->EmitAdrpPlaceholder(adrp_label, out.X()); + // Add LDR with its PC-relative Class patch. + vixl::aarch64::Label* ldr_label = + codegen_->NewPcRelativeTypePatch(dex_file, type_index, adrp_label); + // /* GcRoot */ out = *(base_address + offset) /* PC-relative */ + GenerateGcRootFieldLoad(cls, + cls->GetLocations()->Out(), + out.X(), + /* placeholder */ 0u, + ldr_label, + kCompilerReadBarrierOption); + generate_null_check = true; + break; + } case HLoadClass::LoadKind::kJitTableAddress: { __ Ldr(out, codegen_->DeduplicateJitClassLiteral(cls->GetDexFile(), cls->GetTypeIndex(), @@ -4464,11 +4508,11 @@ HLoadString::LoadKind CodeGeneratorARM64::GetSupportedLoadStringKind( case HLoadString::LoadKind::kBssEntry: DCHECK(!Runtime::Current()->UseJitCompilation()); break; - case HLoadString::LoadKind::kDexCacheViaMethod: - break; case HLoadString::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); break; + case HLoadString::LoadKind::kDexCacheViaMethod: + break; } return desired_string_load_kind; } @@ -4512,7 +4556,7 @@ void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) NO_THREAD case HLoadString::LoadKind::kBootImageLinkTimePcRelative: { // Add ADRP with its PC-relative String patch. const DexFile& dex_file = load->GetDexFile(); - uint32_t string_index = load->GetStringIndex().index_; + const dex::StringIndex string_index = load->GetStringIndex(); DCHECK(codegen_->GetCompilerOptions().IsBootImage()); vixl::aarch64::Label* adrp_label = codegen_->NewPcRelativeStringPatch(dex_file, string_index); codegen_->EmitAdrpPlaceholder(adrp_label, out.X()); @@ -4532,7 +4576,7 @@ void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) NO_THREAD case HLoadString::LoadKind::kBssEntry: { // Add ADRP with its PC-relative String .bss entry patch. const DexFile& dex_file = load->GetDexFile(); - uint32_t string_index = load->GetStringIndex().index_; + const dex::StringIndex string_index = load->GetStringIndex(); DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); UseScratchRegisterScope temps(codegen_->GetVIXLAssembler()); Register temp = temps.AcquireX(); diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index d6a5f9d1fa..cb5ff4e1b8 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -540,7 +540,7 @@ class CodeGeneratorARM64 : public CodeGenerator { // ADRP (pass `adrp_label = null`) or the ADD (pass `adrp_label` pointing // to the associated ADRP patch label). vixl::aarch64::Label* NewPcRelativeStringPatch(const DexFile& dex_file, - uint32_t string_index, + dex::StringIndex string_index, vixl::aarch64::Label* adrp_label = nullptr); // Add a new PC-relative type patch for an instruction and return the label @@ -744,7 +744,7 @@ class CodeGeneratorARM64 : public CodeGenerator { ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. TypeToLiteralMap boot_image_type_patches_; - // PC-relative type patch info. + // PC-relative type patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. Uint32ToLiteralMap boot_image_address_patches_; diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 877c698f0f..93fe1f2611 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -394,22 +394,23 @@ class BoundsCheckSlowPathARMVIXL : public SlowPathCodeARMVIXL { class LoadClassSlowPathARMVIXL : public SlowPathCodeARMVIXL { public: LoadClassSlowPathARMVIXL(HLoadClass* cls, HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCodeARMVIXL(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCodeARMVIXL(at), cls_(cls), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { - LocationSummary* locations = at_->GetLocations(); + LocationSummary* locations = instruction_->GetLocations(); CodeGeneratorARMVIXL* arm_codegen = down_cast(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConventionARMVIXL calling_convention; - __ Mov(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); + dex::TypeIndex type_index = cls_->GetTypeIndex(); + __ Mov(calling_convention.GetRegisterAt(0), type_index.index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; - arm_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); + arm_codegen->InvokeRuntime(entrypoint, instruction_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes(); } else { @@ -423,6 +424,18 @@ class LoadClassSlowPathARMVIXL : public SlowPathCodeARMVIXL { arm_codegen->Move32(locations->Out(), LocationFrom(r0)); } RestoreLiveRegisters(codegen, locations); + // For HLoadClass/kBssEntry, store the resolved Class to the BSS entry. + DCHECK_EQ(instruction_->IsLoadClass(), cls_ == instruction_); + if (cls_ == instruction_ && cls_->GetLoadKind() == HLoadClass::LoadKind::kBssEntry) { + DCHECK(out.IsValid()); + // TODO: Change art_quick_initialize_type/art_quick_initialize_static_storage to + // kSaveEverything and use a temporary for the .bss entry address in the fast path, + // so that we can avoid another calculation here. + CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = + arm_codegen->NewPcRelativeTypePatch(cls_->GetDexFile(), type_index); + arm_codegen->EmitMovwMovtPlaceholder(labels, ip); + __ Str(OutputRegister(cls_), MemOperand(ip)); + } __ B(GetExitLabel()); } @@ -432,10 +445,6 @@ class LoadClassSlowPathARMVIXL : public SlowPathCodeARMVIXL { // The class this slow path will load. HLoadClass* const cls_; - // The instruction where this slow path is happening. - // (Might be the load class or an initialization check). - HInstruction* const at_; - // The dex PC of `at_`. const uint32_t dex_pc_; @@ -454,7 +463,7 @@ class LoadStringSlowPathARMVIXL : public SlowPathCodeARMVIXL { LocationSummary* locations = instruction_->GetLocations(); DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(locations->Out().reg())); HLoadString* load = instruction_->AsLoadString(); - const uint32_t string_index = load->GetStringIndex().index_; + const dex::StringIndex string_index = load->GetStringIndex(); vixl32::Register out = OutputRegister(load); vixl32::Register temp = RegisterFrom(locations->GetTemp(0)); constexpr bool call_saves_everything_except_r0 = (!kUseReadBarrier || kUseBakerReadBarrier); @@ -473,7 +482,7 @@ class LoadStringSlowPathARMVIXL : public SlowPathCodeARMVIXL { __ Mov(entry_address, temp); } - __ Mov(calling_convention.GetRegisterAt(0), string_index); + __ Mov(calling_convention.GetRegisterAt(0), string_index.index_); arm_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes(); @@ -5797,7 +5806,11 @@ HLoadClass::LoadKind CodeGeneratorARMVIXL::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; + case HLoadClass::LoadKind::kBssEntry: + DCHECK(!Runtime::Current()->UseJitCompilation()); + break; case HLoadClass::LoadKind::kJitTableAddress: + DCHECK(Runtime::Current()->UseJitCompilation()); break; case HLoadClass::LoadKind::kDexCacheViaMethod: break; @@ -5862,12 +5875,14 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) { break; } case HLoadClass::LoadKind::kBootImageLinkTimeAddress: { + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); DCHECK_EQ(read_barrier_option, kWithoutReadBarrier); __ Ldr(out, codegen_->DeduplicateBootImageTypeLiteral(cls->GetDexFile(), cls->GetTypeIndex())); break; } case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: { + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); DCHECK_EQ(read_barrier_option, kWithoutReadBarrier); CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); @@ -5881,6 +5896,15 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) { __ Ldr(out, codegen_->DeduplicateBootImageAddressLiteral(address)); break; } + case HLoadClass::LoadKind::kBssEntry: { + DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); + CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = + codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); + codegen_->EmitMovwMovtPlaceholder(labels, out); + GenerateGcRootFieldLoad(cls, out_loc, out, 0, kCompilerReadBarrierOption); + generate_null_check = true; + break; + } case HLoadClass::LoadKind::kJitTableAddress: { __ Ldr(out, codegen_->DeduplicateJitClassLiteral(cls->GetDexFile(), cls->GetTypeIndex(), @@ -6013,7 +6037,7 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) NO_THRE case HLoadString::LoadKind::kBootImageLinkTimePcRelative: { DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); codegen_->EmitMovwMovtPlaceholder(labels, out); return; // No dex cache slow path. } @@ -6028,7 +6052,7 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) NO_THRE DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); vixl32::Register temp = RegisterFrom(locations->GetTemp(0)); CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); codegen_->EmitMovwMovtPlaceholder(labels, temp); GenerateGcRootFieldLoad(load, out_loc, temp, /* offset */ 0, kCompilerReadBarrierOption); LoadStringSlowPathARMVIXL* slow_path = @@ -7372,8 +7396,8 @@ void CodeGeneratorARMVIXL::GenerateVirtualCall(HInvokeVirtual* invoke, Location } CodeGeneratorARMVIXL::PcRelativePatchInfo* CodeGeneratorARMVIXL::NewPcRelativeStringPatch( - const DexFile& dex_file, uint32_t string_index) { - return NewPcRelativePatch(dex_file, string_index, &pc_relative_string_patches_); + const DexFile& dex_file, dex::StringIndex string_index) { + return NewPcRelativePatch(dex_file, string_index.index_, &pc_relative_string_patches_); } CodeGeneratorARMVIXL::PcRelativePatchInfo* CodeGeneratorARMVIXL::NewPcRelativeTypePatch( @@ -7488,9 +7512,13 @@ void CodeGeneratorARMVIXL::EmitLinkerPatches(ArenaVector* linker_pa target_string.string_index.index_)); } if (!GetCompilerOptions().IsBootImage()) { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } else { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } @@ -7503,8 +7531,6 @@ void CodeGeneratorARMVIXL::EmitLinkerPatches(ArenaVector* linker_pa target_type.dex_file, target_type.type_index.index_)); } - EmitPcRelativeLinkerPatches(pc_relative_type_patches_, - linker_patches); for (const auto& entry : boot_image_address_patches_) { DCHECK(GetCompilerOptions().GetIncludePatchInformation()); VIXLUInt32Literal* literal = entry.second; diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index 200a463c75..0a4f709b65 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -562,7 +562,8 @@ class CodeGeneratorARMVIXL : public CodeGenerator { vixl::aarch32::Label add_pc_label; }; - PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, uint32_t string_index); + PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, + dex::StringIndex string_index); PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index); PcRelativePatchInfo* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); @@ -731,7 +732,7 @@ class CodeGeneratorARMVIXL : public CodeGenerator { ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. TypeToLiteralMap boot_image_type_patches_; - // PC-relative type patch info. + // PC-relative type patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. Uint32ToLiteralMap boot_image_address_patches_; diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 8498b739ed..725e02bd9f 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -213,23 +213,24 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS { HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCodeMIPS(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCodeMIPS(at), cls_(cls), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { - LocationSummary* locations = at_->GetLocations(); + LocationSummary* locations = instruction_->GetLocations(); CodeGeneratorMIPS* mips_codegen = down_cast(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); + dex::TypeIndex type_index = cls_->GetTypeIndex(); + __ LoadConst32(calling_convention.GetRegisterAt(0), type_index.index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; - mips_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); + mips_codegen->InvokeRuntime(entrypoint, instruction_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes(); } else { @@ -240,11 +241,26 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS { Location out = locations->Out(); if (out.IsValid()) { DCHECK(out.IsRegister() && !locations->GetLiveRegisters()->ContainsCoreRegister(out.reg())); - Primitive::Type type = at_->GetType(); + Primitive::Type type = instruction_->GetType(); mips_codegen->MoveLocation(out, calling_convention.GetReturnLocation(type), type); } RestoreLiveRegisters(codegen, locations); + // For HLoadClass/kBssEntry, store the resolved Class to the BSS entry. + DCHECK_EQ(instruction_->IsLoadClass(), cls_ == instruction_); + if (cls_ == instruction_ && cls_->GetLoadKind() == HLoadClass::LoadKind::kBssEntry) { + DCHECK(out.IsValid()); + // TODO: Change art_quick_initialize_type/art_quick_initialize_static_storage to + // kSaveEverything and use a temporary for the .bss entry address in the fast path, + // so that we can avoid another calculation here. + bool isR6 = mips_codegen->GetInstructionSetFeatures().IsR6(); + Register base = isR6 ? ZERO : locations->InAt(0).AsRegister(); + DCHECK_NE(out.AsRegister(), AT); + CodeGeneratorMIPS::PcRelativePatchInfo* info = + mips_codegen->NewPcRelativeTypePatch(cls_->GetDexFile(), type_index); + mips_codegen->EmitPcRelativeAddressPlaceholder(info, TMP, base); + __ StoreToOffset(kStoreWord, out.AsRegister(), TMP, 0); + } __ B(GetExitLabel()); } @@ -254,10 +270,6 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS { // The class this slow path will load. HLoadClass* const cls_; - // The instruction where this slow path is happening. - // (Might be the load class or an initialization check). - HInstruction* const at_; - // The dex PC of `at_`. const uint32_t dex_pc_; @@ -281,8 +293,8 @@ class LoadStringSlowPathMIPS : public SlowPathCodeMIPS { InvokeRuntimeCallingConvention calling_convention; HLoadString* load = instruction_->AsLoadString(); - const uint32_t string_index = load->GetStringIndex().index_; - __ LoadConst32(calling_convention.GetRegisterAt(0), string_index); + const dex::StringIndex string_index = load->GetStringIndex(); + __ LoadConst32(calling_convention.GetRegisterAt(0), string_index.index_); mips_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes(); Primitive::Type type = instruction_->GetType(); @@ -1014,14 +1026,16 @@ void CodeGeneratorMIPS::EmitLinkerPatches(ArenaVector* linker_patch EmitPcRelativeLinkerPatches(pc_relative_dex_cache_patches_, linker_patches); if (!GetCompilerOptions().IsBootImage()) { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } else { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } - EmitPcRelativeLinkerPatches(pc_relative_type_patches_, - linker_patches); for (const auto& entry : boot_image_string_patches_) { const StringReference& target_string = entry.first; Literal* literal = entry.second; @@ -1050,8 +1064,8 @@ void CodeGeneratorMIPS::EmitLinkerPatches(ArenaVector* linker_patch } CodeGeneratorMIPS::PcRelativePatchInfo* CodeGeneratorMIPS::NewPcRelativeStringPatch( - const DexFile& dex_file, uint32_t string_index) { - return NewPcRelativePatch(dex_file, string_index, &pc_relative_string_patches_); + const DexFile& dex_file, dex::StringIndex string_index) { + return NewPcRelativePatch(dex_file, string_index.index_, &pc_relative_string_patches_); } CodeGeneratorMIPS::PcRelativePatchInfo* CodeGeneratorMIPS::NewPcRelativeTypePatch( @@ -5194,14 +5208,14 @@ HLoadString::LoadKind CodeGeneratorMIPS::GetSupportedLoadStringKind( case HLoadString::LoadKind::kBssEntry: DCHECK(!Runtime::Current()->UseJitCompilation()); break; - case HLoadString::LoadKind::kDexCacheViaMethod: - fallback_load = false; - break; case HLoadString::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); // TODO: implement. fallback_load = true; break; + case HLoadString::LoadKind::kDexCacheViaMethod: + fallback_load = false; + break; } if (fallback_load) { desired_string_load_kind = HLoadString::LoadKind::kDexCacheViaMethod; @@ -5230,6 +5244,9 @@ HLoadClass::LoadKind CodeGeneratorMIPS::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; + case HLoadClass::LoadKind::kBssEntry: + DCHECK(!Runtime::Current()->UseJitCompilation()); + break; case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); fallback_load = true; @@ -5448,8 +5465,9 @@ void LocationsBuilderMIPS::VisitLoadClass(HLoadClass* cls) { switch (load_kind) { // We need an extra register for PC-relative literals on R2. case HLoadClass::LoadKind::kBootImageLinkTimeAddress: - case HLoadClass::LoadKind::kBootImageAddress: case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: + case HLoadClass::LoadKind::kBootImageAddress: + case HLoadClass::LoadKind::kBssEntry: if (codegen_->GetInstructionSetFeatures().IsR6()) { break; } @@ -5479,8 +5497,9 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { switch (load_kind) { // We need an extra register for PC-relative literals on R2. case HLoadClass::LoadKind::kBootImageLinkTimeAddress: - case HLoadClass::LoadKind::kBootImageAddress: case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: + case HLoadClass::LoadKind::kBootImageAddress: + case HLoadClass::LoadKind::kBssEntry: base_or_current_method_reg = isR6 ? ZERO : locations->InAt(0).AsRegister(); break; case HLoadClass::LoadKind::kReferrersClass: @@ -5505,14 +5524,14 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { break; } case HLoadClass::LoadKind::kBootImageLinkTimeAddress: - DCHECK(!kEmitCompilerReadBarrier); + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); __ LoadLiteral(out, base_or_current_method_reg, codegen_->DeduplicateBootImageTypeLiteral(cls->GetDexFile(), cls->GetTypeIndex())); break; case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: { - DCHECK(!kEmitCompilerReadBarrier); + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS::PcRelativePatchInfo* info = codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); @@ -5527,6 +5546,15 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { codegen_->DeduplicateBootImageAddressLiteral(address)); break; } + case HLoadClass::LoadKind::kBssEntry: { + DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); + CodeGeneratorMIPS::PcRelativePatchInfo* info = + codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); + codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); + __ LoadFromOffset(kLoadWord, out, out, 0); + generate_null_check = true; + break; + } case HLoadClass::LoadKind::kJitTableAddress: { LOG(FATAL) << "Unimplemented"; break; @@ -5628,6 +5656,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_ switch (load_kind) { case HLoadString::LoadKind::kBootImageLinkTimeAddress: + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); __ LoadLiteral(out, base_or_current_method_reg, codegen_->DeduplicateBootImageStringLiteral(load->GetDexFile(), @@ -5636,7 +5665,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_ case HLoadString::LoadKind::kBootImageLinkTimePcRelative: { DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS::PcRelativePatchInfo* info = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); return; // No dex cache slow path. } @@ -5652,7 +5681,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_ case HLoadString::LoadKind::kBssEntry: { DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS::PcRelativePatchInfo* info = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); __ LoadFromOffset(kLoadWord, out, out, 0); SlowPathCodeMIPS* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathMIPS(load); diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h index 7b0812cb7b..bc0772c7de 100644 --- a/compiler/optimizing/code_generator_mips.h +++ b/compiler/optimizing/code_generator_mips.h @@ -452,7 +452,8 @@ class CodeGeneratorMIPS : public CodeGenerator { MipsLabel pc_rel_label; }; - PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, uint32_t string_index); + PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, + dex::StringIndex string_index); PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index); PcRelativePatchInfo* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); @@ -504,7 +505,7 @@ class CodeGeneratorMIPS : public CodeGenerator { ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. BootTypeToLiteralMap boot_image_type_patches_; - // PC-relative type patch info. + // PC-relative type patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. Uint32ToLiteralMap boot_image_address_patches_; diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 4d8f7ec49d..a929d6a145 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -167,22 +167,23 @@ class LoadClassSlowPathMIPS64 : public SlowPathCodeMIPS64 { HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCodeMIPS64(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCodeMIPS64(at), cls_(cls), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { - LocationSummary* locations = at_->GetLocations(); + LocationSummary* locations = instruction_->GetLocations(); CodeGeneratorMIPS64* mips64_codegen = down_cast(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex().index_); + dex::TypeIndex type_index = cls_->GetTypeIndex(); + __ LoadConst32(calling_convention.GetRegisterAt(0), type_index.index_); QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType; - mips64_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); + mips64_codegen->InvokeRuntime(entrypoint, instruction_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes(); } else { @@ -193,11 +194,24 @@ class LoadClassSlowPathMIPS64 : public SlowPathCodeMIPS64 { Location out = locations->Out(); if (out.IsValid()) { DCHECK(out.IsRegister() && !locations->GetLiveRegisters()->ContainsCoreRegister(out.reg())); - Primitive::Type type = at_->GetType(); + Primitive::Type type = instruction_->GetType(); mips64_codegen->MoveLocation(out, calling_convention.GetReturnLocation(type), type); } RestoreLiveRegisters(codegen, locations); + // For HLoadClass/kBssEntry, store the resolved Class to the BSS entry. + DCHECK_EQ(instruction_->IsLoadClass(), cls_ == instruction_); + if (cls_ == instruction_ && cls_->GetLoadKind() == HLoadClass::LoadKind::kBssEntry) { + DCHECK(out.IsValid()); + // TODO: Change art_quick_initialize_type/art_quick_initialize_static_storage to + // kSaveEverything and use a temporary for the .bss entry address in the fast path, + // so that we can avoid another calculation here. + DCHECK_NE(out.AsRegister(), AT); + CodeGeneratorMIPS64::PcRelativePatchInfo* info = + mips64_codegen->NewPcRelativeTypePatch(cls_->GetDexFile(), type_index); + mips64_codegen->EmitPcRelativeAddressPlaceholderHigh(info, AT); + __ Sw(out.AsRegister(), AT, /* placeholder */ 0x5678); + } __ Bc(GetExitLabel()); } @@ -207,10 +221,6 @@ class LoadClassSlowPathMIPS64 : public SlowPathCodeMIPS64 { // The class this slow path will load. HLoadClass* const cls_; - // The instruction where this slow path is happening. - // (Might be the load class or an initialization check). - HInstruction* const at_; - // The dex PC of `at_`. const uint32_t dex_pc_; @@ -234,8 +244,8 @@ class LoadStringSlowPathMIPS64 : public SlowPathCodeMIPS64 { InvokeRuntimeCallingConvention calling_convention; HLoadString* load = instruction_->AsLoadString(); - const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex().index_; - __ LoadConst32(calling_convention.GetRegisterAt(0), string_index); + const dex::StringIndex string_index = instruction_->AsLoadString()->GetStringIndex(); + __ LoadConst32(calling_convention.GetRegisterAt(0), string_index.index_); mips64_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), @@ -929,14 +939,16 @@ void CodeGeneratorMIPS64::EmitLinkerPatches(ArenaVector* linker_pat EmitPcRelativeLinkerPatches(pc_relative_dex_cache_patches_, linker_patches); if (!GetCompilerOptions().IsBootImage()) { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } else { + EmitPcRelativeLinkerPatches(pc_relative_type_patches_, + linker_patches); EmitPcRelativeLinkerPatches(pc_relative_string_patches_, linker_patches); } - EmitPcRelativeLinkerPatches(pc_relative_type_patches_, - linker_patches); for (const auto& entry : boot_image_string_patches_) { const StringReference& target_string = entry.first; Literal* literal = entry.second; @@ -965,8 +977,8 @@ void CodeGeneratorMIPS64::EmitLinkerPatches(ArenaVector* linker_pat } CodeGeneratorMIPS64::PcRelativePatchInfo* CodeGeneratorMIPS64::NewPcRelativeStringPatch( - const DexFile& dex_file, uint32_t string_index) { - return NewPcRelativePatch(dex_file, string_index, &pc_relative_string_patches_); + const DexFile& dex_file, dex::StringIndex string_index) { + return NewPcRelativePatch(dex_file, string_index.index_, &pc_relative_string_patches_); } CodeGeneratorMIPS64::PcRelativePatchInfo* CodeGeneratorMIPS64::NewPcRelativeTypePatch( @@ -3322,6 +3334,9 @@ HLoadClass::LoadKind CodeGeneratorMIPS64::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kBootImageAddress: break; + case HLoadClass::LoadKind::kBssEntry: + DCHECK(!Runtime::Current()->UseJitCompilation()); + break; case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); // TODO: implement. @@ -3529,14 +3544,14 @@ void InstructionCodeGeneratorMIPS64::VisitLoadClass(HLoadClass* cls) { ArtMethod::DeclaringClassOffset().Int32Value()); break; case HLoadClass::LoadKind::kBootImageLinkTimeAddress: - DCHECK(!kEmitCompilerReadBarrier); + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); __ LoadLiteral(out, kLoadUnsignedWord, codegen_->DeduplicateBootImageTypeLiteral(cls->GetDexFile(), cls->GetTypeIndex())); break; case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: { - DCHECK(!kEmitCompilerReadBarrier); + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS64::PcRelativePatchInfo* info = codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); codegen_->EmitPcRelativeAddressPlaceholderHigh(info, AT); @@ -3552,6 +3567,15 @@ void InstructionCodeGeneratorMIPS64::VisitLoadClass(HLoadClass* cls) { codegen_->DeduplicateBootImageAddressLiteral(address)); break; } + case HLoadClass::LoadKind::kBssEntry: { + DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); + CodeGeneratorMIPS64::PcRelativePatchInfo* info = + codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); + codegen_->EmitPcRelativeAddressPlaceholderHigh(info, AT); + __ Lwu(out, AT, /* placeholder */ 0x5678); + generate_null_check = true; + break; + } case HLoadClass::LoadKind::kJitTableAddress: { LOG(FATAL) << "Unimplemented"; break; @@ -3622,6 +3646,7 @@ void InstructionCodeGeneratorMIPS64::VisitLoadString(HLoadString* load) NO_THREA switch (load_kind) { case HLoadString::LoadKind::kBootImageLinkTimeAddress: + DCHECK(codegen_->GetCompilerOptions().IsBootImage()); __ LoadLiteral(out, kLoadUnsignedWord, codegen_->DeduplicateBootImageStringLiteral(load->GetDexFile(), @@ -3630,7 +3655,7 @@ void InstructionCodeGeneratorMIPS64::VisitLoadString(HLoadString* load) NO_THREA case HLoadString::LoadKind::kBootImageLinkTimePcRelative: { DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS64::PcRelativePatchInfo* info = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); codegen_->EmitPcRelativeAddressPlaceholderHigh(info, AT); __ Daddiu(out, AT, /* placeholder */ 0x5678); return; // No dex cache slow path. @@ -3647,7 +3672,7 @@ void InstructionCodeGeneratorMIPS64::VisitLoadString(HLoadString* load) NO_THREA case HLoadString::LoadKind::kBssEntry: { DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS64::PcRelativePatchInfo* info = - codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex().index_); + codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); codegen_->EmitPcRelativeAddressPlaceholderHigh(info, AT); __ Lwu(out, AT, /* placeholder */ 0x5678); SlowPathCodeMIPS64* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathMIPS64(load); diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h index 8ac919f47e..df78830713 100644 --- a/compiler/optimizing/code_generator_mips64.h +++ b/compiler/optimizing/code_generator_mips64.h @@ -411,7 +411,8 @@ class CodeGeneratorMIPS64 : public CodeGenerator { Mips64Label pc_rel_label; }; - PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, uint32_t string_index); + PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file, + dex::StringIndex string_index); PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index); PcRelativePatchInfo* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); @@ -469,7 +470,7 @@ class CodeGeneratorMIPS64 : public CodeGenerator { ArenaDeque pc_relative_string_patches_; // Deduplication map for boot type literals for kBootImageLinkTimeAddress. BootTypeToLiteralMap boot_image_type_patches_; - // PC-relative type patch info. + // PC-relative type patch info; type depends on configuration (app .bss or boot image PIC). ArenaDeque pc_relative_type_patches_; // Deduplication map for patchable boot image addresses. Uint32ToLiteralMap boot_image_address_patches_; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 8b1451330b..d97f5f541a 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -225,8 +225,8 @@ class LoadStringSlowPathX86 : public SlowPathCode { SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex().index_; - __ movl(calling_convention.GetRegisterAt(0), Immediate(string_index)); + const dex::StringIndex string_index = instruction_->AsLoadString()->GetStringIndex(); + __ movl(calling_convention.GetRegisterAt(0), Immediate(string_index.index_)); x86_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes(); x86_codegen->Move32(locations->Out(), Location::RegisterLocation(EAX)); @@ -254,21 +254,24 @@ class LoadClassSlowPathX86 : public SlowPathCode { HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCode(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCode(at), cls_(cls), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { - LocationSummary* locations = at_->GetLocations(); + LocationSummary* locations = instruction_->GetLocations(); CodeGeneratorX86* x86_codegen = down_cast(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); InvokeRuntimeCallingConvention calling_convention; - __ movl(calling_convention.GetRegisterAt(0), Immediate(cls_->GetTypeIndex().index_)); + dex::TypeIndex type_index = cls_->GetTypeIndex(); + __ movl(calling_convention.GetRegisterAt(0), Immediate(type_index.index_)); x86_codegen->InvokeRuntime(do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType, - at_, dex_pc_, this); + instruction_, + dex_pc_, + this); if (do_clinit_) { CheckEntrypointTypes(); } else { @@ -281,8 +284,17 @@ class LoadClassSlowPathX86 : public SlowPathCode { DCHECK(out.IsRegister() && !locations->GetLiveRegisters()->ContainsCoreRegister(out.reg())); x86_codegen->Move32(out, Location::RegisterLocation(EAX)); } - RestoreLiveRegisters(codegen, locations); + // For HLoadClass/kBssEntry, store the resolved Class to the BSS entry. + DCHECK_EQ(instruction_->IsLoadClass(), cls_ == instruction_); + if (cls_ == instruction_ && cls_->GetLoadKind() == HLoadClass::LoadKind::kBssEntry) { + DCHECK(out.IsValid()); + Register method_address = locations->InAt(0).AsRegister(); + __ movl(Address(method_address, CodeGeneratorX86::kDummy32BitOffset), + locations->Out().AsRegister()); + Label* fixup_label = x86_codegen->NewTypeBssEntryPatch(cls_); + __ Bind(fixup_label); + } __ jmp(GetExitLabel()); } @@ -292,10 +304,6 @@ class LoadClassSlowPathX86 : public SlowPathCode { // The class this slow path will load. HLoadClass* const cls_; - // The instruction where this slow path is happening. - // (Might be the load class or an initialization check). - HInstruction* const at_; - // The dex PC of `at_`. const uint32_t dex_pc_; @@ -4606,6 +4614,12 @@ void CodeGeneratorX86::RecordTypePatch(HLoadClass* load_class) { __ Bind(&type_patches_.back().label); } +Label* CodeGeneratorX86::NewTypeBssEntryPatch(HLoadClass* load_class) { + DCHECK(!GetCompilerOptions().IsBootImage()); + type_patches_.emplace_back(load_class->GetDexFile(), load_class->GetTypeIndex().index_); + return &type_patches_.back().label; +} + Label* CodeGeneratorX86::NewStringBssEntryPatch(HLoadString* load_string) { DCHECK(!GetCompilerOptions().IsBootImage()); string_patches_.emplace_back(load_string->GetDexFile(), load_string->GetStringIndex().index_); @@ -4649,24 +4663,22 @@ void CodeGeneratorX86::EmitLinkerPatches(ArenaVector* linker_patche linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset)); } if (!GetCompilerOptions().IsBootImage()) { + EmitPcRelativeLinkerPatches(type_patches_, linker_patches); EmitPcRelativeLinkerPatches(string_patches_, linker_patches); } else if (GetCompilerOptions().GetCompilePic()) { + EmitPcRelativeLinkerPatches(type_patches_, linker_patches); EmitPcRelativeLinkerPatches(string_patches_, linker_patches); } else { + for (const PatchInfo