changeset 23040:78e6ba51f14b

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 20 Nov 2015 01:58:58 +0100
parents af898ba7cfda (current diff) 28cb37047aa0 (diff)
children 48da66152e59
files
diffstat 1 files changed, 73 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Nov 20 01:58:05 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Nov 20 01:58:58 2015 +0100
@@ -116,6 +116,77 @@
  * href="http://dl.acm.org/citation.cfm?id=1167515.1167496"> Eliminating synchronization-related
  * atomic operations with biased locking and bulk rebiasing</a> by Kenneth Russell and David
  * Detlefs.
+ *
+ * Comment below is reproduced from {@code markOop.hpp} for convenience:
+ *
+ * <pre>
+ *  Bit-format of an object header (most significant first, big endian layout below):
+ *  32 bits:
+ *  --------
+ *             hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
+ *             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
+ *             size:32 ------------------------------------------>| (CMS free block)
+ *             PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
+ *
+ *  64 bits:
+ *  --------
+ *  unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)
+ *  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
+ *  PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
+ *  size:64 ----------------------------------------------------->| (CMS free block)
+ *
+ *  unused:25 hash:31 -->| cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && normal object)
+ *  JavaThread*:54 epoch:2 cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && biased object)
+ *  narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
+ *  unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
+ *
+ *  - hash contains the identity hash value: largest value is
+ *    31 bits, see os::random().  Also, 64-bit vm's require
+ *    a hash value no bigger than 32 bits because they will not
+ *    properly generate a mask larger than that: see library_call.cpp
+ *    and c1_CodePatterns_sparc.cpp.
+ *
+ *  - the biased lock pattern is used to bias a lock toward a given
+ *    thread. When this pattern is set in the low three bits, the lock
+ *    is either biased toward a given thread or "anonymously" biased,
+ *    indicating that it is possible for it to be biased. When the
+ *    lock is biased toward a given thread, locking and unlocking can
+ *    be performed by that thread without using atomic operations.
+ *    When a lock's bias is revoked, it reverts back to the normal
+ *    locking scheme described below.
+ *
+ *    Note that we are overloading the meaning of the "unlocked" state
+ *    of the header. Because we steal a bit from the age we can
+ *    guarantee that the bias pattern will never be seen for a truly
+ *    unlocked object.
+ *
+ *    Note also that the biased state contains the age bits normally
+ *    contained in the object header. Large increases in scavenge
+ *    times were seen when these bits were absent and an arbitrary age
+ *    assigned to all biased objects, because they tended to consume a
+ *    significant fraction of the eden semispaces and were not
+ *    promoted promptly, causing an increase in the amount of copying
+ *    performed. The runtime system aligns all JavaThread* pointers to
+ *    a very large value (currently 128 bytes (32bVM) or 256 bytes (64bVM))
+ *    to make room for the age bits & the epoch bits (used in support of
+ *    biased locking), and for the CMS "freeness" bit in the 64bVM (+COOPs).
+ *
+ *    [JavaThread* | epoch | age | 1 | 01]       lock is biased toward given thread
+ *    [0           | epoch | age | 1 | 01]       lock is anonymously biased
+ *
+ *  - the two lock bits are used to describe three states: locked/unlocked and monitor.
+ *
+ *    [ptr             | 00]  locked             ptr points to real header on stack
+ *    [header      | 0 | 01]  unlocked           regular object header
+ *    [ptr             | 10]  monitor            inflated lock (header is wapped out)
+ *    [ptr             | 11]  marked             used by markSweep to mark an object
+ *                                               not valid at any other time
+ *
+ *    We assume that stack/thread pointers have the lowest two bits cleared.
+ * </pre>
+ *
+ * Note that {@code Thread::allocate} enforces {@code JavaThread} objects to be aligned
+ * appropriately to comply with the layouts above.
  */
 public class MonitorSnippets implements Snippets {
 
@@ -602,7 +673,7 @@
      * Counters for the various paths for acquiring a lock. The counters whose names start with
      * {@code "lock"} are mutually exclusive. The other counters are for paths that may be shared.
      */
-    private static final SnippetCounter.Group lockCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("MonitorEnters") : null;
+    public static final SnippetCounter.Group lockCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("MonitorEnters") : null;
     public static final SnippetCounter lockBiasExisting = new SnippetCounter(lockCounters, "lock{bias:existing}", "bias-locked previously biased object");
     public static final SnippetCounter lockBiasAcquired = new SnippetCounter(lockCounters, "lock{bias:acquired}", "bias-locked newly biased object");
     public static final SnippetCounter lockBiasTransfer = new SnippetCounter(lockCounters, "lock{bias:transfer}", "bias-locked, biased transferred");
@@ -619,7 +690,7 @@
      * Counters for the various paths for releasing a lock. The counters whose names start with
      * {@code "unlock"} are mutually exclusive. The other counters are for paths that may be shared.
      */
-    private static final SnippetCounter.Group unlockCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("MonitorExits") : null;
+    public static final SnippetCounter.Group unlockCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("MonitorExits") : null;
     public static final SnippetCounter unlockBias = new SnippetCounter(unlockCounters, "unlock{bias}", "bias-unlocked an object");
     public static final SnippetCounter unlockCas = new SnippetCounter(unlockCounters, "unlock{cas}", "cas-unlocked an object");
     public static final SnippetCounter unlockCasRecursive = new SnippetCounter(unlockCounters, "unlock{cas:recursive}", "cas-unlocked an object, recursive");