From 02ca05a5a6e3f5028c6c2987a81be481d07bc617 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Tue, 12 May 2020 13:58:51 +0100 Subject: Move HandleCache to HGraph. This avoids passing the `VariableSizedHandleScope*` argument around and eliminates HGraph::inexact_object_rti_ and its initialization. The latter shall allow running Optimizing gtests that do not require type information without creating a Runtime in future. (To be implemented in a separate CL.) Test: m test-art-host-gtest Test: testrunner.py --host --optmizing Test: aosp_taimen-userdebug boots. Change-Id: I36fe9bc556c6d610d644c8c14cc74c9985a14d64 --- compiler/optimizing/builder.cc | 10 +-- compiler/optimizing/builder.h | 5 +- compiler/optimizing/inliner.cc | 34 ++++----- compiler/optimizing/inliner.h | 3 - compiler/optimizing/instruction_builder.cc | 13 ++-- compiler/optimizing/instruction_builder.h | 5 +- compiler/optimizing/nodes.cc | 11 ++- compiler/optimizing/nodes.h | 83 +++++++++++++++++--- compiler/optimizing/optimization.cc | 6 +- compiler/optimizing/optimization.h | 3 +- compiler/optimizing/optimizing_compiler.cc | 50 ++++-------- compiler/optimizing/optimizing_unit_test.h | 20 ++--- compiler/optimizing/reference_type_propagation.cc | 89 ++++++---------------- compiler/optimizing/reference_type_propagation.h | 37 +-------- .../optimizing/reference_type_propagation_test.cc | 11 ++- compiler/optimizing/select_generator.cc | 6 +- compiler/optimizing/select_generator.h | 2 - compiler/optimizing/ssa_builder.cc | 1 - compiler/optimizing/ssa_builder.h | 4 - 19 files changed, 161 insertions(+), 232 deletions(-) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 64aa1b9358..33dbf4e45e 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -43,8 +43,7 @@ HGraphBuilder::HGraphBuilder(HGraph* graph, const DexCompilationUnit* outer_compilation_unit, CodeGenerator* code_generator, OptimizingCompilerStats* compiler_stats, - ArrayRef interpreter_metadata, - VariableSizedHandleScope* handles) + ArrayRef interpreter_metadata) : graph_(graph), dex_file_(&graph->GetDexFile()), code_item_accessor_(accessor), @@ -53,13 +52,11 @@ HGraphBuilder::HGraphBuilder(HGraph* graph, code_generator_(code_generator), compilation_stats_(compiler_stats), interpreter_metadata_(interpreter_metadata), - handles_(handles), return_type_(DataType::FromShorty(dex_compilation_unit_->GetShorty()[0])) {} HGraphBuilder::HGraphBuilder(HGraph* graph, const DexCompilationUnit* dex_compilation_unit, const CodeItemDebugInfoAccessor& accessor, - VariableSizedHandleScope* handles, DataType::Type return_type) : graph_(graph), dex_file_(&graph->GetDexFile()), @@ -68,7 +65,6 @@ HGraphBuilder::HGraphBuilder(HGraph* graph, outer_compilation_unit_(nullptr), code_generator_(nullptr), compilation_stats_(nullptr), - handles_(handles), return_type_(return_type) {} bool HGraphBuilder::SkipCompilation(size_t number_of_branches) { @@ -119,7 +115,6 @@ GraphAnalysisResult HGraphBuilder::BuildGraph() { SsaBuilder ssa_builder(graph_, dex_compilation_unit_->GetClassLoader(), dex_compilation_unit_->GetDexCache(), - handles_, &local_allocator); HInstructionBuilder instruction_builder(graph_, &block_builder, @@ -132,7 +127,6 @@ GraphAnalysisResult HGraphBuilder::BuildGraph() { code_generator_, interpreter_metadata_, compilation_stats_, - handles_, &local_allocator); // 1) Create basic blocks and link them together. Basic blocks are left @@ -190,7 +184,6 @@ void HGraphBuilder::BuildIntrinsicGraph(ArtMethod* method) { SsaBuilder ssa_builder(graph_, dex_compilation_unit_->GetClassLoader(), dex_compilation_unit_->GetDexCache(), - handles_, &local_allocator); HInstructionBuilder instruction_builder(graph_, &block_builder, @@ -203,7 +196,6 @@ void HGraphBuilder::BuildIntrinsicGraph(ArtMethod* method) { code_generator_, interpreter_metadata_, compilation_stats_, - handles_, &local_allocator); // 1) Create basic blocks for the intrinsic and link them together. diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 6152740324..8b76dd9106 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -39,14 +39,12 @@ class HGraphBuilder : public ValueObject { const DexCompilationUnit* outer_compilation_unit, CodeGenerator* code_generator, OptimizingCompilerStats* compiler_stats, - ArrayRef interpreter_metadata, - VariableSizedHandleScope* handles); + ArrayRef interpreter_metadata); // Only for unit testing. HGraphBuilder(HGraph* graph, const DexCompilationUnit* dex_compilation_unit, const CodeItemDebugInfoAccessor& accessor, - VariableSizedHandleScope* handles, DataType::Type return_type = DataType::Type::kInt32); GraphAnalysisResult BuildGraph(); @@ -72,7 +70,6 @@ class HGraphBuilder : public ValueObject { OptimizingCompilerStats* const compilation_stats_; const ArrayRef interpreter_metadata_; - VariableSizedHandleScope* const handles_; const DataType::Type return_type_; DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 5472839027..5920f78270 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -855,7 +855,8 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); PointerSize pointer_size = class_linker->GetImagePointerSize(); - Handle monomorphic_type = handles_->NewHandle(GetMonomorphicType(classes)); + Handle monomorphic_type = + graph_->GetHandleCache()->NewHandle(GetMonomorphicType(classes)); resolved_method = ResolveMethodFromInlineCache( monomorphic_type, resolved_method, invoke_instruction, pointer_size); @@ -891,7 +892,6 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, ReferenceTypePropagation rtp_fixup(graph_, outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), - handles_, /* is_first_run= */ false); rtp_fixup.Run(); @@ -1019,7 +1019,7 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, } ArtMethod* method = nullptr; - Handle handle = handles_->NewHandle(classes->Get(i)); + Handle handle = graph_->GetHandleCache()->NewHandle(classes->Get(i)); method = ResolveMethodFromInlineCache( handle, resolved_method, invoke_instruction, pointer_size); if (method == nullptr) { @@ -1091,7 +1091,6 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, ReferenceTypePropagation rtp_fixup(graph_, outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), - handles_, /* is_first_run= */ false); rtp_fixup.Run(); return true; @@ -1287,7 +1286,6 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget( ReferenceTypePropagation rtp_fixup(graph_, outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), - handles_, /* is_first_run= */ false); rtp_fixup.Run(); @@ -1411,7 +1409,6 @@ bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ReferenceTypePropagation(graph_, outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), - handles_, /* is_first_run= */ false).Run(); } return true; @@ -1729,11 +1726,11 @@ HInstanceFieldGet* HInliner::CreateInstanceFieldGet(uint32_t field_index, /* dex_pc= */ 0); if (iget->GetType() == DataType::Type::kReference) { // Use the same dex_cache that we used for field lookup as the hint_dex_cache. - Handle dex_cache = handles_->NewHandle(referrer->GetDexCache()); + Handle dex_cache = + graph_->GetHandleCache()->NewHandle(referrer->GetDexCache()); ReferenceTypePropagation rtp(graph_, outer_compilation_unit_.GetClassLoader(), dex_cache, - handles_, /* is_first_run= */ false); rtp.Visit(iget); } @@ -1772,11 +1769,9 @@ HInstanceFieldSet* HInliner::CreateInstanceFieldSet(uint32_t field_index, } template -static inline Handle NewHandleIfDifferent(ObjPtr object, - Handle hint, - VariableSizedHandleScope* handles) +static inline Handle NewHandleIfDifferent(ObjPtr object, Handle hint, HGraph* graph) REQUIRES_SHARED(Locks::mutator_lock_) { - return (object != hint.Get()) ? handles->NewHandle(object) : hint; + return (object != hint.Get()) ? graph->GetHandleCache()->NewHandle(object) : hint; } static bool CanEncodeInlinedMethodInStackMap(const DexFile& caller_dex_file, ArtMethod* callee) @@ -1839,7 +1834,6 @@ void HInliner::SubstituteArguments(HGraph* callee_graph, ReferenceTypePropagation(callee_graph, outer_compilation_unit_.GetClassLoader(), dex_compilation_unit.GetDexCache(), - handles_, /* is_first_run= */ false).Run(); } } @@ -1997,13 +1991,14 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); Handle dex_cache = NewHandleIfDifferent(resolved_method->GetDexCache(), caller_compilation_unit_.GetDexCache(), - handles_); + graph_); Handle class_loader = NewHandleIfDifferent(resolved_method->GetDeclaringClass()->GetClassLoader(), caller_compilation_unit_.GetClassLoader(), - handles_); + graph_); - Handle compiling_class = handles_->NewHandle(resolved_method->GetDeclaringClass()); + Handle compiling_class = + graph_->GetHandleCache()->NewHandle(resolved_method->GetDeclaringClass()); DexCompilationUnit dex_compilation_unit( class_loader, class_linker, @@ -2035,6 +2030,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, HGraph* callee_graph = new (graph_->GetAllocator()) HGraph( graph_->GetAllocator(), graph_->GetArenaStack(), + graph_->GetHandleCache()->GetHandles(), callee_dex_file, method_index, codegen_->GetCompilerOptions().GetInstructionSet(), @@ -2066,8 +2062,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, &outer_compilation_unit_, codegen_, inline_stats_, - resolved_method->GetQuickenedInfo(), - handles_); + resolved_method->GetQuickenedInfo()); if (builder.BuildGraph() != kAnalysisSuccess) { LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedCannotBuild) @@ -2158,7 +2153,6 @@ void HInliner::RunOptimizations(HGraph* callee_graph, codegen_, outer_compilation_unit_, dex_compilation_unit, - handles_, inline_stats_, total_number_of_dex_registers_ + accessor.RegistersSize(), total_number_of_instructions_ + number_of_instructions, @@ -2267,7 +2261,7 @@ void HInliner::FixUpReturnReferenceType(ArtMethod* resolved_method, DCHECK(return_replacement->IsPhi()); ObjPtr cls = resolved_method->LookupResolvedReturnType(); ReferenceTypeInfo rti = ReferenceTypePropagation::IsAdmissible(cls) - ? ReferenceTypeInfo::Create(handles_->NewHandle(cls)) + ? ReferenceTypeInfo::Create(graph_->GetHandleCache()->NewHandle(cls)) : graph_->GetInexactObjectRti(); return_replacement->SetReferenceTypeInfo(rti); } diff --git a/compiler/optimizing/inliner.h b/compiler/optimizing/inliner.h index 786b7683bf..6510857301 100644 --- a/compiler/optimizing/inliner.h +++ b/compiler/optimizing/inliner.h @@ -37,7 +37,6 @@ class HInliner : public HOptimization { CodeGenerator* codegen, const DexCompilationUnit& outer_compilation_unit, const DexCompilationUnit& caller_compilation_unit, - VariableSizedHandleScope* handles, OptimizingCompilerStats* stats, size_t total_number_of_dex_registers, size_t total_number_of_instructions, @@ -54,7 +53,6 @@ class HInliner : public HOptimization { parent_(parent), depth_(depth), inlining_budget_(0), - handles_(handles), inline_stats_(nullptr) {} bool Run() override; @@ -330,7 +328,6 @@ class HInliner : public HOptimization { // The budget left for inlining, in number of instructions. size_t inlining_budget_; - VariableSizedHandleScope* const handles_; // Used to record stats about optimizations on the inlined graph. // If the inlining is successful, these stats are merged to the caller graph's stats. diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index ea3d3c0427..768bc2465c 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -52,11 +52,9 @@ HInstructionBuilder::HInstructionBuilder(HGraph* graph, CodeGenerator* code_generator, ArrayRef interpreter_metadata, OptimizingCompilerStats* compiler_stats, - VariableSizedHandleScope* handles, ScopedArenaAllocator* local_allocator) : allocator_(graph->GetAllocator()), graph_(graph), - handles_(handles), dex_file_(dex_file), code_item_accessor_(accessor), return_type_(return_type), @@ -1436,7 +1434,7 @@ HClinitCheck* HInstructionBuilder::ProcessClinitCheckForInvoke( if (IsInitialized(klass)) { *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone; } else { - Handle h_klass = handles_->NewHandle(klass); + Handle h_klass = graph_->GetHandleCache()->NewHandle(klass); HLoadClass* cls = BuildLoadClass(h_klass->GetDexTypeIndex(), h_klass->GetDexFile(), h_klass, @@ -1957,7 +1955,8 @@ void HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, DataType::Type field_type = GetFieldAccessType(*dex_file_, field_index); - Handle klass = handles_->NewHandle(resolved_field->GetDeclaringClass()); + Handle klass = + graph_->GetHandleCache()->NewHandle(resolved_field->GetDeclaringClass()); HLoadClass* constant = BuildLoadClass(klass->GetDexTypeIndex(), klass->GetDexFile(), klass, @@ -2207,7 +2206,7 @@ void HInstructionBuilder::BuildLoadString(dex::StringIndex string_index, uint32_ HSharpening::ProcessLoadString(load_string, code_generator_, *dex_compilation_unit_, - handles_); + graph_->GetHandleCache()->GetHandles()); AppendInstruction(load_string); } @@ -2235,7 +2234,7 @@ HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, } } - // Note: `klass` must be from `handles_`. + // Note: `klass` must be from `graph_->GetHandleCache()`. bool is_referrers_class = (klass != nullptr) && (outer_compilation_unit_->GetCompilingClass().Get() == klass.Get()); HLoadClass* load_class = new (allocator_) HLoadClass( @@ -2273,7 +2272,7 @@ Handle HInstructionBuilder::ResolveClass(ScopedObjectAccess& soa, DCHECK_EQ(klass == nullptr, soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); // Clean up the exception left by type resolution if any. - Handle h_klass = handles_->NewHandle(klass); + Handle h_klass = graph_->GetHandleCache()->NewHandle(klass); class_cache_.Put(type_index, h_klass); return h_klass; } diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 95d331558f..04f2a22301 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -41,7 +41,6 @@ class InstructionOperands; class OptimizingCompilerStats; class ScopedObjectAccess; class SsaBuilder; -class VariableSizedHandleScope; namespace mirror { class Class; @@ -61,7 +60,6 @@ class HInstructionBuilder : public ValueObject { CodeGenerator* code_generator, ArrayRef interpreter_metadata, OptimizingCompilerStats* compiler_stats, - VariableSizedHandleScope* handles, ScopedArenaAllocator* local_allocator); bool Build(); @@ -301,7 +299,6 @@ class HInstructionBuilder : public ValueObject { ArenaAllocator* const allocator_; HGraph* const graph_; - VariableSizedHandleScope* const handles_; // The dex file where the method being compiled is, and the bytecode data. const DexFile* const dex_file_; @@ -343,7 +340,7 @@ class HInstructionBuilder : public ValueObject { ScopedArenaVector loop_headers_; // Cached resolved types for the current compilation unit's DexFile. - // Handle<>s reference entries in the `handles_`. + // Handle<>s reference entries in the `graph_->GetHandleCache()`. ScopedArenaSafeMap> class_cache_; static constexpr int kDefaultNumberOfLoops = 2; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index a5e0991578..3ea13b66f7 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -39,12 +39,11 @@ namespace art { // double). static constexpr bool kEnableFloatingPointStaticEvaluation = (FLT_EVAL_METHOD == 0); -void HGraph::InitializeInexactObjectRTI(VariableSizedHandleScope* handles) { +ReferenceTypeInfo::TypeHandle HandleCache::CreateRootHandle(VariableSizedHandleScope* handles, + ClassRoot class_root) { + // Mutator lock is required for NewHandle and GetClassRoot(). ScopedObjectAccess soa(Thread::Current()); - // Create the inexact Object reference type and store it in the HGraph. - inexact_object_rti_ = ReferenceTypeInfo::Create( - handles->NewHandle(GetClassRoot()), - /* is_exact= */ false); + return handles->NewHandle(GetClassRoot(class_root)); } void HGraph::AddBlock(HBasicBlock* block) { @@ -662,7 +661,7 @@ HNullConstant* HGraph::GetNullConstant(uint32_t dex_pc) { // id and/or any invariants the graph is assuming when adding new instructions. if ((cached_null_constant_ == nullptr) || (cached_null_constant_->GetBlock() == nullptr)) { cached_null_constant_ = new (allocator_) HNullConstant(dex_pc); - cached_null_constant_->SetReferenceTypeInfo(inexact_object_rti_); + cached_null_constant_->SetReferenceTypeInfo(GetInexactObjectRti()); InsertConstant(cached_null_constant_); } if (kIsDebugBuild) { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 7aeab722f0..67e02f236d 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -32,6 +32,7 @@ #include "base/stl_util.h" #include "base/transform_array_ref.h" #include "art_method.h" +#include "class_root.h" #include "data_type.h" #include "deoptimization_kind.h" #include "dex/dex_file.h" @@ -302,11 +303,75 @@ class ReferenceTypeInfo : ValueObject { std::ostream& operator<<(std::ostream& os, const ReferenceTypeInfo& rhs); +class HandleCache { + public: + explicit HandleCache(VariableSizedHandleScope* handles) : handles_(handles) { } + + VariableSizedHandleScope* GetHandles() { return handles_; } + + template + MutableHandle NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_) { + return handles_->NewHandle(object); + } + + template + MutableHandle NewHandle(ObjPtr object) REQUIRES_SHARED(Locks::mutator_lock_) { + return handles_->NewHandle(object); + } + + ReferenceTypeInfo::TypeHandle GetObjectClassHandle() { + return GetRootHandle(ClassRoot::kJavaLangObject, &object_class_handle_); + } + + ReferenceTypeInfo::TypeHandle GetClassClassHandle() { + return GetRootHandle(ClassRoot::kJavaLangClass, &class_class_handle_); + } + + ReferenceTypeInfo::TypeHandle GetMethodHandleClassHandle() { + return GetRootHandle(ClassRoot::kJavaLangInvokeMethodHandleImpl, &method_handle_class_handle_); + } + + ReferenceTypeInfo::TypeHandle GetMethodTypeClassHandle() { + return GetRootHandle(ClassRoot::kJavaLangInvokeMethodType, &method_type_class_handle_); + } + + ReferenceTypeInfo::TypeHandle GetStringClassHandle() { + return GetRootHandle(ClassRoot::kJavaLangString, &string_class_handle_); + } + + ReferenceTypeInfo::TypeHandle GetThrowableClassHandle() { + return GetRootHandle(ClassRoot::kJavaLangThrowable, &throwable_class_handle_); + } + + + private: + inline ReferenceTypeInfo::TypeHandle GetRootHandle(ClassRoot class_root, + ReferenceTypeInfo::TypeHandle* cache) { + if (UNLIKELY(!ReferenceTypeInfo::IsValidHandle(*cache))) { + *cache = CreateRootHandle(handles_, class_root); + } + return *cache; + } + + static ReferenceTypeInfo::TypeHandle CreateRootHandle(VariableSizedHandleScope* handles, + ClassRoot class_root); + + VariableSizedHandleScope* handles_; + + 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_; +}; + // Control-flow graph of a method. Contains a list of basic blocks. class HGraph : public ArenaObject { public: HGraph(ArenaAllocator* allocator, ArenaStack* arena_stack, + VariableSizedHandleScope* handles, const DexFile& dex_file, uint32_t method_idx, InstructionSet instruction_set, @@ -319,6 +384,7 @@ class HGraph : public ArenaObject { int start_instruction_id = 0) : allocator_(allocator), arena_stack_(arena_stack), + handle_cache_(handles), blocks_(allocator->Adapter(kArenaAllocBlockList)), reverse_post_order_(allocator->Adapter(kArenaAllocReversePostOrder)), linear_order_(allocator->Adapter(kArenaAllocLinearOrder)), @@ -350,7 +416,6 @@ class HGraph : public ArenaObject { cached_double_constants_(std::less(), allocator->Adapter(kArenaAllocConstantsMap)), cached_current_method_(nullptr), art_method_(nullptr), - inexact_object_rti_(ReferenceTypeInfo::CreateInvalid()), osr_(osr), baseline_(baseline), cha_single_implementation_list_(allocator->Adapter(kArenaAllocCHA)), @@ -358,11 +423,11 @@ class HGraph : public ArenaObject { blocks_.reserve(kDefaultNumberOfBlocks); } - // Acquires and stores RTI of inexact Object to be used when creating HNullConstant. - void InitializeInexactObjectRTI(VariableSizedHandleScope* handles); - ArenaAllocator* GetAllocator() const { return allocator_; } ArenaStack* GetArenaStack() const { return arena_stack_; } + + HandleCache* GetHandleCache() { return &handle_cache_; } + const ArenaVector& GetBlocks() const { return blocks_; } bool IsInSsaForm() const { return in_ssa_form_; } @@ -625,7 +690,9 @@ class HGraph : public ArenaObject { // before cursor. HInstruction* InsertOppositeCondition(HInstruction* cond, HInstruction* cursor); - ReferenceTypeInfo GetInexactObjectRti() const { return inexact_object_rti_; } + ReferenceTypeInfo GetInexactObjectRti() { + return ReferenceTypeInfo::Create(handle_cache_.GetObjectClassHandle(), /* is_exact= */ false); + } uint32_t GetNumberOfCHAGuards() { return number_of_cha_guards_; } void SetNumberOfCHAGuards(uint32_t num) { number_of_cha_guards_ = num; } @@ -668,6 +735,8 @@ class HGraph : public ArenaObject { ArenaAllocator* const allocator_; ArenaStack* const arena_stack_; + HandleCache handle_cache_; + // List of blocks in insertion order. ArenaVector blocks_; @@ -774,10 +843,6 @@ class HGraph : public ArenaObject { // (such as when the superclass could not be found). ArtMethod* art_method_; - // Keep the RTI of inexact Object to avoid having to pass stack handle - // collection pointer to passes which may create NullConstant. - ReferenceTypeInfo inexact_object_rti_; - // Whether we are compiling this graph for on stack replacement: this will // make all loops seen as irreducible and emit special stack maps to mark // compiled code entries which the interpreter can directly jump to. diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index fb60c01b5b..7483190a45 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -167,8 +167,7 @@ ArenaVector ConstructOptimizations( HGraph* graph, OptimizingCompilerStats* stats, CodeGenerator* codegen, - const DexCompilationUnit& dex_compilation_unit, - VariableSizedHandleScope* handles) { + const DexCompilationUnit& dex_compilation_unit) { ArenaVector optimizations(allocator->Adapter()); // Some optimizations require SideEffectsAnalysis or HInductionVarAnalysis @@ -243,7 +242,6 @@ ArenaVector ConstructOptimizations( codegen, dex_compilation_unit, // outer_compilation_unit dex_compilation_unit, // outermost_compilation_unit - handles, stats, accessor.RegistersSize(), /* total_number_of_instructions= */ 0, @@ -253,7 +251,7 @@ ArenaVector ConstructOptimizations( break; } case OptimizationPass::kSelectGenerator: - opt = new (allocator) HSelectGenerator(graph, handles, stats, pass_name); + opt = new (allocator) HSelectGenerator(graph, stats, pass_name); break; case OptimizationPass::kInstructionSimplifier: opt = new (allocator) InstructionSimplifier(graph, codegen, stats, pass_name); diff --git a/compiler/optimizing/optimization.h b/compiler/optimizing/optimization.h index f4777ad754..5ed3762e93 100644 --- a/compiler/optimizing/optimization.h +++ b/compiler/optimizing/optimization.h @@ -142,8 +142,7 @@ ArenaVector ConstructOptimizations( HGraph* graph, OptimizingCompilerStats* stats, CodeGenerator* codegen, - const DexCompilationUnit& dex_compilation_unit, - VariableSizedHandleScope* handles); + const DexCompilationUnit& dex_compilation_unit); } // namespace art diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index bf9afa27eb..1a2d40bcfd 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -307,7 +307,6 @@ class OptimizingCompiler final : public Compiler { CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, PassObserver* pass_observer, - VariableSizedHandleScope* handles, const OptimizationDef definitions[], size_t length) const { // Convert definitions to optimization passes. @@ -318,8 +317,7 @@ class OptimizingCompiler final : public Compiler { graph, compilation_stats_.get(), codegen, - dex_compilation_unit, - handles); + dex_compilation_unit); DCHECK_EQ(length, optimizations.size()); // Run the optimization passes one by one. Any "depends_on" pass refers back to // the most recent occurrence of that pass, skipped or executed. @@ -350,17 +348,15 @@ class OptimizingCompiler final : public Compiler { CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, PassObserver* pass_observer, - VariableSizedHandleScope* handles, const OptimizationDef (&definitions)[length]) const { return RunOptimizations( - graph, codegen, dex_compilation_unit, pass_observer, handles, definitions, length); + graph, codegen, dex_compilation_unit, pass_observer, definitions, length); } void RunOptimizations(HGraph* graph, CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - VariableSizedHandleScope* handles) const; + PassObserver* pass_observer) const; private: // Create a 'CompiledMethod' for an optimized graph. @@ -396,14 +392,12 @@ class OptimizingCompiler final : public Compiler { bool RunArchOptimizations(HGraph* graph, CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - VariableSizedHandleScope* handles) const; + PassObserver* pass_observer) const; bool RunBaselineOptimizations(HGraph* graph, CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - VariableSizedHandleScope* handles) const; + PassObserver* pass_observer) const; std::vector GenerateJitDebugInfo(const debug::MethodDebugInfo& method_debug_info); @@ -456,8 +450,7 @@ static bool IsInstructionSetSupported(InstructionSet instruction_set) { bool OptimizingCompiler::RunBaselineOptimizations(HGraph* graph, CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - VariableSizedHandleScope* handles) const { + PassObserver* pass_observer) const { switch (codegen->GetCompilerOptions().GetInstructionSet()) { #ifdef ART_ENABLE_CODEGEN_x86 case InstructionSet::kX86: { @@ -468,7 +461,6 @@ bool OptimizingCompiler::RunBaselineOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, x86_optimizations); } #endif @@ -477,7 +469,6 @@ bool OptimizingCompiler::RunBaselineOptimizations(HGraph* graph, UNUSED(codegen); UNUSED(dex_compilation_unit); UNUSED(pass_observer); - UNUSED(handles); return false; } } @@ -485,8 +476,7 @@ bool OptimizingCompiler::RunBaselineOptimizations(HGraph* graph, bool OptimizingCompiler::RunArchOptimizations(HGraph* graph, CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - VariableSizedHandleScope* handles) const { + PassObserver* pass_observer) const { switch (codegen->GetCompilerOptions().GetInstructionSet()) { #if defined(ART_ENABLE_CODEGEN_arm) case InstructionSet::kThumb2: @@ -501,7 +491,6 @@ bool OptimizingCompiler::RunArchOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, arm_optimizations); } #endif @@ -517,7 +506,6 @@ bool OptimizingCompiler::RunArchOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, arm64_optimizations); } #endif @@ -534,7 +522,6 @@ bool OptimizingCompiler::RunArchOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, x86_optimizations); } #endif @@ -550,7 +537,6 @@ bool OptimizingCompiler::RunArchOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, x86_64_optimizations); } #endif @@ -595,8 +581,7 @@ static std::string ConvertPassNameToOptimizationName(const std::string& pass_nam void OptimizingCompiler::RunOptimizations(HGraph* graph, CodeGenerator* codegen, const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - VariableSizedHandleScope* handles) const { + PassObserver* pass_observer) const { const std::vector* pass_names = GetCompilerOptions().GetPassesToRun(); if (pass_names != nullptr) { // If passes were defined on command-line, build the optimization @@ -612,7 +597,6 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, optimizations.data(), length); return; @@ -682,10 +666,9 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, codegen, dex_compilation_unit, pass_observer, - handles, optimizations); - RunArchOptimizations(graph, codegen, dex_compilation_unit, pass_observer, handles); + RunArchOptimizations(graph, codegen, dex_compilation_unit, pass_observer); } static ArenaVector EmitAndSortLinkerPatches(CodeGenerator* codegen) { @@ -798,6 +781,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, HGraph* graph = new (allocator) HGraph( allocator, arena_stack, + handles, dex_file, method_idx, compiler_options.GetInstructionSet(), @@ -837,8 +821,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, &dex_compilation_unit, codegen.get(), compilation_stats_.get(), - interpreter_metadata, - handles); + interpreter_metadata); GraphAnalysisResult result = builder.BuildGraph(); if (result != kAnalysisSuccess) { switch (result) { @@ -881,9 +864,9 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, } if (baseline) { - RunBaselineOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer, handles); + RunBaselineOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer); } else { - RunOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer, handles); + RunOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer); } RegisterAllocator::Strategy regalloc_strategy = @@ -926,6 +909,7 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( HGraph* graph = new (allocator) HGraph( allocator, arena_stack, + handles, dex_file, method_idx, compiler_options.GetInstructionSet(), @@ -962,8 +946,7 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( &dex_compilation_unit, codegen.get(), compilation_stats_.get(), - /* interpreter_metadata= */ ArrayRef(), - handles); + /* interpreter_metadata= */ ArrayRef()); builder.BuildIntrinsicGraph(method); } @@ -976,10 +959,9 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( codegen.get(), dex_compilation_unit, &pass_observer, - handles, optimizations); - RunArchOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer, handles); + RunArchOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer); AllocateRegisters(graph, codegen.get(), diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index eb262bc123..2c757f8535 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -117,10 +117,9 @@ class OptimizingUnitTestHelper { void ResetPoolAndAllocator() { pool_and_allocator_.reset(new ArenaPoolAndAllocator()); - handles_.reset(); // When getting rid of the old HGraph, we can also reset handles_. } - HGraph* CreateGraph() { + HGraph* CreateGraph(VariableSizedHandleScope* handles = nullptr) { ArenaAllocator* const allocator = pool_and_allocator_->GetAllocator(); // Reserve a big array of 0s so the dex file constructor can offsets from the header. @@ -140,6 +139,7 @@ class OptimizingUnitTestHelper { return new (allocator) HGraph( allocator, pool_and_allocator_->GetArenaStack(), + handles, *dex_files_.back(), /*method_idx*/-1, kRuntimeISA); @@ -147,8 +147,9 @@ class OptimizingUnitTestHelper { // Create a control-flow graph from Dex instructions. HGraph* CreateCFG(const std::vector& data, - DataType::Type return_type = DataType::Type::kInt32) { - HGraph* graph = CreateGraph(); + DataType::Type return_type = DataType::Type::kInt32, + VariableSizedHandleScope* handles = nullptr) { + HGraph* graph = CreateGraph(handles); // The code item data might not aligned to 4 bytes, copy it to ensure that. const size_t code_item_size = data.size() * sizeof(data.front()); @@ -158,13 +159,9 @@ class OptimizingUnitTestHelper { const dex::CodeItem* code_item = reinterpret_cast(aligned_data); { - ScopedObjectAccess soa(Thread::Current()); - if (handles_ == nullptr) { - handles_.reset(new VariableSizedHandleScope(soa.Self())); - } const DexCompilationUnit* dex_compilation_unit = new (graph->GetAllocator()) DexCompilationUnit( - handles_->NewHandle(nullptr), + /* class_loader= */ Handle(), // Invalid handle. /* class_linker= */ nullptr, graph->GetDexFile(), code_item, @@ -172,9 +169,9 @@ class OptimizingUnitTestHelper { /* method_idx= */ dex::kDexNoIndex, /* access_flags= */ 0u, /* verified_method= */ nullptr, - handles_->NewHandle(nullptr)); + /* dex_cache= */ Handle()); // Invalid handle. CodeItemDebugInfoAccessor accessor(graph->GetDexFile(), code_item, /*dex_method_idx*/ 0u); - HGraphBuilder builder(graph, dex_compilation_unit, accessor, handles_.get(), return_type); + HGraphBuilder builder(graph, dex_compilation_unit, accessor, return_type); bool graph_built = (builder.BuildGraph() == kAnalysisSuccess); return graph_built ? graph : nullptr; } @@ -205,7 +202,6 @@ class OptimizingUnitTestHelper { std::vector> dex_files_; std::unique_ptr pool_and_allocator_; - std::unique_ptr handles_; }; class OptimizingUnitTest : public CommonCompilerTest, public OptimizingUnitTestHelper {}; diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index fb7222ccf6..ff1e01ba4c 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -40,54 +40,15 @@ static inline ObjPtr FindDexCacheWithHint( } } -static inline ReferenceTypeInfo::TypeHandle GetRootHandle(VariableSizedHandleScope* handles, - ClassRoot class_root, - ReferenceTypeInfo::TypeHandle* cache) { - if (!ReferenceTypeInfo::IsValidHandle(*cache)) { - // Mutator lock is required for NewHandle. - ScopedObjectAccess soa(Thread::Current()); - *cache = handles->NewHandle(GetClassRoot(class_root)); - } - return *cache; -} - -ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetObjectClassHandle() { - return GetRootHandle(handles_, ClassRoot::kJavaLangObject, &object_class_handle_); -} - -ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetClassClassHandle() { - return GetRootHandle(handles_, ClassRoot::kJavaLangClass, &class_class_handle_); -} - -ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetMethodHandleClassHandle() { - return GetRootHandle(handles_, - ClassRoot::kJavaLangInvokeMethodHandleImpl, - &method_handle_class_handle_); -} - -ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetMethodTypeClassHandle() { - return GetRootHandle(handles_, ClassRoot::kJavaLangInvokeMethodType, &method_type_class_handle_); -} - -ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetStringClassHandle() { - return GetRootHandle(handles_, ClassRoot::kJavaLangString, &string_class_handle_); -} - -ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetThrowableClassHandle() { - return GetRootHandle(handles_, ClassRoot::kJavaLangThrowable, &throwable_class_handle_); -} - class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { public: RTPVisitor(HGraph* graph, Handle class_loader, Handle hint_dex_cache, - HandleCache* handle_cache, bool is_first_run) : HGraphDelegateVisitor(graph), class_loader_(class_loader), hint_dex_cache_(hint_dex_cache), - handle_cache_(handle_cache), allocator_(graph->GetArenaStack()), worklist_(allocator_.Adapter(kArenaAllocReferenceTypePropagation)), is_first_run_(is_first_run) { @@ -138,11 +99,14 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { void AddToWorklist(HInstruction* instruction); void AddDependentInstructionsToWorklist(HInstruction* instruction); + HandleCache* GetHandleCache() { + return GetGraph()->GetHandleCache(); + } + static constexpr size_t kDefaultWorklistSize = 8; Handle class_loader_; Handle hint_dex_cache_; - HandleCache* const handle_cache_; // Use local allocator for allocating memory. ScopedArenaAllocator allocator_; @@ -153,13 +117,11 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { ReferenceTypePropagation::ReferenceTypePropagation(HGraph* graph, Handle class_loader, Handle hint_dex_cache, - VariableSizedHandleScope* handles, bool is_first_run, const char* name) : HOptimization(graph, name), class_loader_(class_loader), hint_dex_cache_(hint_dex_cache), - handle_cache_(handles), is_first_run_(is_first_run) { } @@ -200,7 +162,6 @@ void ReferenceTypePropagation::Visit(HInstruction* instruction) { RTPVisitor visitor(graph_, class_loader_, hint_dex_cache_, - &handle_cache_, is_first_run_); instruction->Accept(&visitor); } @@ -360,7 +321,7 @@ static void BoundTypeForClassCheck(HInstruction* check) { } bool ReferenceTypePropagation::Run() { - RTPVisitor visitor(graph_, class_loader_, hint_dex_cache_, &handle_cache_, is_first_run_); + RTPVisitor visitor(graph_, class_loader_, hint_dex_cache_, is_first_run_); // To properly propagate type info we need to visit in the dominator-based order. // Reverse post order guarantees a node's dominators are visited first. @@ -426,8 +387,8 @@ void ReferenceTypePropagation::RTPVisitor::BoundTypeForIfNotNull(HBasicBlock* bl ? ifInstruction->IfTrueSuccessor() : ifInstruction->IfFalseSuccessor(); - ReferenceTypeInfo object_rti = ReferenceTypeInfo::Create( - handle_cache_->GetObjectClassHandle(), /* is_exact= */ false); + ReferenceTypeInfo object_rti = + ReferenceTypeInfo::Create(GetHandleCache()->GetObjectClassHandle(), /* is_exact= */ false); BoundTypeIn(obj, notNullBlock, /* start_instruction= */ nullptr, object_rti); } @@ -571,13 +532,13 @@ void ReferenceTypePropagation::RTPVisitor::SetClassAsTypeInfo(HInstruction* inst << "Expected String.: " << method->PrettyMethod(); } instr->SetReferenceTypeInfo( - ReferenceTypeInfo::Create(handle_cache_->GetStringClassHandle(), /* is_exact= */ true)); + ReferenceTypeInfo::Create(GetHandleCache()->GetStringClassHandle(), /* is_exact= */ true)); } else if (IsAdmissible(klass)) { - ReferenceTypeInfo::TypeHandle handle = handle_cache_->NewHandle(klass); + ReferenceTypeInfo::TypeHandle handle = GetHandleCache()->NewHandle(klass); is_exact = is_exact || handle->CannotBeAssignedFromOtherTypes(); instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(handle, is_exact)); } else { - instr->SetReferenceTypeInfo(instr->GetBlock()->GetGraph()->GetInexactObjectRti()); + instr->SetReferenceTypeInfo(GetGraph()->GetInexactObjectRti()); } } @@ -647,7 +608,7 @@ void ReferenceTypePropagation::RTPVisitor::VisitUnresolvedInstanceFieldGet( HUnresolvedInstanceFieldGet* instr) { // TODO: Use descriptor to get the actual type. if (instr->GetFieldType() == DataType::Type::kReference) { - instr->SetReferenceTypeInfo(instr->GetBlock()->GetGraph()->GetInexactObjectRti()); + instr->SetReferenceTypeInfo(GetGraph()->GetInexactObjectRti()); } } @@ -655,7 +616,7 @@ void ReferenceTypePropagation::RTPVisitor::VisitUnresolvedStaticFieldGet( HUnresolvedStaticFieldGet* instr) { // TODO: Use descriptor to get the actual type. if (instr->GetFieldType() == DataType::Type::kReference) { - instr->SetReferenceTypeInfo(instr->GetBlock()->GetGraph()->GetInexactObjectRti()); + instr->SetReferenceTypeInfo(GetGraph()->GetInexactObjectRti()); } } @@ -665,7 +626,7 @@ void ReferenceTypePropagation::RTPVisitor::VisitLoadClass(HLoadClass* instr) { instr->SetValidLoadedClassRTI(); } instr->SetReferenceTypeInfo( - ReferenceTypeInfo::Create(handle_cache_->GetClassClassHandle(), /* is_exact= */ true)); + ReferenceTypeInfo::Create(GetHandleCache()->GetClassClassHandle(), /* is_exact= */ true)); } void ReferenceTypePropagation::RTPVisitor::VisitInstanceOf(HInstanceOf* instr) { @@ -681,18 +642,17 @@ void ReferenceTypePropagation::RTPVisitor::VisitClinitCheck(HClinitCheck* instr) void ReferenceTypePropagation::RTPVisitor::VisitLoadMethodHandle(HLoadMethodHandle* instr) { instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create( - handle_cache_->GetMethodHandleClassHandle(), - /* is_exact= */ true)); + GetHandleCache()->GetMethodHandleClassHandle(), /* is_exact= */ true)); } void ReferenceTypePropagation::RTPVisitor::VisitLoadMethodType(HLoadMethodType* instr) { - instr->SetReferenceTypeInfo( - ReferenceTypeInfo::Create(handle_cache_->GetMethodTypeClassHandle(), /* is_exact= */ true)); + instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create( + GetHandleCache()->GetMethodTypeClassHandle(), /* is_exact= */ true)); } void ReferenceTypePropagation::RTPVisitor::VisitLoadString(HLoadString* instr) { instr->SetReferenceTypeInfo( - ReferenceTypeInfo::Create(handle_cache_->GetStringClassHandle(), /* is_exact= */ true)); + ReferenceTypeInfo::Create(GetHandleCache()->GetStringClassHandle(), /* is_exact= */ true)); } void ReferenceTypePropagation::RTPVisitor::VisitLoadException(HLoadException* instr) { @@ -705,8 +665,8 @@ void ReferenceTypePropagation::RTPVisitor::VisitLoadException(HLoadException* in catch_info->GetCatchDexFile(), /* is_exact= */ false); } else { - instr->SetReferenceTypeInfo( - ReferenceTypeInfo::Create(handle_cache_->GetThrowableClassHandle(), /* is_exact= */ false)); + instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create( + GetHandleCache()->GetThrowableClassHandle(), /* is_exact= */ false)); } } @@ -805,14 +765,13 @@ void ReferenceTypePropagation::RTPVisitor::VisitPhi(HPhi* phi) { } void ReferenceTypePropagation::FixUpInstructionType(HInstruction* instruction, - VariableSizedHandleScope* handle_scope) { + HandleCache* handle_cache) { if (instruction->IsSelect()) { ScopedObjectAccess soa(Thread::Current()); - HandleCache handle_cache(handle_scope); HSelect* select = instruction->AsSelect(); ReferenceTypeInfo false_rti = select->GetFalseValue()->GetReferenceTypeInfo(); ReferenceTypeInfo true_rti = select->GetTrueValue()->GetReferenceTypeInfo(); - select->SetReferenceTypeInfo(MergeTypes(false_rti, true_rti, &handle_cache)); + select->SetReferenceTypeInfo(MergeTypes(false_rti, true_rti, handle_cache)); } else { LOG(FATAL) << "Invalid instruction in FixUpInstructionType"; } @@ -873,12 +832,12 @@ void ReferenceTypePropagation::RTPVisitor::UpdateArrayGet(HArrayGet* instr) { Handle handle = parent_rti.GetTypeHandle(); if (handle->IsObjectArrayClass() && IsAdmissible(handle->GetComponentType())) { ReferenceTypeInfo::TypeHandle component_handle = - handle_cache_->NewHandle(handle->GetComponentType()); + GetHandleCache()->NewHandle(handle->GetComponentType()); bool is_exact = component_handle->CannotBeAssignedFromOtherTypes(); instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(component_handle, is_exact)); } else { // We don't know what the parent actually is, so we fallback to object. - instr->SetReferenceTypeInfo(instr->GetBlock()->GetGraph()->GetInexactObjectRti()); + instr->SetReferenceTypeInfo(GetGraph()->GetInexactObjectRti()); } } @@ -981,7 +940,7 @@ void ReferenceTypePropagation::RTPVisitor::UpdatePhi(HPhi* instr) { if (inputs[i]->IsNullConstant()) { continue; } - new_rti = MergeTypes(new_rti, inputs[i]->GetReferenceTypeInfo(), handle_cache_); + new_rti = MergeTypes(new_rti, inputs[i]->GetReferenceTypeInfo(), GetHandleCache()); if (new_rti.IsValid() && new_rti.IsObjectClass()) { if (!new_rti.IsExact()) { break; diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 8a41d653d2..344dea8ccf 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -33,7 +33,6 @@ class ReferenceTypePropagation : public HOptimization { ReferenceTypePropagation(HGraph* graph, Handle class_loader, Handle hint_dex_cache, - VariableSizedHandleScope* handles, bool is_first_run, const char* name = kReferenceTypePropagationPassName); @@ -57,42 +56,9 @@ class ReferenceTypePropagation : public HOptimization { // Fix the reference type for an instruction whose inputs have changed. // For a select instruction, the reference types of the inputs are merged // and the resulting reference type is set on the select instruction. - static void FixUpInstructionType(HInstruction* instruction, - VariableSizedHandleScope* handle_scope); + static void FixUpInstructionType(HInstruction* instruction, HandleCache* handle_cache); private: - class HandleCache { - public: - explicit HandleCache(VariableSizedHandleScope* handles) : handles_(handles) { } - - template - MutableHandle NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_) { - return handles_->NewHandle(object); - } - - template - MutableHandle NewHandle(ObjPtr object) REQUIRES_SHARED(Locks::mutator_lock_) { - return handles_->NewHandle(object); - } - - ReferenceTypeInfo::TypeHandle GetObjectClassHandle(); - ReferenceTypeInfo::TypeHandle GetClassClassHandle(); - ReferenceTypeInfo::TypeHandle GetMethodHandleClassHandle(); - ReferenceTypeInfo::TypeHandle GetMethodTypeClassHandle(); - ReferenceTypeInfo::TypeHandle GetStringClassHandle(); - ReferenceTypeInfo::TypeHandle GetThrowableClassHandle(); - - private: - VariableSizedHandleScope* handles_; - - 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_; - }; - class RTPVisitor; static ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, @@ -108,7 +74,6 @@ class ReferenceTypePropagation : public HOptimization { // graph_->GetDexFile(). Since we may look up also in other dex files, it's used only // as a hint, to reduce the number of calls to the costly ClassLinker::FindDexCache(). Handle hint_dex_cache_; - HandleCache handle_cache_; // Whether this reference type propagation is the first run we are doing. const bool is_first_run_; diff --git a/compiler/optimizing/reference_type_propagation_test.cc b/compiler/optimizing/reference_type_propagation_test.cc index 028b6d3b79..01f0dd3f2b 100644 --- a/compiler/optimizing/reference_type_propagation_test.cc +++ b/compiler/optimizing/reference_type_propagation_test.cc @@ -30,16 +30,15 @@ namespace art { */ class ReferenceTypePropagationTest : public OptimizingUnitTest { public: - ReferenceTypePropagationTest() : graph_(CreateGraph()), propagation_(nullptr) { } + ReferenceTypePropagationTest() : graph_(nullptr), propagation_(nullptr) { } ~ReferenceTypePropagationTest() { } void SetupPropagation(VariableSizedHandleScope* handles) { - graph_->InitializeInexactObjectRTI(handles); + graph_ = CreateGraph(handles); propagation_ = new (GetAllocator()) ReferenceTypePropagation(graph_, Handle(), Handle(), - handles, true, "test_prop"); } @@ -47,7 +46,7 @@ class ReferenceTypePropagationTest : public OptimizingUnitTest { // Relay method to merge type in reference type propagation. ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, const ReferenceTypeInfo& b) REQUIRES_SHARED(Locks::mutator_lock_) { - return propagation_->MergeTypes(a, b, &propagation_->handle_cache_); + return propagation_->MergeTypes(a, b, graph_->GetHandleCache()); } // Helper method to construct an invalid type. @@ -57,12 +56,12 @@ class ReferenceTypePropagationTest : public OptimizingUnitTest { // Helper method to construct the Object type. ReferenceTypeInfo ObjectType(bool is_exact = true) REQUIRES_SHARED(Locks::mutator_lock_) { - return ReferenceTypeInfo::Create(propagation_->handle_cache_.GetObjectClassHandle(), is_exact); + return ReferenceTypeInfo::Create(graph_->GetHandleCache()->GetObjectClassHandle(), is_exact); } // Helper method to construct the String type. ReferenceTypeInfo StringType(bool is_exact = true) REQUIRES_SHARED(Locks::mutator_lock_) { - return ReferenceTypeInfo::Create(propagation_->handle_cache_.GetStringClassHandle(), is_exact); + return ReferenceTypeInfo::Create(graph_->GetHandleCache()->GetStringClassHandle(), is_exact); } // General building fields. diff --git a/compiler/optimizing/select_generator.cc b/compiler/optimizing/select_generator.cc index dcc7f77fc2..54053820ca 100644 --- a/compiler/optimizing/select_generator.cc +++ b/compiler/optimizing/select_generator.cc @@ -24,11 +24,9 @@ namespace art { static constexpr size_t kMaxInstructionsInBranch = 1u; HSelectGenerator::HSelectGenerator(HGraph* graph, - VariableSizedHandleScope* handles, OptimizingCompilerStats* stats, const char* name) - : HOptimization(graph, name, stats), - handle_scope_(handles) { + : HOptimization(graph, name, stats) { } // Returns true if `block` has only one predecessor, ends with a Goto @@ -163,7 +161,7 @@ bool HSelectGenerator::Run() { if (both_successors_return) { if (true_value->GetType() == DataType::Type::kReference) { DCHECK(false_value->GetType() == DataType::Type::kReference); - ReferenceTypePropagation::FixUpInstructionType(select, handle_scope_); + ReferenceTypePropagation::FixUpInstructionType(select, graph_->GetHandleCache()); } } else if (phi->GetType() == DataType::Type::kReference) { select->SetReferenceTypeInfo(phi->GetReferenceTypeInfo()); diff --git a/compiler/optimizing/select_generator.h b/compiler/optimizing/select_generator.h index 2889166f60..30ac8a86eb 100644 --- a/compiler/optimizing/select_generator.h +++ b/compiler/optimizing/select_generator.h @@ -64,7 +64,6 @@ namespace art { class HSelectGenerator : public HOptimization { public: HSelectGenerator(HGraph* graph, - VariableSizedHandleScope* handles, OptimizingCompilerStats* stats, const char* name = kSelectGeneratorPassName); @@ -73,7 +72,6 @@ class HSelectGenerator : public HOptimization { static constexpr const char* kSelectGeneratorPassName = "select_generator"; private: - VariableSizedHandleScope* handle_scope_; DISALLOW_COPY_AND_ASSIGN(HSelectGenerator); }; diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index a5e8ff65a9..67ee83c9dd 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -540,7 +540,6 @@ GraphAnalysisResult SsaBuilder::BuildSsa() { ReferenceTypePropagation(graph_, class_loader_, dex_cache_, - handles_, /* is_first_run= */ true).Run(); // HInstructionBuilder duplicated ArrayGet instructions with ambiguous type diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h index bb892c9304..a7d4e0ebd3 100644 --- a/compiler/optimizing/ssa_builder.h +++ b/compiler/optimizing/ssa_builder.h @@ -51,19 +51,16 @@ class SsaBuilder : public ValueObject { SsaBuilder(HGraph* graph, Handle class_loader, Handle dex_cache, - VariableSizedHandleScope* handles, ScopedArenaAllocator* local_allocator) : graph_(graph), class_loader_(class_loader), dex_cache_(dex_cache), - handles_(handles), agets_fixed_(false), local_allocator_(local_allocator), ambiguous_agets_(local_allocator->Adapter(kArenaAllocGraphBuilder)), ambiguous_asets_(local_allocator->Adapter(kArenaAllocGraphBuilder)), uninitialized_strings_(local_allocator->Adapter(kArenaAllocGraphBuilder)), uninitialized_string_phis_(local_allocator->Adapter(kArenaAllocGraphBuilder)) { - graph_->InitializeInexactObjectRTI(handles); } GraphAnalysisResult BuildSsa(); @@ -129,7 +126,6 @@ class SsaBuilder : public ValueObject { HGraph* const graph_; Handle class_loader_; Handle dex_cache_; - VariableSizedHandleScope* const handles_; // True if types of ambiguous ArrayGets have been resolved. bool agets_fixed_; -- cgit v1.2.3-59-g8ed1b