1 /*
  2  * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 package sun.jvm.hotspot.runtime;
 26 
 27 import java.util.*;
 28 
 29 import sun.jvm.hotspot.oops.*;
 30 import sun.jvm.hotspot.utilities.*;
 31 import sun.jvm.hotspot.debugger.*;
 32 import sun.jvm.hotspot.types.*;
 33 import sun.jvm.hotspot.utilities.Observable;
 34 import sun.jvm.hotspot.utilities.Observer;
 35 
 36 public class ObjectSynchronizer {
 37   static {
 38     VM.registerVMInitializedObserver(new Observer() {
 39         public void update(Observable o, Object data) {
 40           initialize(VM.getVM().getTypeDataBase());
 41         }
 42       });
 43   }
 44 
 45   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
 46     Type objectSynchronizerType = db.lookupType("ObjectSynchronizer");
 47     Type monitorListType = db.lookupType("MonitorList");
 48     Address monitorListAddr = objectSynchronizerType.getField("_in_use_list").getStaticFieldAddress();
 49     inUseListHead = monitorListType.getAddressField("_head").getAddress(monitorListAddr);
 50   }
 51 
 52   public long identityHashValueFor(Oop obj) {
 53     Mark mark = obj.getMark();
 54     if (mark.isUnlocked()) {
 55       // FIXME: can not generate marks in debugging system
 56       return mark.hash();
 57     } else if (mark.hasMonitor()) {
 58       if (VM.getVM().getCommandLineFlag("UseObjectMonitorTable").getBool()) {
 59         return mark.hash();
 60       }
 61       ObjectMonitor monitor = mark.monitor();
 62       Mark temp = monitor.header();
 63       return temp.hash();
 64     } else {
 65       if (Assert.ASSERTS_ENABLED) {
 66         Assert.that(VM.getVM().isDebugging(), "Can not access displaced header otherwise");
 67       }
 68       if (mark.hasDisplacedMarkHelper()) {
 69         Mark temp = mark.displacedMarkHelper();
 70         return temp.hash();
 71       }
 72       // FIXME: can not do anything else here in debugging system
 73       return 0;
 74     }
 75   }
 76 
 77   public static Iterator objectMonitorIterator() {
 78     return new ObjectMonitorIterator();
 79   }
 80 
 81   private static class ObjectMonitorIterator implements Iterator {
 82 
 83     // JVMTI raw monitors are not included in _in_use_list and
 84     // are not returned by this Iterator.
 85 
 86     ObjectMonitorIterator() {
 87       mon = inUseListHead == null ? null : new ObjectMonitor(inUseListHead);
 88     }
 89 
 90     public boolean hasNext() {
 91       return (mon != null);
 92     }
 93 
 94     public Object next() {
 95       ObjectMonitor ret = mon;
 96       if (ret == null) {
 97         throw new NoSuchElementException();
 98       }
 99       // advance to next entry
100       Address nextMon = mon.nextOM();
101       mon = nextMon == null ? null : new ObjectMonitor(nextMon);
102 
103       return ret;
104     }
105 
106     public void remove() {
107       throw new UnsupportedOperationException();
108     }
109 
110     private ObjectMonitor mon;
111   }
112 
113   private static Address inUseListHead;
114 
115 }