hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ObjectSynchronizer.java
author dcubed
Tue, 14 Oct 2014 10:32:12 -0700
changeset 27165 785a8d56024c
parent 5547 f4b087cbb361
permissions -rw-r--r--
8049737: Contended Locking reorder and cache line bucket Summary: JEP-143/JDK-8046133 - optimization #1 - reorder and cache line bucket. Reviewed-by: shade, dice, dholmes, dsimms Contributed-by: dave.dice@oracle.com, karen.kinnear@oracle.com, daniel.daugherty@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
27165
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
     2
 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
package sun.jvm.hotspot.runtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import sun.jvm.hotspot.oops.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
import sun.jvm.hotspot.utilities.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
import sun.jvm.hotspot.debugger.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.types.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
public class ObjectSynchronizer {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  static {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
    VM.registerVMInitializedObserver(new Observer() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
        public void update(Observable o, Object data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
          initialize(VM.getVM().getTypeDataBase());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
      });
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    Type type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
      type = db.lookupType("ObjectSynchronizer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
      AddressField blockListField;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
      blockListField = type.getAddressField("gBlockList");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
      gBlockListAddr = blockListField.getValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
      blockSize = db.lookupIntConstant("ObjectSynchronizer::_BLOCKSIZE").intValue();
27165
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    51
      defaultCacheLineSize = db.lookupIntConstant("DEFAULT_CACHE_LINE_SIZE").intValue();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    } catch (RuntimeException e) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    type = db.lookupType("ObjectMonitor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    objectMonitorTypeSize = type.getSize();
27165
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    55
    if ((objectMonitorTypeSize % defaultCacheLineSize) != 0) {
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    56
      // sizeof(ObjectMonitor) is not already a multiple of a cache line.
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    57
      // The ObjectMonitor allocation code in ObjectSynchronizer pads each
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    58
      // ObjectMonitor in a block to the next cache line boundary.
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    59
      int needLines = ((int)objectMonitorTypeSize / defaultCacheLineSize) + 1;
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    60
      objectMonitorTypeSize = needLines * defaultCacheLineSize;
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
    61
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  public long identityHashValueFor(Oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    Mark mark = obj.getMark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    if (mark.isUnlocked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      // FIXME: can not generate marks in debugging system
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
      return mark.hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    } else if (mark.hasMonitor()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
      ObjectMonitor monitor = mark.monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
      Mark temp = monitor.header();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
      return temp.hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
      if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
        Assert.that(VM.getVM().isDebugging(), "Can not access displaced header otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
      if (mark.hasDisplacedMarkHelper()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
        Mark temp = mark.displacedMarkHelper();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
        return temp.hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
      // FIXME: can not do anything else here in debugging system
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
      return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  public static Iterator objectMonitorIterator() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
    if (gBlockListAddr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
      return new ObjectMonitorIterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
      return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  private static class ObjectMonitorIterator implements Iterator {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    // JVMTI raw monitors are not pointed by gBlockList
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    // and are not included by this Iterator. May add them later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    ObjectMonitorIterator() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
      blockAddr = gBlockListAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      index = blockSize - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      block = new ObjectMonitor(blockAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    public boolean hasNext() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
      return (index > 0 || block.freeNext() != null);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    public Object next() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
      Address addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
      if (index > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
        addr = blockAddr.addOffsetTo(index*objectMonitorTypeSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
        blockAddr = block.freeNext();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
        index = blockSize - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
        addr = blockAddr.addOffsetTo(index*objectMonitorTypeSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
      index --;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
      return new ObjectMonitor(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    public void remove() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
      throw new UnsupportedOperationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    private ObjectMonitor block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    private int index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    private Address blockAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  private static Address gBlockListAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  private static int blockSize;
27165
785a8d56024c 8049737: Contended Locking reorder and cache line bucket
dcubed
parents: 5547
diff changeset
   133
  private static int defaultCacheLineSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  private static long objectMonitorTypeSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
}