diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 20 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 47 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.h | 2 |
14 files changed, 169 insertions, 2 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 1e44311cb1..f57333741c 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -736,6 +736,26 @@ void CodeGenerator::GenerateLoadClassRuntimeCall(HLoadClass* cls) { } } +void CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary( + HLoadMethodHandle* method_handle, + Location runtime_proto_index_location, + Location runtime_return_location) { + DCHECK_EQ(method_handle->InputCount(), 1u); + LocationSummary* locations = + new (method_handle->GetBlock()->GetGraph()->GetAllocator()) LocationSummary( + method_handle, LocationSummary::kCallOnMainOnly); + locations->SetInAt(0, Location::NoLocation()); + locations->AddTemp(runtime_proto_index_location); + locations->SetOut(runtime_return_location); +} + +void CodeGenerator::GenerateLoadMethodHandleRuntimeCall(HLoadMethodHandle* method_handle) { + LocationSummary* locations = method_handle->GetLocations(); + MoveConstant(locations->GetTemp(0), method_handle->GetMethodHandleIndex()); + CheckEntrypointTypes<kQuickResolveMethodHandle, void*, uint32_t>(); + InvokeRuntime(kQuickResolveMethodHandle, method_handle, method_handle->GetDexPc()); +} + void CodeGenerator::CreateLoadMethodTypeRuntimeCallLocationSummary( HLoadMethodType* method_type, Location runtime_proto_index_location, diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 7e84a448cc..bcb25997f4 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -564,6 +564,11 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { Location runtime_return_location); void GenerateLoadClassRuntimeCall(HLoadClass* cls); + static void CreateLoadMethodHandleRuntimeCallLocationSummary(HLoadMethodHandle* method_handle, + Location runtime_handle_index_location, + Location runtime_return_location); + void GenerateLoadMethodHandleRuntimeCall(HLoadMethodHandle* method_handle); + static void CreateLoadMethodTypeRuntimeCallLocationSummary(HLoadMethodType* method_type, Location runtime_type_index_location, Location runtime_return_location); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 0601d2d79a..6f173e19f5 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -5144,6 +5144,16 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) NO_THREAD_SA } } +void LocationsBuilderARM64::VisitLoadMethodHandle(HLoadMethodHandle* load) { + InvokeRuntimeCallingConvention calling_convention; + Location location = LocationFrom(calling_convention.GetRegisterAt(0)); + CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary(load, location, location); +} + +void InstructionCodeGeneratorARM64::VisitLoadMethodHandle(HLoadMethodHandle* load) { + codegen_->GenerateLoadMethodHandleRuntimeCall(load); +} + void LocationsBuilderARM64::VisitLoadMethodType(HLoadMethodType* load) { InvokeRuntimeCallingConvention calling_convention; Location location = LocationFrom(calling_convention.GetRegisterAt(0)); diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 33304c619d..859e1597c6 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -7527,6 +7527,16 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) NO_THREAD_ } } +void LocationsBuilderARMVIXL::VisitLoadMethodHandle(HLoadMethodHandle* load) { + InvokeRuntimeCallingConventionARMVIXL calling_convention; + Location location = LocationFrom(calling_convention.GetRegisterAt(0)); + CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary(load, location, location); +} + +void InstructionCodeGeneratorARMVIXL::VisitLoadMethodHandle(HLoadMethodHandle* load) { + codegen_->GenerateLoadMethodHandleRuntimeCall(load); +} + void LocationsBuilderARMVIXL::VisitLoadMethodType(HLoadMethodType* load) { InvokeRuntimeCallingConventionARMVIXL calling_convention; Location location = LocationFrom(calling_convention.GetRegisterAt(0)); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 3a3fcffe15..7f3441fdf4 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -8226,6 +8226,16 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAF } } +void LocationsBuilderMIPS::VisitLoadMethodHandle(HLoadMethodHandle* load) { + InvokeRuntimeCallingConvention calling_convention; + Location loc = Location::RegisterLocation(calling_convention.GetRegisterAt(0)); + CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary(load, loc, loc); +} + +void InstructionCodeGeneratorMIPS::VisitLoadMethodHandle(HLoadMethodHandle* load) { + codegen_->GenerateLoadMethodHandleRuntimeCall(load); +} + void LocationsBuilderMIPS::VisitLoadMethodType(HLoadMethodType* load) { InvokeRuntimeCallingConvention calling_convention; Location loc = Location::RegisterLocation(calling_convention.GetRegisterAt(0)); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index d6fc9a15b8..ee32b96daf 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -6262,6 +6262,16 @@ void InstructionCodeGeneratorMIPS64::VisitLoadClass(HLoadClass* cls) NO_THREAD_S } } +void LocationsBuilderMIPS64::VisitLoadMethodHandle(HLoadMethodHandle* load) { + InvokeRuntimeCallingConvention calling_convention; + Location loc = Location::RegisterLocation(calling_convention.GetRegisterAt(0)); + CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary(load, loc, loc); +} + +void InstructionCodeGeneratorMIPS64::VisitLoadMethodHandle(HLoadMethodHandle* load) { + codegen_->GenerateLoadMethodHandleRuntimeCall(load); +} + void LocationsBuilderMIPS64::VisitLoadMethodType(HLoadMethodType* load) { InvokeRuntimeCallingConvention calling_convention; Location loc = Location::RegisterLocation(calling_convention.GetRegisterAt(0)); diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index d18a750faf..9e315381b1 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -6539,6 +6539,16 @@ void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAFE } } +void LocationsBuilderX86::VisitLoadMethodHandle(HLoadMethodHandle* load) { + InvokeRuntimeCallingConvention calling_convention; + Location location = Location::RegisterLocation(calling_convention.GetRegisterAt(0)); + CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary(load, location, location); +} + +void InstructionCodeGeneratorX86::VisitLoadMethodHandle(HLoadMethodHandle* load) { + codegen_->GenerateLoadMethodHandleRuntimeCall(load); +} + void LocationsBuilderX86::VisitLoadMethodType(HLoadMethodType* load) { InvokeRuntimeCallingConvention calling_convention; Location location = Location::RegisterLocation(calling_convention.GetRegisterAt(0)); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 450c8574b0..f7397046d7 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -5908,6 +5908,16 @@ void LocationsBuilderX86_64::VisitClinitCheck(HClinitCheck* check) { } } +void LocationsBuilderX86_64::VisitLoadMethodHandle(HLoadMethodHandle* load) { + // Custom calling convention: RAX serves as both input and output. + Location location = Location::RegisterLocation(RAX); + CodeGenerator::CreateLoadMethodHandleRuntimeCallLocationSummary(load, location, location); +} + +void InstructionCodeGeneratorX86_64::VisitLoadMethodHandle(HLoadMethodHandle* load) { + codegen_->GenerateLoadMethodHandleRuntimeCall(load); +} + void LocationsBuilderX86_64::VisitLoadMethodType(HLoadMethodType* load) { // Custom calling convention: RAX serves as both input and output. Location location = Location::RegisterLocation(RAX); diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 87ce1f0c73..d65ad40565 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -386,6 +386,11 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { << load_class->NeedsAccessCheck() << std::noboolalpha; } + void VisitLoadMethodHandle(HLoadMethodHandle* load_method_handle) OVERRIDE { + StartAttributeStream("load_kind") << "RuntimeCall"; + StartAttributeStream("method_handle_index") << load_method_handle->GetMethodHandleIndex(); + } + void VisitLoadMethodType(HLoadMethodType* load_method_type) OVERRIDE { StartAttributeStream("load_kind") << "RuntimeCall"; const DexFile& dex_file = load_method_type->GetDexFile(); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 61730a8128..35a39456a2 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1896,6 +1896,13 @@ bool HInstructionBuilder::LoadClassNeedsAccessCheck(Handle<mirror::Class> klass) } } +void HInstructionBuilder::BuildLoadMethodHandle(uint16_t proto_idx, uint32_t dex_pc) { + const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); + HLoadMethodHandle* load_method_handle = + new (allocator_) HLoadMethodHandle(graph_->GetCurrentMethod(), proto_idx, dex_file, dex_pc); + AppendInstruction(load_method_handle); +} + void HInstructionBuilder::BuildLoadMethodType(uint16_t proto_idx, uint32_t dex_pc) { const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); HLoadMethodType* load_method_type = @@ -2934,6 +2941,13 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, break; } + case Instruction::CONST_METHOD_HANDLE: { + uint16_t method_handle_idx = instruction.VRegB_21c(); + BuildLoadMethodHandle(method_handle_idx, dex_pc); + UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); + break; + } + case Instruction::CONST_METHOD_TYPE: { uint16_t proto_idx = instruction.VRegB_21c(); BuildLoadMethodType(proto_idx, dex_pc); diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 3fde54cffa..95ffa6b054 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -240,7 +240,10 @@ class HInstructionBuilder : public ValueObject { bool LoadClassNeedsAccessCheck(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); - // Builds a `HLoadMethodType` loading the given `proto_index`. + // Builds a `HLoadMethodHandle` loading the given `method_handle_idx`. + void BuildLoadMethodHandle(uint16_t method_handle_idx, uint32_t dex_pc); + + // Builds a `HLoadMethodType` loading the given `proto_idx`. void BuildLoadMethodType(uint16_t proto_idx, uint32_t dex_pc); // Returns the outer-most compiling method's class. diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 54882ff92b..a7c2d0b125 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1383,6 +1383,7 @@ class HLoopInformationOutwardIterator : public ValueObject { M(LessThanOrEqual, Condition) \ M(LoadClass, Instruction) \ M(LoadException, Instruction) \ + M(LoadMethodHandle, Instruction) \ M(LoadMethodType, Instruction) \ M(LoadString, Instruction) \ M(LongConstant, Constant) \ @@ -6500,6 +6501,50 @@ inline void HLoadString::AddSpecialInput(HInstruction* special_input) { special_input->AddUseAt(this, 0); } +class HLoadMethodHandle FINAL : public HInstruction { + public: + HLoadMethodHandle(HCurrentMethod* current_method, + uint16_t method_handle_idx, + const DexFile& dex_file, + uint32_t dex_pc) + : HInstruction(kLoadMethodHandle, + DataType::Type::kReference, + SideEffectsForArchRuntimeCalls(), + dex_pc), + special_input_(HUserRecord<HInstruction*>(current_method)), + method_handle_idx_(method_handle_idx), + dex_file_(dex_file) { + } + + using HInstruction::GetInputRecords; // Keep the const version visible. + ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() OVERRIDE FINAL { + return ArrayRef<HUserRecord<HInstruction*>>( + &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u); + } + + bool IsClonable() const OVERRIDE { return true; } + + uint16_t GetMethodHandleIndex() const { return method_handle_idx_; } + + const DexFile& GetDexFile() const { return dex_file_; } + + static SideEffects SideEffectsForArchRuntimeCalls() { + return SideEffects::CanTriggerGC(); + } + + DECLARE_INSTRUCTION(LoadMethodHandle); + + protected: + DEFAULT_COPY_CONSTRUCTOR(LoadMethodHandle); + + private: + // The special input is the HCurrentMethod for kRuntimeCall. + HUserRecord<HInstruction*> special_input_; + + const uint16_t method_handle_idx_; + const DexFile& dex_file_; +}; + class HLoadMethodType FINAL : public HInstruction { public: HLoadMethodType(HCurrentMethod* current_method, @@ -6540,7 +6585,7 @@ class HLoadMethodType FINAL : public HInstruction { // The special input is the HCurrentMethod for kRuntimeCall. HUserRecord<HInstruction*> special_input_; - uint16_t proto_idx_; + const uint16_t proto_idx_; const DexFile& dex_file_; }; diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index b15a0ea52f..ecfa790b91 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -59,6 +59,12 @@ ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetClassCla return GetRootHandle(handles_, ClassLinker::kJavaLangClass, &class_class_handle_); } +ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetMethodHandleClassHandle() { + return GetRootHandle(handles_, + ClassLinker::kJavaLangInvokeMethodHandleImpl, + &method_handle_class_handle_); +} + ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetMethodTypeClassHandle() { return GetRootHandle(handles_, ClassLinker::kJavaLangInvokeMethodType, @@ -95,6 +101,7 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { void VisitLoadClass(HLoadClass* load_class) OVERRIDE; void VisitInstanceOf(HInstanceOf* load_class) OVERRIDE; void VisitClinitCheck(HClinitCheck* clinit_check) OVERRIDE; + void VisitLoadMethodHandle(HLoadMethodHandle* instr) OVERRIDE; void VisitLoadMethodType(HLoadMethodType* instr) OVERRIDE; void VisitLoadString(HLoadString* instr) OVERRIDE; void VisitLoadException(HLoadException* instr) OVERRIDE; @@ -675,6 +682,12 @@ void ReferenceTypePropagation::RTPVisitor::VisitClinitCheck(HClinitCheck* instr) instr->SetReferenceTypeInfo(instr->InputAt(0)->GetReferenceTypeInfo()); } +void ReferenceTypePropagation::RTPVisitor::VisitLoadMethodHandle(HLoadMethodHandle* instr) { + instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create( + handle_cache_->GetMethodHandleClassHandle(), + /* is_exact */ true)); +} + void ReferenceTypePropagation::RTPVisitor::VisitLoadMethodType(HLoadMethodType* instr) { instr->SetReferenceTypeInfo( ReferenceTypeInfo::Create(handle_cache_->GetMethodTypeClassHandle(), /* is_exact */ true)); diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index da2193d223..d36d592708 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -75,6 +75,7 @@ class ReferenceTypePropagation : public HOptimization { ReferenceTypeInfo::TypeHandle GetObjectClassHandle(); ReferenceTypeInfo::TypeHandle GetClassClassHandle(); + ReferenceTypeInfo::TypeHandle GetMethodHandleClassHandle(); ReferenceTypeInfo::TypeHandle GetMethodTypeClassHandle(); ReferenceTypeInfo::TypeHandle GetStringClassHandle(); ReferenceTypeInfo::TypeHandle GetThrowableClassHandle(); @@ -84,6 +85,7 @@ class ReferenceTypePropagation : public HOptimization { ReferenceTypeInfo::TypeHandle object_class_handle_; ReferenceTypeInfo::TypeHandle class_class_handle_; + ReferenceTypeInfo::TypeHandle method_handle_class_handle_; ReferenceTypeInfo::TypeHandle method_type_class_handle_; ReferenceTypeInfo::TypeHandle string_class_handle_; ReferenceTypeInfo::TypeHandle throwable_class_handle_; |