Do a TryLock when allocating a ProfilingInfo from the interpreter.

This removes some thread contentions just for allocating ProfilingInfo.

bug:23128949

Change-Id: I9ff7d44c4b0ee272425cf4c6248d3065f67958f3
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 8858b48..a6c8c52 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -751,23 +751,38 @@
 ProfilingInfo* JitCodeCache::AddProfilingInfo(Thread* self,
                                               ArtMethod* method,
                                               const std::vector<uint32_t>& entries,
-                                              bool retry_allocation) {
-  ProfilingInfo* info = AddProfilingInfoInternal(self, method, entries);
+                                              bool retry_allocation)
+    // No thread safety analysis as we are using TryLock/Unlock explicitly.
+    NO_THREAD_SAFETY_ANALYSIS {
+  ProfilingInfo* info = nullptr;
+  if (!retry_allocation) {
+    // If we are allocating for the interpreter, just try to lock, to avoid
+    // lock contention with the JIT.
+    if (lock_.ExclusiveTryLock(self)) {
+      info = AddProfilingInfoInternal(self, method, entries);
+      lock_.ExclusiveUnlock(self);
+    }
+  } else {
+    {
+      MutexLock mu(self, lock_);
+      info = AddProfilingInfoInternal(self, method, entries);
+    }
 
-  if (info == nullptr && retry_allocation) {
-    GarbageCollectCache(self);
-    info = AddProfilingInfoInternal(self, method, entries);
+    if (info == nullptr) {
+      GarbageCollectCache(self);
+      MutexLock mu(self, lock_);
+      info = AddProfilingInfoInternal(self, method, entries);
+    }
   }
   return info;
 }
 
-ProfilingInfo* JitCodeCache::AddProfilingInfoInternal(Thread* self,
+ProfilingInfo* JitCodeCache::AddProfilingInfoInternal(Thread* self ATTRIBUTE_UNUSED,
                                                       ArtMethod* method,
                                                       const std::vector<uint32_t>& entries) {
   size_t profile_info_size = RoundUp(
       sizeof(ProfilingInfo) + sizeof(InlineCache) * entries.size(),
       sizeof(void*));
-  MutexLock mu(self, lock_);
 
   // Check whether some other thread has concurrently created it.
   ProfilingInfo* info = method->GetProfilingInfo(sizeof(void*));
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 4574edf..0117776 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -208,7 +208,7 @@
   ProfilingInfo* AddProfilingInfoInternal(Thread* self,
                                           ArtMethod* method,
                                           const std::vector<uint32_t>& entries)
-      REQUIRES(!lock_)
+      REQUIRES(lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
   // If a collection is in progress, wait for it to finish. Return