diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/inliner.cc | 36 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 2 |
2 files changed, 24 insertions, 14 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index ab1ef2973e..e3c2f5b37d 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -190,28 +190,34 @@ static uint32_t FindMethodIndexIn(ArtMethod* method, } } -static uint32_t FindClassIndexIn(mirror::Class* cls, const DexFile& dex_file) +static uint32_t FindClassIndexIn(mirror::Class* cls, + const DexFile& dex_file, + Handle<mirror::DexCache> dex_cache) SHARED_REQUIRES(Locks::mutator_lock_) { + uint32_t index = DexFile::kDexNoIndex; if (cls->GetDexCache() == nullptr) { - DCHECK(cls->IsArrayClass()); - // TODO: find the class in `dex_file`. - return DexFile::kDexNoIndex; + DCHECK(cls->IsArrayClass()) << PrettyClass(cls); + index = cls->FindTypeIndexInOtherDexFile(dex_file); } else if (cls->GetDexTypeIndex() == DexFile::kDexNoIndex16) { + DCHECK(cls->IsProxyClass()) << PrettyClass(cls); // TODO: deal with proxy classes. - return DexFile::kDexNoIndex; } else if (IsSameDexFile(cls->GetDexFile(), dex_file)) { + 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 // cache of the dex file of the class will be updated. - if (cls->GetDexCache()->GetResolvedType(cls->GetDexTypeIndex()) == nullptr) { - cls->GetDexCache()->SetResolvedType(cls->GetDexTypeIndex(), cls); + if (dex_cache->GetResolvedType(index) == nullptr) { + dex_cache->SetResolvedType(index, cls); } - return cls->GetDexTypeIndex(); - } else { - // TODO: find the class in `dex_file`. - return DexFile::kDexNoIndex; } + + return index; } bool HInliner::TryInline(HInvoke* invoke_instruction) { @@ -303,7 +309,7 @@ HInstanceFieldGet* HInliner::BuildGetReceiverClass(ClassLinker* class_linker, uint32_t dex_pc) const { ArtField* field = class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0); DCHECK_EQ(std::string(field->GetName()), "shadow$_klass_"); - return new (graph_->GetArena()) HInstanceFieldGet( + HInstanceFieldGet* result = new (graph_->GetArena()) HInstanceFieldGet( receiver, Primitive::kPrimNot, field->GetOffset(), @@ -313,6 +319,9 @@ HInstanceFieldGet* HInliner::BuildGetReceiverClass(ClassLinker* class_linker, *field->GetDexFile(), handles_->NewHandle(field->GetDexCache()), dex_pc); + // The class of a field is effectively final, and does not have any memory dependencies. + result->SetSideEffects(SideEffects::None()); + return result; } bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, @@ -322,7 +331,8 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, << invoke_instruction->DebugName(); const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); - uint32_t class_index = FindClassIndexIn(ic.GetMonomorphicType(), caller_dex_file); + uint32_t class_index = FindClassIndexIn( + ic.GetMonomorphicType(), caller_dex_file, caller_compilation_unit_.GetDexCache()); if (class_index == DexFile::kDexNoIndex) { VLOG(compiler) << "Call to " << PrettyMethod(resolved_method) << " from inline cache is not inlined because its class is not" diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index f7307adac0..399afabea6 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2068,6 +2068,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { } SideEffects GetSideEffects() const { return side_effects_; } + void SetSideEffects(SideEffects other) { side_effects_ = other; } void AddSideEffects(SideEffects other) { side_effects_.Add(other); } size_t GetLifetimePosition() const { return lifetime_position_; } @@ -2106,7 +2107,6 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { protected: virtual const HUserRecord<HInstruction*> InputRecordAt(size_t i) const = 0; virtual void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) = 0; - void SetSideEffects(SideEffects other) { side_effects_ = other; } private: void RemoveEnvironmentUser(HUseListNode<HEnvironment*>* use_node) { env_uses_.Remove(use_node); } |