summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2016-03-11 09:57:57 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2016-03-11 09:57:57 +0000
commit07e3ca9a46801990d662c48d0fddedc63c4c053c (patch)
tree94fedc96b28c6a46d2b83c80b2cfefd4c2898f4a /compiler/optimizing
parentb7f257f353b1eb2db2732939a0404c118316891d (diff)
Fix thread race when fetching the ProfilingInfo object.
Problem is: 1) Compiler fetches the ProfilingInfo of A, it's null. 2) Mutator creates the ProfilingInfo. 3) Compiler notifies it's not using A anymore, calls ProfilingInfo::DecrementInlineUse -> Crash as we expected ProfilingInfo::IncrementUse to be called before. Also update some namings to better reflect what is going on. Change-Id: I55ea4c5d81988131467095e18a0d13a8be9d0ef7
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/inliner.cc26
1 files changed, 19 insertions, 7 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index bbdac262c4..d861e39c8b 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -224,16 +224,29 @@ static uint32_t FindClassIndexIn(mirror::Class* cls,
class ScopedProfilingInfoInlineUse {
public:
- explicit ScopedProfilingInfoInlineUse(ArtMethod* method) : method_(method) {
- Runtime::Current()->GetJit()->GetCodeCache()->NotifyInliningOf(method_, Thread::Current());
+ explicit ScopedProfilingInfoInlineUse(ArtMethod* method, Thread* self)
+ : method_(method),
+ self_(self),
+ // Fetch the profiling info ahead of using it. If it's null when fetching,
+ // we should not call JitCodeCache::DoneInlining.
+ profiling_info_(
+ Runtime::Current()->GetJit()->GetCodeCache()->NotifyCompilerUse(method, self)) {
}
~ScopedProfilingInfoInlineUse() {
- Runtime::Current()->GetJit()->GetCodeCache()->DoneInlining(method_, Thread::Current());
+ if (profiling_info_ != nullptr) {
+ size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
+ DCHECK_EQ(profiling_info_, method_->GetProfilingInfo(pointer_size));
+ Runtime::Current()->GetJit()->GetCodeCache()->DoneCompilerUse(method_, self_);
+ }
}
+ ProfilingInfo* GetProfilingInfo() const { return profiling_info_; }
+
private:
ArtMethod* const method_;
+ Thread* const self_;
+ ProfilingInfo* const profiling_info_;
};
bool HInliner::TryInline(HInvoke* invoke_instruction) {
@@ -287,15 +300,14 @@ 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();
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);
+ ScopedProfilingInfoInlineUse spiis(caller, soa.Self());
+ ProfilingInfo* profiling_info = spiis.GetProfilingInfo();
if (profiling_info != nullptr) {
const InlineCache& ic = *profiling_info->GetInlineCache(invoke_instruction->GetDexPc());
- if (ic.IsUnitialized()) {
+ if (ic.IsUninitialized()) {
VLOG(compiler) << "Interface or virtual call to "
<< PrettyMethod(method_index, caller_dex_file)
<< " is not hit and not inlined";