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 ObjectMonitor monitor = mark.monitor(); 59 Mark temp = monitor.header(); 60 return temp.hash(); 61 } else { 62 if (Assert.ASSERTS_ENABLED) { 63 Assert.that(VM.getVM().isDebugging(), "Can not access displaced header otherwise"); 64 } 65 if (mark.hasDisplacedMarkHelper()) { 66 Mark temp = mark.displacedMarkHelper(); 67 return temp.hash(); 68 } 69 // FIXME: can not do anything else here in debugging system 70 return 0; 71 } 72 } 73 74 public static Iterator objectMonitorIterator() { 75 return new ObjectMonitorIterator(); 76 } 77 78 private static class ObjectMonitorIterator implements Iterator { 79 80 // JVMTI raw monitors are not included in _in_use_list and 81 // are not returned by this Iterator. 82 83 ObjectMonitorIterator() { 84 mon = inUseListHead == null ? null : new ObjectMonitor(inUseListHead); 85 } 86 87 public boolean hasNext() { 88 return (mon != null); 89 } 90 91 public Object next() { 92 ObjectMonitor ret = mon; 93 if (ret == null) { 94 throw new NoSuchElementException(); 95 } 96 // advance to next entry 97 Address nextMon = mon.nextOM(); 98 mon = nextMon == null ? null : new ObjectMonitor(nextMon); 99 100 return ret; 101 } 102 103 public void remove() { 104 throw new UnsupportedOperationException(); 105 } 106 107 private ObjectMonitor mon; 108 } 109 110 private static Address inUseListHead; 111 112 }