diff options
-rw-r--r-- | compiler/optimizing/code_generator.cc | 26 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 9 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 21 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 9 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 9 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 17 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 25 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 58 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/sharpening.cc | 27 |
18 files changed, 141 insertions, 135 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 402eeee65f..f00648f570 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -1378,28 +1378,21 @@ uint32_t CodeGenerator::GetReferenceDisableFlagOffset() const { void CodeGenerator::EmitJitRoots(uint8_t* code, Handle<mirror::ObjectArray<mirror::Object>> roots, - const uint8_t* roots_data, - Handle<mirror::DexCache> outer_dex_cache) { + const uint8_t* roots_data) { DCHECK_EQ(static_cast<size_t>(roots->GetLength()), GetNumberOfJitRoots()); - StackHandleScope<1> hs(Thread::Current()); - MutableHandle<mirror::DexCache> h_dex_cache(hs.NewHandle<mirror::DexCache>(nullptr)); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); size_t index = 0; for (auto& entry : jit_string_roots_) { - const DexFile& entry_dex_file = *entry.first.dex_file; - // Avoid the expensive FindDexCache call by checking if the string is - // in the compiled method's dex file. - h_dex_cache.Assign(IsSameDexFile(*outer_dex_cache->GetDexFile(), entry_dex_file) - ? outer_dex_cache.Get() - : class_linker->FindDexCache(hs.Self(), entry_dex_file)); - mirror::String* string = class_linker->LookupString( - entry_dex_file, entry.first.string_index, h_dex_cache); - DCHECK(string != nullptr) << "JIT roots require strings to have been loaded"; + // Update the `roots` with the string, and replace the address temporarily + // stored to the index in the table. + uint64_t address = entry.second; + roots->Set(index, reinterpret_cast<StackReference<mirror::String>*>(address)->AsMirrorPtr()); + DCHECK(roots->Get(index) != nullptr); + entry.second = index; // Ensure the string is strongly interned. This is a requirement on how the JIT // handles strings. b/32995596 - class_linker->GetInternTable()->InternStrong(string); - roots->Set(index, string); - entry.second = index; + class_linker->GetInternTable()->InternStrong( + reinterpret_cast<mirror::String*>(roots->Get(index))); ++index; } for (auto& entry : jit_class_roots_) { @@ -1407,6 +1400,7 @@ void CodeGenerator::EmitJitRoots(uint8_t* code, // stored to the index in the table. uint64_t address = entry.second; roots->Set(index, reinterpret_cast<StackReference<mirror::Class>*>(address)->AsMirrorPtr()); + DCHECK(roots->Get(index) != nullptr); entry.second = index; ++index; } diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 2e2c3c00af..6366b9838f 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -351,8 +351,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { // Also emits literal patches. void EmitJitRoots(uint8_t* code, Handle<mirror::ObjectArray<mirror::Object>> roots, - const uint8_t* roots_data, - Handle<mirror::DexCache> outer_dex_cache) + const uint8_t* roots_data) REQUIRES_SHARED(Locks::mutator_lock_); bool IsLeafMethod() const { @@ -713,9 +712,9 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { const ArenaVector<HBasicBlock*>* block_order_; // Maps a StringReference (dex_file, string_index) to the index in the literal table. - // Entries are intially added with a 0 index, and `EmitJitRoots` will compute all the - // indices. - ArenaSafeMap<StringReference, uint32_t, StringReferenceValueComparator> jit_string_roots_; + // Entries are intially added with a pointer in the handle zone, and `EmitJitRoots` + // will compute all the indices. + ArenaSafeMap<StringReference, uint64_t, StringReferenceValueComparator> jit_string_roots_; // Maps a ClassReference (dex_file, type_index) to the index in the literal table. // Entries are intially added with a pointer in the handle zone, and `EmitJitRoots` diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 1dd526f404..541a1c5b8f 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -5936,7 +5936,9 @@ void LocationsBuilderARM::VisitLoadString(HLoadString* load) { } } -void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { LocationSummary* locations = load->GetLocations(); Location out_loc = locations->Out(); Register out = out_loc.AsRegister<Register>(); @@ -5961,8 +5963,9 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK_NE(load->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast<uint32_t>(load->GetAddress()); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); __ LoadLiteral(out, codegen_->DeduplicateBootImageAddressLiteral(address)); return; // No dex cache slow path. } @@ -5986,7 +5989,8 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) { } case HLoadString::LoadKind::kJitTableAddress: { __ LoadLiteral(out, codegen_->DeduplicateJitStringLiteral(load->GetDexFile(), - load->GetStringIndex())); + load->GetStringIndex(), + load->GetString())); // /* GcRoot<mirror::String> */ out = *out GenerateGcRootFieldLoad(load, out_loc, out, /* offset */ 0, kCompilerReadBarrierOption); return; @@ -7316,8 +7320,10 @@ Literal* CodeGeneratorARM::DeduplicateBootImageAddressLiteral(uint32_t address) } Literal* CodeGeneratorARM::DeduplicateJitStringLiteral(const DexFile& dex_file, - dex::StringIndex string_index) { - jit_string_roots_.Overwrite(StringReference(&dex_file, string_index), /* placeholder */ 0u); + dex::StringIndex string_index, + Handle<mirror::String> handle) { + jit_string_roots_.Overwrite(StringReference(&dex_file, string_index), + reinterpret_cast64<uint64_t>(handle.GetReference())); return jit_string_patches_.GetOrCreate( StringReference(&dex_file, string_index), [this]() { return __ NewLiteral<uint32_t>(/* placeholder */ 0u); }); diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 6435851320..d5968e0764 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -489,7 +489,9 @@ class CodeGeneratorARM : public CodeGenerator { dex::StringIndex string_index); Literal* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, dex::TypeIndex type_index); Literal* DeduplicateBootImageAddressLiteral(uint32_t address); - Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, dex::StringIndex string_index); + Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, + dex::StringIndex string_index, + Handle<mirror::String> handle); Literal* DeduplicateJitClassLiteral(const DexFile& dex_file, dex::TypeIndex type_index, uint64_t address); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 240e39df4b..9aaeadb44a 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -4137,8 +4137,9 @@ vixl::aarch64::Literal<uint32_t>* CodeGeneratorARM64::DeduplicateBootImageAddres } vixl::aarch64::Literal<uint32_t>* CodeGeneratorARM64::DeduplicateJitStringLiteral( - const DexFile& dex_file, dex::StringIndex string_index) { - jit_string_roots_.Overwrite(StringReference(&dex_file, string_index), /* placeholder */ 0u); + const DexFile& dex_file, dex::StringIndex string_index, Handle<mirror::String> handle) { + jit_string_roots_.Overwrite(StringReference(&dex_file, string_index), + reinterpret_cast64<uint64_t>(handle.GetReference())); return jit_string_patches_.GetOrCreate( StringReference(&dex_file, string_index), [this]() { return __ CreateLiteralDestroyedWithPool<uint32_t>(/* placeholder */ 0u); }); @@ -4527,7 +4528,9 @@ void LocationsBuilderARM64::VisitLoadString(HLoadString* load) { } } -void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { Register out = OutputRegister(load); Location out_loc = load->GetLocations()->Out(); @@ -4550,8 +4553,10 @@ void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK(load->GetAddress() != 0u && IsUint<32>(load->GetAddress())); - __ Ldr(out.W(), codegen_->DeduplicateBootImageAddressLiteral(load->GetAddress())); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); + __ Ldr(out.W(), codegen_->DeduplicateBootImageAddressLiteral(address)); return; // No dex cache slow path. } case HLoadString::LoadKind::kBssEntry: { @@ -4582,7 +4587,8 @@ void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) { } case HLoadString::LoadKind::kJitTableAddress: { __ Ldr(out, codegen_->DeduplicateJitStringLiteral(load->GetDexFile(), - load->GetStringIndex())); + load->GetStringIndex(), + load->GetString())); GenerateGcRootFieldLoad(load, out_loc, out.X(), diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index 8f33b6becf..d6a5f9d1fa 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -567,7 +567,8 @@ class CodeGeneratorARM64 : public CodeGenerator { dex::TypeIndex type_index); vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageAddressLiteral(uint64_t address); vixl::aarch64::Literal<uint32_t>* DeduplicateJitStringLiteral(const DexFile& dex_file, - dex::StringIndex string_index); + dex::StringIndex string_index, + Handle<mirror::String> handle); vixl::aarch64::Literal<uint32_t>* DeduplicateJitClassLiteral(const DexFile& dex_file, dex::TypeIndex string_index, uint64_t address); diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index cf4d94deea..c769decaa0 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -6021,7 +6021,9 @@ void LocationsBuilderARMVIXL::VisitLoadString(HLoadString* load) { } } -void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { LocationSummary* locations = load->GetLocations(); Location out_loc = locations->Out(); vixl32::Register out = OutputRegister(load); @@ -6041,8 +6043,9 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK_NE(load->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast<uint32_t>(load->GetAddress()); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); __ Ldr(out, codegen_->DeduplicateBootImageAddressLiteral(address)); return; // No dex cache slow path. } @@ -6062,7 +6065,8 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) { } case HLoadString::LoadKind::kJitTableAddress: { __ Ldr(out, codegen_->DeduplicateJitStringLiteral(load->GetDexFile(), - load->GetStringIndex())); + load->GetStringIndex(), + load->GetString())); // /* GcRoot<mirror::String> */ out = *out GenerateGcRootFieldLoad(load, out_loc, out, /* offset */ 0, kCompilerReadBarrierOption); return; @@ -7443,9 +7447,12 @@ VIXLUInt32Literal* CodeGeneratorARMVIXL::DeduplicateDexCacheAddressLiteral(uint3 return DeduplicateUint32Literal(address, &uint32_literals_); } -VIXLUInt32Literal* CodeGeneratorARMVIXL::DeduplicateJitStringLiteral(const DexFile& dex_file, - dex::StringIndex string_index) { - jit_string_roots_.Overwrite(StringReference(&dex_file, string_index), /* placeholder */ 0u); +VIXLUInt32Literal* CodeGeneratorARMVIXL::DeduplicateJitStringLiteral( + const DexFile& dex_file, + dex::StringIndex string_index, + Handle<mirror::String> handle) { + jit_string_roots_.Overwrite(StringReference(&dex_file, string_index), + reinterpret_cast64<uint64_t>(handle.GetReference())); return jit_string_patches_.GetOrCreate( StringReference(&dex_file, string_index), [this]() { diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index 297d63cefd..200a463c75 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -573,7 +573,8 @@ class CodeGeneratorARMVIXL : public CodeGenerator { VIXLUInt32Literal* DeduplicateBootImageAddressLiteral(uint32_t address); VIXLUInt32Literal* DeduplicateDexCacheAddressLiteral(uint32_t address); VIXLUInt32Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, - dex::StringIndex string_index); + dex::StringIndex string_index, + Handle<mirror::String> handle); VIXLUInt32Literal* DeduplicateJitClassLiteral(const DexFile& dex_file, dex::TypeIndex type_index, uint64_t address); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 29f8b2aa3c..bc62854e5d 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -5625,7 +5625,9 @@ void LocationsBuilderMIPS::VisitLoadString(HLoadString* load) { } } -void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { HLoadString::LoadKind load_kind = load->GetLoadKind(); LocationSummary* locations = load->GetLocations(); Location out_loc = locations->Out(); @@ -5660,8 +5662,9 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK_NE(load->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast<uint32_t>(load->GetAddress()); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); __ LoadLiteral(out, base_or_current_method_reg, codegen_->DeduplicateBootImageAddressLiteral(address)); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index dd3f0fee5a..1b9c6da460 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -3628,7 +3628,9 @@ void LocationsBuilderMIPS64::VisitLoadString(HLoadString* load) { } } -void InstructionCodeGeneratorMIPS64::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorMIPS64::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { HLoadString::LoadKind load_kind = load->GetLoadKind(); LocationSummary* locations = load->GetLocations(); Location out_loc = locations->Out(); @@ -3650,8 +3652,9 @@ void InstructionCodeGeneratorMIPS64::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK_NE(load->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast<uint32_t>(load->GetAddress()); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); __ LoadLiteral(out, kLoadUnsignedWord, codegen_->DeduplicateBootImageAddressLiteral(address)); diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 786bc50345..a9b717db4f 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -6231,15 +6231,19 @@ void LocationsBuilderX86::VisitLoadString(HLoadString* load) { } Label* CodeGeneratorX86::NewJitRootStringPatch(const DexFile& dex_file, - dex::StringIndex dex_index) { - jit_string_roots_.Overwrite(StringReference(&dex_file, dex_index), /* placeholder */ 0u); + dex::StringIndex dex_index, + Handle<mirror::String> handle) { + jit_string_roots_.Overwrite( + StringReference(&dex_file, dex_index), reinterpret_cast64<uint64_t>(handle.GetReference())); // Add a patch entry and return the label. jit_string_patches_.emplace_back(dex_file, dex_index.index_); PatchInfo<Label>* info = &jit_string_patches_.back(); return &info->label; } -void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { LocationSummary* locations = load->GetLocations(); Location out_loc = locations->Out(); Register out = out_loc.AsRegister<Register>(); @@ -6257,8 +6261,9 @@ void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK_NE(load->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast<uint32_t>(load->GetAddress()); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); __ movl(out, Immediate(address)); codegen_->RecordSimplePatch(); return; // No dex cache slow path. @@ -6279,7 +6284,7 @@ void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) { case HLoadString::LoadKind::kJitTableAddress: { Address address = Address::Absolute(CodeGeneratorX86::kDummy32BitOffset); Label* fixup_label = codegen_->NewJitRootStringPatch( - load->GetDexFile(), load->GetStringIndex()); + load->GetDexFile(), load->GetStringIndex(), load->GetString()); // /* GcRoot<mirror::String> */ out = *address GenerateGcRootFieldLoad(load, out_loc, address, fixup_label, kCompilerReadBarrierOption); return; diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 1af685087c..dd1628c867 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -415,7 +415,9 @@ class CodeGeneratorX86 : public CodeGenerator { void RecordTypePatch(HLoadClass* load_class); Label* NewStringBssEntryPatch(HLoadString* load_string); Label* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); - Label* NewJitRootStringPatch(const DexFile& dex_file, dex::StringIndex dex_index); + Label* NewJitRootStringPatch(const DexFile& dex_file, + dex::StringIndex dex_index, + Handle<mirror::String> handle); Label* NewJitRootClassPatch(const DexFile& dex_file, dex::TypeIndex dex_index, uint64_t address); void MoveFromReturnRegister(Location trg, Primitive::Type type) OVERRIDE; diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 06b48c489c..261473505f 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -5630,15 +5630,19 @@ void LocationsBuilderX86_64::VisitLoadString(HLoadString* load) { } Label* CodeGeneratorX86_64::NewJitRootStringPatch(const DexFile& dex_file, - dex::StringIndex dex_index) { - jit_string_roots_.Overwrite(StringReference(&dex_file, dex_index), /* placeholder */ 0u); + dex::StringIndex dex_index, + Handle<mirror::String> handle) { + jit_string_roots_.Overwrite( + StringReference(&dex_file, dex_index), reinterpret_cast64<uint64_t>(handle.GetReference())); // Add a patch entry and return the label. jit_string_patches_.emplace_back(dex_file, dex_index.index_); PatchInfo<Label>* info = &jit_string_patches_.back(); return &info->label; } -void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) { +// NO_THREAD_SAFETY_ANALYSIS as we manipulate handles whose internal object we know does not +// move. +void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) NO_THREAD_SAFETY_ANALYSIS { LocationSummary* locations = load->GetLocations(); Location out_loc = locations->Out(); CpuRegister out = out_loc.AsRegister<CpuRegister>(); @@ -5650,8 +5654,9 @@ void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) { return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { - DCHECK_NE(load->GetAddress(), 0u); - uint32_t address = dchecked_integral_cast<uint32_t>(load->GetAddress()); + uint32_t address = dchecked_integral_cast<uint32_t>( + reinterpret_cast<uintptr_t>(load->GetString().Get())); + DCHECK_NE(address, 0u); __ movl(out, Immediate(address)); // Zero-extended. codegen_->RecordSimplePatch(); return; // No dex cache slow path. @@ -5672,8 +5677,8 @@ void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) { case HLoadString::LoadKind::kJitTableAddress: { Address address = Address::Absolute(CodeGeneratorX86_64::kDummy32BitOffset, /* no_rip */ true); - Label* fixup_label = - codegen_->NewJitRootStringPatch(load->GetDexFile(), load->GetStringIndex()); + Label* fixup_label = codegen_->NewJitRootStringPatch( + load->GetDexFile(), load->GetStringIndex(), load->GetString()); // /* GcRoot<mirror::String> */ out = *address GenerateGcRootFieldLoad(load, out_loc, address, fixup_label, kCompilerReadBarrierOption); return; diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index f827e79a94..32d006c5f3 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -412,7 +412,9 @@ class CodeGeneratorX86_64 : public CodeGenerator { void RecordTypePatch(HLoadClass* load_class); Label* NewStringBssEntryPatch(HLoadString* load_string); Label* NewPcRelativeDexCacheArrayPatch(const DexFile& dex_file, uint32_t element_offset); - Label* NewJitRootStringPatch(const DexFile& dex_file, dex::StringIndex dex_index); + Label* NewJitRootStringPatch(const DexFile& dex_file, + dex::StringIndex dex_index, + Handle<mirror::String> handle); Label* NewJitRootClassPatch(const DexFile& dex_file, dex::TypeIndex dex_index, uint64_t address); void MoveFromReturnRegister(Location trg, Primitive::Type type) OVERRIDE; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index a599c2aa84..d45fa11534 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2498,6 +2498,17 @@ std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs) { } } +// Helper for InstructionDataEquals to fetch the mirror String out +// from a kJitTableAddress LoadString kind. +// NO_THREAD_SAFETY_ANALYSIS because even though we're accessing +// mirrors, they are stored in a variable size handle scope which is always +// visited during a pause. Also, the only caller of this helper +// only uses the mirror for pointer comparison. +static inline mirror::String* AsMirrorInternal(Handle<mirror::String> handle) + NO_THREAD_SAFETY_ANALYSIS { + return handle.Get(); +} + bool HLoadString::InstructionDataEquals(const HInstruction* other) const { const HLoadString* other_load_string = other->AsLoadString(); // TODO: To allow GVN for HLoadString from different dex files, we should compare the strings @@ -2506,16 +2517,16 @@ bool HLoadString::InstructionDataEquals(const HInstruction* other) const { GetPackedFields() != other_load_string->GetPackedFields()) { return false; } - LoadKind load_kind = GetLoadKind(); - if (HasAddress(load_kind)) { - return GetAddress() == other_load_string->GetAddress(); - } else { - DCHECK(HasStringReference(load_kind)) << load_kind; - return IsSameDexFile(GetDexFile(), other_load_string->GetDexFile()); + switch (GetLoadKind()) { + case LoadKind::kBootImageAddress: + case LoadKind::kJitTableAddress: + return AsMirrorInternal(GetString()) == AsMirrorInternal(other_load_string->GetString()); + default: + return IsSameDexFile(GetDexFile(), other_load_string->GetDexFile()); } } -void HLoadString::SetLoadKindInternal(LoadKind load_kind) { +void HLoadString::SetLoadKind(LoadKind load_kind) { // Once sharpened, the load kind should not be changed again. DCHECK_EQ(GetLoadKind(), LoadKind::kDexCacheViaMethod); SetPackedField<LoadKindField>(load_kind); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index db1b277990..ea9a94c420 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -5787,39 +5787,31 @@ class HLoadString FINAL : public HInstruction { uint32_t dex_pc) : HInstruction(SideEffectsForArchRuntimeCalls(), dex_pc), special_input_(HUserRecord<HInstruction*>(current_method)), - string_index_(string_index) { + string_index_(string_index), + dex_file_(dex_file) { SetPackedField<LoadKindField>(LoadKind::kDexCacheViaMethod); - load_data_.dex_file_ = &dex_file; } - void SetLoadKindWithAddress(LoadKind load_kind, uint64_t address) { - DCHECK(HasAddress(load_kind)); - load_data_.address = address; - SetLoadKindInternal(load_kind); - } - - void SetLoadKindWithStringReference(LoadKind load_kind, - const DexFile& dex_file, - dex::StringIndex string_index) { - DCHECK(HasStringReference(load_kind)); - load_data_.dex_file_ = &dex_file; - string_index_ = string_index; - SetLoadKindInternal(load_kind); - } + void SetLoadKind(LoadKind load_kind); LoadKind GetLoadKind() const { return GetPackedField<LoadKindField>(); } - const DexFile& GetDexFile() const; + const DexFile& GetDexFile() const { + return dex_file_; + } dex::StringIndex GetStringIndex() const { return string_index_; } - uint64_t GetAddress() const { - DCHECK(HasAddress(GetLoadKind())); - return load_data_.address; + Handle<mirror::String> GetString() const { + return string_; + } + + void SetString(Handle<mirror::String> str) { + string_ = str; } bool CanBeMoved() const OVERRIDE { return true; } @@ -5874,18 +5866,6 @@ class HLoadString FINAL : public HInstruction { static_assert(kNumberOfLoadStringPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>; - static bool HasStringReference(LoadKind load_kind) { - return load_kind == LoadKind::kBootImageLinkTimeAddress || - load_kind == LoadKind::kBootImageLinkTimePcRelative || - load_kind == LoadKind::kBssEntry || - load_kind == LoadKind::kDexCacheViaMethod || - load_kind == LoadKind::kJitTableAddress; - } - - static bool HasAddress(LoadKind load_kind) { - return load_kind == LoadKind::kBootImageAddress; - } - void SetLoadKindInternal(LoadKind load_kind); // The special input is the HCurrentMethod for kDexCacheViaMethod. @@ -5893,26 +5873,16 @@ class HLoadString FINAL : public HInstruction { // for PC-relative loads, i.e. kDexCachePcRelative or kBootImageLinkTimePcRelative. HUserRecord<HInstruction*> special_input_; - // String index serves also as the hash code and it's also needed for slow-paths, - // so it must not be overwritten with other load data. dex::StringIndex string_index_; + const DexFile& dex_file_; - union { - const DexFile* dex_file_; // For string reference. - uint64_t address; // Up to 64-bit, needed for kDexCacheAddress on 64-bit targets. - } load_data_; + Handle<mirror::String> string_; DISALLOW_COPY_AND_ASSIGN(HLoadString); }; std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadString::LoadKind). -inline const DexFile& HLoadString::GetDexFile() const { - DCHECK(HasStringReference(GetLoadKind())) << GetLoadKind(); - return *load_data_.dex_file_; -} - -// Note: defined outside class to see operator<<(., HLoadString::LoadKind). inline void HLoadString::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 4bf5b080a7..297500b12f 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -1205,7 +1205,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, } MaybeRecordStat(MethodCompilationStat::kCompiled); codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size), *code_item); - codegen->EmitJitRoots(code_allocator.GetData(), roots, roots_data, dex_cache); + codegen->EmitJitRoots(code_allocator.GetData(), roots, roots_data); const void* code = code_cache->CommitCode( self, diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index ca26c30dcf..dc8ee23ba4 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -275,7 +275,6 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { dex::StringIndex string_index = load_string->GetStringIndex(); HLoadString::LoadKind desired_load_kind = HLoadString::LoadKind::kDexCacheViaMethod; - uint64_t address = 0u; // String or dex cache element address. { Runtime* runtime = Runtime::Current(); ClassLinker* class_linker = runtime->GetClassLinker(); @@ -284,12 +283,13 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *compilation_unit_.GetDexFile()) ? compilation_unit_.GetDexCache() : hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file)); + mirror::String* string = nullptr; if (codegen_->GetCompilerOptions().IsBootImage()) { // Compiling boot image. Resolve the string and allocate it if needed, to ensure // the string will be added to the boot image. DCHECK(!runtime->UseJitCompilation()); - mirror::String* string = class_linker->ResolveString(dex_file, string_index, dex_cache); + string = class_linker->ResolveString(dex_file, string_index, dex_cache); CHECK(string != nullptr); if (compiler_driver_->GetSupportBootImageFixup()) { DCHECK(ContainsElement(compiler_driver_->GetDexFilesForOatFile(), &dex_file)); @@ -303,43 +303,32 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { } else if (runtime->UseJitCompilation()) { // TODO: Make sure we don't set the "compile PIC" flag for JIT as that's bogus. // DCHECK(!codegen_->GetCompilerOptions().GetCompilePic()); - mirror::String* string = class_linker->LookupString(dex_file, string_index, dex_cache); + string = class_linker->LookupString(dex_file, string_index, dex_cache); if (string != nullptr) { if (runtime->GetHeap()->ObjectIsInBootImageSpace(string)) { desired_load_kind = HLoadString::LoadKind::kBootImageAddress; - address = reinterpret_cast64<uint64_t>(string); } else { desired_load_kind = HLoadString::LoadKind::kJitTableAddress; } } } else { // AOT app compilation. Try to lookup the string without allocating if not found. - mirror::String* string = class_linker->LookupString(dex_file, string_index, dex_cache); + string = class_linker->LookupString(dex_file, string_index, dex_cache); if (string != nullptr && runtime->GetHeap()->ObjectIsInBootImageSpace(string) && !codegen_->GetCompilerOptions().GetCompilePic()) { desired_load_kind = HLoadString::LoadKind::kBootImageAddress; - address = reinterpret_cast64<uint64_t>(string); } else { desired_load_kind = HLoadString::LoadKind::kBssEntry; } } + if (string != nullptr) { + load_string->SetString(handles_->NewHandle(string)); + } } HLoadString::LoadKind load_kind = codegen_->GetSupportedLoadStringKind(desired_load_kind); - switch (load_kind) { - case HLoadString::LoadKind::kBootImageLinkTimeAddress: - case HLoadString::LoadKind::kBootImageLinkTimePcRelative: - case HLoadString::LoadKind::kBssEntry: - case HLoadString::LoadKind::kDexCacheViaMethod: - case HLoadString::LoadKind::kJitTableAddress: - load_string->SetLoadKindWithStringReference(load_kind, dex_file, string_index); - break; - case HLoadString::LoadKind::kBootImageAddress: - DCHECK_NE(address, 0u); - load_string->SetLoadKindWithAddress(load_kind, address); - break; - } + load_string->SetLoadKind(load_kind); } } // namespace art |