diff options
| author | 2016-03-07 14:29:04 +0000 | |
|---|---|---|
| committer | 2016-03-09 17:25:19 +0000 | |
| commit | b6e20ae17d0881a66c22532e4152ce6779454a92 (patch) | |
| tree | 35d7fbfb812aef11ea51010794dce26eb91c1ae4 /compiler/optimizing | |
| parent | 8a8c84114b16b8971bc2d3c5c7e0e31470d1a68b (diff) | |
Clear inline caches at each full GC.
This fixes occasional failures of 141-class-unload.
Also fix a bug where clearing inline caches also cleared the dex
pc associated with it.
bug:26846185
bug:23128949
Change-Id: I77bf1dee229d7764c3cc21440829c7fba7b37001
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/inliner.cc | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 3e3719e6ea..bbdac262c4 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -28,6 +28,8 @@ #include "driver/dex_compilation_unit.h" #include "instruction_simplifier.h" #include "intrinsics.h" +#include "jit/jit.h" +#include "jit/jit_code_cache.h" #include "mirror/class_loader.h" #include "mirror/dex_cache.h" #include "nodes.h" @@ -220,6 +222,20 @@ static uint32_t FindClassIndexIn(mirror::Class* cls, return index; } +class ScopedProfilingInfoInlineUse { + public: + explicit ScopedProfilingInfoInlineUse(ArtMethod* method) : method_(method) { + Runtime::Current()->GetJit()->GetCodeCache()->NotifyInliningOf(method_, Thread::Current()); + } + + ~ScopedProfilingInfoInlineUse() { + Runtime::Current()->GetJit()->GetCodeCache()->DoneInlining(method_, Thread::Current()); + } + + private: + ArtMethod* const method_; +}; + bool HInliner::TryInline(HInvoke* invoke_instruction) { if (invoke_instruction->IsInvokeUnresolved()) { return false; // Don't bother to move further if we know the method is unresolved. @@ -272,29 +288,32 @@ bool HInliner::TryInline(HInvoke* invoke_instruction) { // Check if we can use an inline cache. ArtMethod* caller = graph_->GetArtMethod(); size_t pointer_size = class_linker->GetImagePointerSize(); - // Under JIT, we should always know the caller. - DCHECK(!Runtime::Current()->UseJit() || (caller != nullptr)); - if (caller != nullptr && caller->GetProfilingInfo(pointer_size) != nullptr) { + if (Runtime::Current()->UseJit()) { + // Under JIT, we should always know the caller. + DCHECK(caller != nullptr); + ScopedProfilingInfoInlineUse spiis(caller); ProfilingInfo* profiling_info = caller->GetProfilingInfo(pointer_size); - const InlineCache& ic = *profiling_info->GetInlineCache(invoke_instruction->GetDexPc()); - if (ic.IsUnitialized()) { - VLOG(compiler) << "Interface or virtual call to " - << PrettyMethod(method_index, caller_dex_file) - << " is not hit and not inlined"; - return false; - } else if (ic.IsMonomorphic()) { - MaybeRecordStat(kMonomorphicCall); - return TryInlineMonomorphicCall(invoke_instruction, resolved_method, ic); - } else if (ic.IsPolymorphic()) { - MaybeRecordStat(kPolymorphicCall); - return TryInlinePolymorphicCall(invoke_instruction, resolved_method, ic); - } else { - DCHECK(ic.IsMegamorphic()); - VLOG(compiler) << "Interface or virtual call to " - << PrettyMethod(method_index, caller_dex_file) - << " is megamorphic and not inlined"; - MaybeRecordStat(kMegamorphicCall); - return false; + if (profiling_info != nullptr) { + const InlineCache& ic = *profiling_info->GetInlineCache(invoke_instruction->GetDexPc()); + if (ic.IsUnitialized()) { + VLOG(compiler) << "Interface or virtual call to " + << PrettyMethod(method_index, caller_dex_file) + << " is not hit and not inlined"; + return false; + } else if (ic.IsMonomorphic()) { + MaybeRecordStat(kMonomorphicCall); + return TryInlineMonomorphicCall(invoke_instruction, resolved_method, ic); + } else if (ic.IsPolymorphic()) { + MaybeRecordStat(kPolymorphicCall); + return TryInlinePolymorphicCall(invoke_instruction, resolved_method, ic); + } else { + DCHECK(ic.IsMegamorphic()); + VLOG(compiler) << "Interface or virtual call to " + << PrettyMethod(method_index, caller_dex_file) + << " is megamorphic and not inlined"; + MaybeRecordStat(kMegamorphicCall); + return false; + } } } |