diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/builder.h | 15 | ||||
-rw-r--r-- | compiler/optimizing/inliner.cc | 45 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 47 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.h | 11 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 26 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 44 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation_test.cc | 1 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.h | 3 |
10 files changed, 96 insertions, 105 deletions
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 3a4c9dbd16..e4ad4222fb 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -54,10 +54,7 @@ class HGraphBuilder : public ValueObject { compiler_driver_(driver), compilation_stats_(compiler_stats), block_builder_(graph, dex_file, code_item), - ssa_builder_(graph, - dex_compilation_unit->GetClassLoader(), - dex_compilation_unit->GetDexCache(), - handles), + ssa_builder_(graph, dex_compilation_unit->GetDexCache(), handles), instruction_builder_(graph, &block_builder_, &ssa_builder_, @@ -83,12 +80,10 @@ class HGraphBuilder : public ValueObject { code_item_(code_item), dex_compilation_unit_(nullptr), compiler_driver_(nullptr), + null_dex_cache_(), compilation_stats_(nullptr), block_builder_(graph, nullptr, code_item), - ssa_builder_(graph, - handles->NewHandle<mirror::ClassLoader>(nullptr), - handles->NewHandle<mirror::DexCache>(nullptr), - handles), + ssa_builder_(graph, null_dex_cache_, handles), instruction_builder_(graph, &block_builder_, &ssa_builder_, @@ -101,7 +96,7 @@ class HGraphBuilder : public ValueObject { /* code_generator */ nullptr, /* interpreter_metadata */ nullptr, /* compiler_stats */ nullptr, - handles->NewHandle<mirror::DexCache>(nullptr), + null_dex_cache_, handles) {} GraphAnalysisResult BuildGraph(); @@ -122,6 +117,8 @@ class HGraphBuilder : public ValueObject { CompilerDriver* const compiler_driver_; + ScopedNullHandle<mirror::DexCache> null_dex_cache_; + OptimizingCompilerStats* compilation_stats_; HBasicBlockBuilder block_builder_; diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index b56ef0f866..f0afccb782 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -198,9 +198,9 @@ static uint32_t FindMethodIndexIn(ArtMethod* method, } static dex::TypeIndex FindClassIndexIn(mirror::Class* cls, - const DexCompilationUnit& compilation_unit) + const DexFile& dex_file, + Handle<mirror::DexCache> dex_cache) REQUIRES_SHARED(Locks::mutator_lock_) { - const DexFile& dex_file = *compilation_unit.GetDexFile(); dex::TypeIndex index; if (cls->GetDexCache() == nullptr) { DCHECK(cls->IsArrayClass()) << cls->PrettyClass(); @@ -209,19 +209,22 @@ static dex::TypeIndex FindClassIndexIn(mirror::Class* cls, DCHECK(cls->IsProxyClass()) << cls->PrettyClass(); // TODO: deal with proxy classes. } else if (IsSameDexFile(cls->GetDexFile(), dex_file)) { - DCHECK_EQ(cls->GetDexCache(), compilation_unit.GetDexCache().Get()); + DCHECK_EQ(cls->GetDexCache(), dex_cache.Get()); index = cls->GetDexTypeIndex(); + // Update the dex cache to ensure the class is in. The generated code will + // consider it is. We make it safe by updating the dex cache, as other + // dex files might also load the class, and there is no guarantee the dex + // cache of the dex file of the class will be updated. + if (dex_cache->GetResolvedType(index) == nullptr) { + dex_cache->SetResolvedType(index, cls); + } } else { index = cls->FindTypeIndexInOtherDexFile(dex_file); - // We cannot guarantee the entry will resolve to the same class, + // We cannot guarantee the entry in the dex cache will resolve to the same class, // as there may be different class loaders. So only return the index if it's - // the right class already resolved with the class loader. - if (index.IsValid()) { - ObjPtr<mirror::Class> resolved = ClassLinker::LookupResolvedType( - index, compilation_unit.GetDexCache().Get(), compilation_unit.GetClassLoader().Get()); - if (resolved != cls) { - index = dex::TypeIndex::Invalid(); - } + // the right class in the dex cache already. + if (index.IsValid() && dex_cache->GetResolvedType(index) != cls) { + index = dex::TypeIndex::Invalid(); } } @@ -448,8 +451,9 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, DCHECK(invoke_instruction->IsInvokeVirtual() || invoke_instruction->IsInvokeInterface()) << invoke_instruction->DebugName(); + const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); dex::TypeIndex class_index = FindClassIndexIn( - GetMonomorphicType(classes), caller_compilation_unit_); + GetMonomorphicType(classes), caller_dex_file, caller_compilation_unit_.GetDexCache()); if (!class_index.IsValid()) { VLOG(compiler) << "Call to " << ArtMethod::PrettyMethod(resolved_method) << " from inline cache is not inlined because its class is not" @@ -492,7 +496,6 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, // Run type propagation to get the guard typed, and eventually propagate the // type of the receiver. ReferenceTypePropagation rtp_fixup(graph_, - outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false); @@ -587,6 +590,7 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); PointerSize pointer_size = class_linker->GetImagePointerSize(); + const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); bool all_targets_inlined = true; bool one_target_inlined = false; @@ -608,7 +612,8 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, HInstruction* cursor = invoke_instruction->GetPrevious(); HBasicBlock* bb_cursor = invoke_instruction->GetBlock(); - dex::TypeIndex class_index = FindClassIndexIn(handle.Get(), caller_compilation_unit_); + dex::TypeIndex class_index = FindClassIndexIn( + handle.Get(), caller_dex_file, caller_compilation_unit_.GetDexCache()); HInstruction* return_replacement = nullptr; if (!class_index.IsValid() || !TryBuildAndInline(invoke_instruction, @@ -664,7 +669,6 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, // Run type propagation to get the guards typed. ReferenceTypePropagation rtp_fixup(graph_, - outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false); @@ -859,7 +863,6 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget( // Run type propagation to get the guard typed. ReferenceTypePropagation rtp_fixup(graph_, - outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false); @@ -928,7 +931,6 @@ bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, // Actual return value has a more specific type than the method's declared // return type. Run RTP again on the outer graph to propagate it. ReferenceTypePropagation(graph_, - outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false).Run(); @@ -1181,11 +1183,7 @@ HInstanceFieldGet* HInliner::CreateInstanceFieldGet(Handle<mirror::DexCache> dex /* dex_pc */ 0); if (iget->GetType() == Primitive::kPrimNot) { // Use the same dex_cache that we used for field lookup as the hint_dex_cache. - ReferenceTypePropagation rtp(graph_, - outer_compilation_unit_.GetClassLoader(), - dex_cache, - handles_, - /* is_first_run */ false); + ReferenceTypePropagation rtp(graph_, dex_cache, handles_, /* is_first_run */ false); rtp.Visit(iget); } return iget; @@ -1231,7 +1229,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, resolved_method->GetDeclaringClass()->GetClassLoader())); DexCompilationUnit dex_compilation_unit( - class_loader, + class_loader.ToJObject(), class_linker, callee_dex_file, code_item, @@ -1348,7 +1346,6 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, // are more specific than the declared ones, run RTP again on the inner graph. if (run_rtp || ArgumentTypesMoreSpecific(invoke_instruction, resolved_method)) { ReferenceTypePropagation(callee_graph, - outer_compilation_unit_.GetClassLoader(), dex_compilation_unit.GetDexCache(), handles_, /* is_first_run */ false).Run(); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 3aaf2ca102..a1c391f455 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -669,10 +669,11 @@ static InvokeType GetInvokeTypeFromOpCode(Instruction::Code opcode) { ArtMethod* HInstructionBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<2> hs(soa.Self()); + StackHandleScope<3> hs(soa.Self()); ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); - Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); // We fetch the referenced class eagerly (that is, the class pointed by in the MethodId // at method_idx), as `CanAccessResolvedMethod` expects it be be in the dex cache. @@ -1259,7 +1260,9 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio static mirror::Class* GetClassFrom(CompilerDriver* driver, const DexCompilationUnit& compilation_unit) { ScopedObjectAccess soa(Thread::Current()); - Handle<mirror::ClassLoader> class_loader = compilation_unit.GetClassLoader(); + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader>(compilation_unit.GetClassLoader()))); Handle<mirror::DexCache> dex_cache = compilation_unit.GetDexCache(); return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); @@ -1275,9 +1278,10 @@ mirror::Class* HInstructionBuilder::GetCompilingClass() const { bool HInstructionBuilder::IsOutermostCompilingClass(dex::TypeIndex type_index) const { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<2> hs(soa.Self()); + StackHandleScope<3> hs(soa.Self()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); - Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass( soa, dex_cache, class_loader, type_index, dex_compilation_unit_))); Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); @@ -1313,7 +1317,8 @@ ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, StackHandleScope<2> hs(soa.Self()); ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); - Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); ArtField* resolved_field = class_linker->ResolveField(*dex_compilation_unit_->GetDexFile(), @@ -1630,8 +1635,10 @@ static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls) HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); + StackHandleScope<2> hs(soa.Self()); const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); - Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); Handle<mirror::Class> klass = handles_->NewHandle(compiler_driver_->ResolveClass( soa, dex_compilation_unit_->GetDexCache(), class_loader, type_index, dex_compilation_unit_)); @@ -1715,9 +1722,17 @@ void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction, } } -bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, bool* finalizable) const { +bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, + Handle<mirror::DexCache> dex_cache, + bool* finalizable) const { return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks( - LookupReferrerClass(), LookupResolvedType(type_index, *dex_compilation_unit_), finalizable); + dex_compilation_unit_->GetDexMethodIndex(), dex_cache, type_index, finalizable); +} + +bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, bool* finalizable) const { + ScopedObjectAccess soa(Thread::Current()); + Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); + return NeedsAccessCheck(type_index, dex_cache, finalizable); } bool HInstructionBuilder::CanDecodeQuickenedInfo() const { @@ -2757,18 +2772,4 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, return true; } // NOLINT(readability/fn_size) -ObjPtr<mirror::Class> HInstructionBuilder::LookupResolvedType( - dex::TypeIndex type_index, - const DexCompilationUnit& compilation_unit) const { - return ClassLinker::LookupResolvedType( - type_index, compilation_unit.GetDexCache().Get(), compilation_unit.GetClassLoader().Get()); -} - -ObjPtr<mirror::Class> HInstructionBuilder::LookupReferrerClass() const { - // TODO: Cache the result in a Handle<mirror::Class>. - const DexFile::MethodId& method_id = - dex_compilation_unit_->GetDexFile()->GetMethodId(dex_compilation_unit_->GetDexMethodIndex()); - return LookupResolvedType(method_id.class_idx_, *dex_compilation_unit_); -} - } // namespace art diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index e735a0c46d..3bb680ce44 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -106,8 +106,11 @@ class HInstructionBuilder : public ValueObject { // Returns whether the current method needs access check for the type. // Output parameter finalizable is set to whether the type is finalizable. - bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const + bool NeedsAccessCheck(dex::TypeIndex type_index, + Handle<mirror::DexCache> dex_cache, + /*out*/bool* finalizable) const REQUIRES_SHARED(Locks::mutator_lock_); + bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const; template<typename T> void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); @@ -297,12 +300,6 @@ class HInstructionBuilder : public ValueObject { // be found. ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put); - ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index, - const DexCompilationUnit& compilation_unit) const - REQUIRES_SHARED(Locks::mutator_lock_); - - ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_); - ArenaAllocator* const arena_; HGraph* const graph_; VariableSizedHandleScope* handles_; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 0375c66e42..727ca7d893 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -306,7 +306,7 @@ class OptimizingCompiler FINAL : public Compiler { InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - Handle<mirror::ClassLoader> class_loader, + jobject class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) const OVERRIDE; @@ -375,7 +375,7 @@ class OptimizingCompiler FINAL : public Compiler { InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - Handle<mirror::ClassLoader> class_loader, + jobject class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, ArtMethod* method, @@ -875,7 +875,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - Handle<mirror::ClassLoader> class_loader, + jobject class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, ArtMethod* method, @@ -946,8 +946,11 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, const uint8_t* interpreter_metadata = nullptr; if (method == nullptr) { ScopedObjectAccess soa(Thread::Current()); + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::ClassLoader> loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader>(class_loader))); method = compiler_driver->ResolveMethod( - soa, dex_cache, class_loader, &dex_compilation_unit, method_idx, invoke_type); + soa, dex_cache, loader, &dex_compilation_unit, method_idx, invoke_type); } // For AOT compilation, we may not get a method, for example if its class is erroneous. // JIT should always have a method. @@ -956,6 +959,16 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, graph->SetArtMethod(method); ScopedObjectAccess soa(Thread::Current()); interpreter_metadata = method->GetQuickenedInfo(class_linker->GetImagePointerSize()); + dex::TypeIndex type_index = method->GetDeclaringClass()->GetDexTypeIndex(); + + // Update the dex cache if the type is not in it yet. Note that under AOT, + // the verifier must have set it, but under JIT, there's no guarantee, as we + // don't necessarily run the verifier. + // The compiler and the compiler driver assume the compiling class is + // in the dex cache. + if (dex_cache->GetResolvedType(type_index) == nullptr) { + dex_cache->SetResolvedType(type_index, method->GetDeclaringClass()); + } } std::unique_ptr<CodeGenerator> codegen( @@ -1036,7 +1049,7 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - Handle<mirror::ClassLoader> jclass_loader, + jobject jclass_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) const { CompilerDriver* compiler_driver = GetCompilerDriver(); @@ -1150,6 +1163,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache())); DCHECK(method->IsCompilable()); + jobject jclass_loader = class_loader.ToJObject(); const DexFile* dex_file = method->GetDexFile(); const uint16_t class_def_idx = method->GetClassDefIndex(); const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); @@ -1173,7 +1187,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, invoke_type, class_def_idx, method_idx, - class_loader, + jclass_loader, *dex_file, dex_cache, method, diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 6e332ca59b..c55fccc7d3 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -65,13 +65,11 @@ ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetThrowabl class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { public: RTPVisitor(HGraph* graph, - Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> hint_dex_cache, HandleCache* handle_cache, ArenaVector<HInstruction*>* worklist, bool is_first_run) : HGraphDelegateVisitor(graph), - class_loader_(class_loader), hint_dex_cache_(hint_dex_cache), handle_cache_(handle_cache), worklist_(worklist), @@ -103,7 +101,6 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { bool is_exact); private: - Handle<mirror::ClassLoader> class_loader_; Handle<mirror::DexCache> hint_dex_cache_; HandleCache* handle_cache_; ArenaVector<HInstruction*>* worklist_; @@ -111,13 +108,11 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { }; ReferenceTypePropagation::ReferenceTypePropagation(HGraph* graph, - Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> 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), worklist_(graph->GetArena()->Adapter(kArenaAllocReferenceTypePropagation)), @@ -152,12 +147,7 @@ void ReferenceTypePropagation::ValidateTypes() { } void ReferenceTypePropagation::Visit(HInstruction* instruction) { - RTPVisitor visitor(graph_, - class_loader_, - hint_dex_cache_, - &handle_cache_, - &worklist_, - is_first_run_); + RTPVisitor visitor(graph_, hint_dex_cache_, &handle_cache_, &worklist_, is_first_run_); instruction->Accept(&visitor); } @@ -331,12 +321,7 @@ void ReferenceTypePropagation::Run() { } void ReferenceTypePropagation::VisitBasicBlock(HBasicBlock* block) { - RTPVisitor visitor(graph_, - class_loader_, - hint_dex_cache_, - &handle_cache_, - &worklist_, - is_first_run_); + RTPVisitor visitor(graph_, hint_dex_cache_, &handle_cache_, &worklist_, is_first_run_); // Handle Phis first as there might be instructions in the same block who depend on them. for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { VisitPhi(it.Current()->AsPhi()); @@ -557,9 +542,8 @@ void ReferenceTypePropagation::RTPVisitor::UpdateReferenceTypeInfo(HInstruction* ScopedObjectAccess soa(Thread::Current()); ObjPtr<mirror::DexCache> dex_cache = FindDexCacheWithHint(soa.Self(), dex_file, hint_dex_cache_); - ObjPtr<mirror::Class> klass = - ClassLinker::LookupResolvedType(type_idx, dex_cache, class_loader_.Get()); - SetClassAsTypeInfo(instr, klass, is_exact); + // Get type from dex cache assuming it was populated by the verifier. + SetClassAsTypeInfo(instr, dex_cache->GetResolvedType(type_idx), is_exact); } void ReferenceTypePropagation::RTPVisitor::VisitNewInstance(HNewInstance* instr) { @@ -572,13 +556,25 @@ void ReferenceTypePropagation::RTPVisitor::VisitNewArray(HNewArray* instr) { SetClassAsTypeInfo(instr, instr->GetLoadClass()->GetClass().Get(), /* is_exact */ true); } +static mirror::Class* GetClassFromDexCache(Thread* self, + const DexFile& dex_file, + dex::TypeIndex type_idx, + Handle<mirror::DexCache> hint_dex_cache) + REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::DexCache> dex_cache = FindDexCacheWithHint(self, dex_file, hint_dex_cache); + // Get type from dex cache assuming it was populated by the verifier. + return dex_cache->GetResolvedType(type_idx); +} + void ReferenceTypePropagation::RTPVisitor::VisitParameterValue(HParameterValue* instr) { // We check if the existing type is valid: the inliner may have set it. if (instr->GetType() == Primitive::kPrimNot && !instr->GetReferenceTypeInfo().IsValid()) { - UpdateReferenceTypeInfo(instr, - instr->GetTypeIndex(), - instr->GetDexFile(), - /* is_exact */ false); + ScopedObjectAccess soa(Thread::Current()); + mirror::Class* resolved_class = GetClassFromDexCache(soa.Self(), + instr->GetDexFile(), + instr->GetTypeIndex(), + hint_dex_cache_); + SetClassAsTypeInfo(instr, resolved_class, /* is_exact */ false); } } diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 215e96786b..4663471729 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -33,7 +33,6 @@ namespace art { class ReferenceTypePropagation : public HOptimization { public: ReferenceTypePropagation(HGraph* graph, - Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> hint_dex_cache, VariableSizedHandleScope* handles, bool is_first_run, @@ -106,8 +105,6 @@ class ReferenceTypePropagation : public HOptimization { void ValidateTypes(); - Handle<mirror::ClassLoader> class_loader_; - // Note: hint_dex_cache_ is usually, but not necessarily, the dex cache associated with // 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(). diff --git a/compiler/optimizing/reference_type_propagation_test.cc b/compiler/optimizing/reference_type_propagation_test.cc index 84a4bab1a9..b061c871b0 100644 --- a/compiler/optimizing/reference_type_propagation_test.cc +++ b/compiler/optimizing/reference_type_propagation_test.cc @@ -38,7 +38,6 @@ class ReferenceTypePropagationTest : public CommonCompilerTest { void SetupPropagation(VariableSizedHandleScope* handles) { graph_->InitializeInexactObjectRTI(handles); propagation_ = new (&allocator_) ReferenceTypePropagation(graph_, - Handle<mirror::ClassLoader>(), Handle<mirror::DexCache>(), handles, true, diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 50ab11bc23..487e4dd498 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -499,11 +499,7 @@ GraphAnalysisResult SsaBuilder::BuildSsa() { // 4) Compute type of reference type instructions. The pass assumes that // NullConstant has been fixed up. - ReferenceTypePropagation(graph_, - class_loader_, - dex_cache_, - handles_, - /* is_first_run */ true).Run(); + ReferenceTypePropagation(graph_, dex_cache_, handles_, /* is_first_run */ true).Run(); // 5) HInstructionBuilder duplicated ArrayGet instructions with ambiguous type // (int/float or long/double) and marked ArraySets with ambiguous input type. diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h index 978f113ec4..45dac54115 100644 --- a/compiler/optimizing/ssa_builder.h +++ b/compiler/optimizing/ssa_builder.h @@ -48,11 +48,9 @@ namespace art { class SsaBuilder : public ValueObject { public: SsaBuilder(HGraph* graph, - Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> dex_cache, VariableSizedHandleScope* handles) : graph_(graph), - class_loader_(class_loader), dex_cache_(dex_cache), handles_(handles), agets_fixed_(false), @@ -117,7 +115,6 @@ class SsaBuilder : public ValueObject { void RemoveRedundantUninitializedStrings(); HGraph* graph_; - Handle<mirror::ClassLoader> class_loader_; Handle<mirror::DexCache> dex_cache_; VariableSizedHandleScope* const handles_; |