diff options
Diffstat (limited to 'compiler/optimizing/inliner.cc')
| -rw-r--r-- | compiler/optimizing/inliner.cc | 65 |
1 files changed, 31 insertions, 34 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index f9e78b0a8f..451aa38033 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -17,6 +17,7 @@ #include "inliner.h" #include "art_method-inl.h" +#include "base/enums.h" #include "builder.h" #include "class_linker.h" #include "constant_folding.h" @@ -35,7 +36,7 @@ #include "nodes.h" #include "optimizing_compiler.h" #include "reference_type_propagation.h" -#include "register_allocator.h" +#include "register_allocator_linear_scan.h" #include "quick/inline_method_analyser.h" #include "sharpening.h" #include "ssa_builder.h" @@ -151,7 +152,7 @@ static ArtMethod* FindVirtualOrInterfaceTarget(HInvoke* invoke, ArtMethod* resol } ClassLinker* cl = Runtime::Current()->GetClassLinker(); - size_t pointer_size = cl->GetImagePointerSize(); + PointerSize pointer_size = cl->GetImagePointerSize(); if (invoke->IsInvokeInterface()) { resolved_method = info.GetTypeHandle()->FindVirtualMethodForInterface( resolved_method, pointer_size); @@ -208,12 +209,8 @@ static uint32_t FindClassIndexIn(mirror::Class* cls, DCHECK(cls->IsProxyClass()) << PrettyClass(cls); // TODO: deal with proxy classes. } else if (IsSameDexFile(cls->GetDexFile(), dex_file)) { + DCHECK_EQ(cls->GetDexCache(), dex_cache.Get()); index = cls->GetDexTypeIndex(); - } else { - index = cls->FindTypeIndexInOtherDexFile(dex_file); - } - - if (index != DexFile::kDexNoIndex) { // 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 @@ -221,6 +218,14 @@ static uint32_t FindClassIndexIn(mirror::Class* cls, if (dex_cache->GetResolvedType(index) == nullptr) { dex_cache->SetResolvedType(index, cls); } + } else { + index = cls->FindTypeIndexInOtherDexFile(dex_file); + // 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 in the dex cache already. + if (index != DexFile::kDexNoIndex && dex_cache->GetResolvedType(index) != cls) { + index = DexFile::kDexNoIndex; + } } return index; @@ -239,7 +244,7 @@ class ScopedProfilingInfoInlineUse { ~ScopedProfilingInfoInlineUse() { if (profiling_info_ != nullptr) { - size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); DCHECK_EQ(profiling_info_, method_->GetProfilingInfo(pointer_size)); Runtime::Current()->GetJit()->GetCodeCache()->DoneCompilerUse(method_, self_); } @@ -273,7 +278,7 @@ bool HInliner::TryInline(HInvoke* invoke_instruction) { return false; } MethodReference ref = invoke_instruction->AsInvokeStaticOrDirect()->GetTargetMethod(); - mirror::DexCache* const dex_cache = (&caller_dex_file == ref.dex_file) + mirror::DexCache* const dex_cache = IsSameDexFile(caller_dex_file, *ref.dex_file) ? caller_compilation_unit_.GetDexCache().Get() : class_linker->FindDexCache(soa.Self(), *ref.dex_file); resolved_method = dex_cache->GetResolvedMethod( @@ -386,7 +391,7 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, } ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); - size_t pointer_size = class_linker->GetImagePointerSize(); + PointerSize pointer_size = class_linker->GetImagePointerSize(); if (invoke_instruction->IsInvokeInterface()) { resolved_method = ic.GetMonomorphicType()->FindVirtualMethodForInterface( resolved_method, pointer_size); @@ -478,7 +483,7 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, } ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); - size_t pointer_size = class_linker->GetImagePointerSize(); + PointerSize pointer_size = class_linker->GetImagePointerSize(); const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); bool all_targets_inlined = true; @@ -640,7 +645,7 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, return false; } ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); - size_t pointer_size = class_linker->GetImagePointerSize(); + PointerSize pointer_size = class_linker->GetImagePointerSize(); DCHECK(resolved_method != nullptr); ArtMethod* actual_method = nullptr; @@ -656,8 +661,8 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, } ArtMethod* new_method = nullptr; if (invoke_instruction->IsInvokeInterface()) { - new_method = ic.GetTypeAt(i)->GetEmbeddedImTableEntry( - method_index % mirror::Class::kImtSize, pointer_size); + new_method = ic.GetTypeAt(i)->GetImt(pointer_size)->Get( + method_index, pointer_size); if (new_method->IsRuntimeMethod()) { // Bail out as soon as we see a conflict trampoline in one of the target's // interface table. @@ -804,8 +809,6 @@ bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ArtMethod* metho bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, ArtMethod* method, HInstruction** return_replacement) { - const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); - if (method->IsProxyMethod()) { VLOG(compiler) << "Method " << PrettyMethod(method) << " is not inlined because of unimplemented inline support for proxy methods."; @@ -828,15 +831,6 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, return false; } - uint32_t method_index = FindMethodIndexIn( - method, caller_dex_file, invoke_instruction->GetDexMethodIndex()); - if (method_index == DexFile::kDexNoIndex) { - VLOG(compiler) << "Call to " - << PrettyMethod(method) - << " cannot be inlined because unaccessible to caller"; - return false; - } - bool same_dex_file = IsSameDexFile(*outer_compilation_unit_.GetDexFile(), *method->GetDexFile()); const DexFile::CodeItem* code_item = method->GetCodeItem(); @@ -873,7 +867,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, if (Runtime::Current()->UseJitCompilation() || !compiler_driver_->IsMethodVerifiedWithoutFailures( method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method) << " couldn't be verified, so it cannot be inlined"; return false; } @@ -883,7 +877,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, invoke_instruction->AsInvokeStaticOrDirect()->IsStaticWithImplicitClinitCheck()) { // Case of a static method that cannot be inlined because it implicitly // requires an initialization check of its declaring class. - VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method) << " is not inlined because it is static and requires a clinit" << " check that cannot be emitted due to Dex cache limitations"; return false; @@ -893,7 +887,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, return false; } - VLOG(compiler) << "Successfully inlined " << PrettyMethod(method_index, caller_dex_file); + VLOG(compiler) << "Successfully inlined " << PrettyMethod(method); MaybeRecordStat(kInlinedInvoke); return true; } @@ -1011,7 +1005,7 @@ bool HInliner::TryPatternSubstitution(HInvoke* invoke_instruction, invoke_instruction->GetBlock()->InsertInstructionBefore(iput, invoke_instruction); // Check whether the field is final. If it is, we need to add a barrier. - size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); + PointerSize pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size); DCHECK(resolved_field != nullptr); if (resolved_field->IsFinal()) { @@ -1037,7 +1031,7 @@ HInstanceFieldGet* HInliner::CreateInstanceFieldGet(Handle<mirror::DexCache> dex uint32_t field_index, HInstruction* obj) SHARED_REQUIRES(Locks::mutator_lock_) { - size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); + PointerSize pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size); DCHECK(resolved_field != nullptr); HInstanceFieldGet* iget = new (graph_->GetArena()) HInstanceFieldGet( @@ -1065,7 +1059,7 @@ HInstanceFieldSet* HInliner::CreateInstanceFieldSet(Handle<mirror::DexCache> dex HInstruction* obj, HInstruction* value) SHARED_REQUIRES(Locks::mutator_lock_) { - size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); + PointerSize pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size); DCHECK(resolved_field != nullptr); HInstanceFieldSet* iput = new (graph_->GetArena()) HInstanceFieldSet( @@ -1094,8 +1088,11 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, uint32_t method_index = resolved_method->GetDexMethodIndex(); ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache())); + Handle<mirror::ClassLoader> class_loader(handles_->NewHandle( + resolved_method->GetDeclaringClass()->GetClassLoader())); + DexCompilationUnit dex_compilation_unit( - caller_compilation_unit_.GetClassLoader(), + class_loader.ToJObject(), class_linker, callee_dex_file, code_item, @@ -1404,7 +1401,7 @@ bool HInliner::ArgumentTypesMoreSpecific(HInvoke* invoke_instruction, ArtMethod* } } - size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); // Iterate over the list of parameter types and test whether any of the // actual inputs has a more specific reference type than the type declared in @@ -1461,7 +1458,7 @@ void HInliner::FixUpReturnReferenceType(ArtMethod* resolved_method, // TODO: we could be more precise by merging the phi inputs but that requires // some functionality from the reference type propagation. DCHECK(return_replacement->IsPhi()); - size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); mirror::Class* cls = resolved_method->GetReturnType(false /* resolve */, pointer_size); return_replacement->SetReferenceTypeInfo(GetClassRTI(cls)); } |