diff src/share/vm/oops/methodData.cpp @ 14726:92aa6797d639

Backed out merge changeset: b51e29501f30 Backed out merge revision to its first parent (8f483e200405)
author Doug Simon <doug.simon@oracle.com>
date Mon, 24 Mar 2014 21:30:43 +0100
parents b51e29501f30
children
line wrap: on
line diff
--- a/src/share/vm/oops/methodData.cpp	Fri Mar 21 16:36:59 2014 -0700
+++ b/src/share/vm/oops/methodData.cpp	Mon Mar 24 21:30:43 2014 +0100
@@ -1125,8 +1125,7 @@
 }
 
 // Initialize the MethodData* corresponding to a given method.
-MethodData::MethodData(methodHandle method, int size, TRAPS)
-  : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {
+MethodData::MethodData(methodHandle method, int size, TRAPS) {
   // Set the method back-pointer.
   _method = method();
   initialize();
@@ -1304,7 +1303,7 @@
   return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells));
 }
 
-ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent) {
+ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp) {
   DataLayout* end = extra_data_limit();
 
   for (;; dp = next_extra(dp)) {
@@ -1326,11 +1325,10 @@
       if (m != NULL) {
         SpeculativeTrapData* data = new SpeculativeTrapData(dp);
         // data->method() may be null in case of a concurrent
-        // allocation. Maybe it's for the same method. Try to use that
+        // allocation. Assume it's for the same method and use that
         // entry in that case.
         if (dp->bci() == bci) {
           if (data->method() == NULL) {
-            assert(concurrent, "impossible because no concurrent allocation");
             return NULL;
           } else if (data->method() == m) {
             return data;
@@ -1359,40 +1357,40 @@
   // Allocation in the extra data space has to be atomic because not
   // all entries have the same size and non atomic concurrent
   // allocation would result in a corrupted extra data space.
-  ProfileData* result = bci_to_extra_data_helper(bci, m, dp, true);
-  if (result != NULL) {
-    return result;
-  }
-
-  if (create_if_missing && dp < end) {
-    MutexLocker ml(&_extra_data_lock);
-    // Check again now that we have the lock. Another thread may
-    // have added extra data entries.
-    ProfileData* result = bci_to_extra_data_helper(bci, m, dp, false);
-    if (result != NULL || dp >= end) {
+  while (true) {
+    ProfileData* result = bci_to_extra_data_helper(bci, m, dp);
+    if (result != NULL) {
       return result;
     }
 
-    assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free");
-    assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info");
-    u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag;
-    // SpeculativeTrapData is 2 slots. Make sure we have room.
-    if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) {
-      return NULL;
+    if (create_if_missing && dp < end) {
+      assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free");
+      assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info");
+      u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag;
+      // SpeculativeTrapData is 2 slots. Make sure we have room.
+      if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) {
+        return NULL;
+      }
+      DataLayout temp;
+      temp.initialize(tag, bci, 0);
+      // May have been set concurrently
+      if (dp->header() != temp.header() && !dp->atomic_set_header(temp.header())) {
+        // Allocation failure because of concurrent allocation. Try
+        // again.
+        continue;
+      }
+      assert(dp->tag() == tag, "sane");
+      assert(dp->bci() == bci, "no concurrent allocation");
+      if (tag == DataLayout::bit_data_tag) {
+        return new BitData(dp);
+      } else {
+        // If being allocated concurrently, one trap may be lost
+        SpeculativeTrapData* data = new SpeculativeTrapData(dp);
+        data->set_method(m);
+        return data;
+      }
     }
-    DataLayout temp;
-    temp.initialize(tag, bci, 0);
-
-    dp->set_header(temp.header());
-    assert(dp->tag() == tag, "sane");
-    assert(dp->bci() == bci, "no concurrent allocation");
-    if (tag == DataLayout::bit_data_tag) {
-      return new BitData(dp);
-    } else {
-      SpeculativeTrapData* data = new SpeculativeTrapData(dp);
-      data->set_method(m);
-      return data;
-    }
+    return NULL;
   }
   return NULL;
 }