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 }