1 /*
  2  * Copyright (c) 2001, 2021, 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.debugger.*;
 30 import sun.jvm.hotspot.oops.*;
 31 import sun.jvm.hotspot.types.*;
 32 import sun.jvm.hotspot.utilities.Observable;
 33 import sun.jvm.hotspot.utilities.Observer;
 34 
 35 public class ObjectMonitor extends VMObject {
 36   static {
 37     VM.registerVMInitializedObserver(new Observer() {
 38         public void update(Observable o, Object data) {
 39           initialize(VM.getVM().getTypeDataBase());
 40         }
 41       });
 42   }
 43 
 44   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
 45     heap = VM.getVM().getObjectHeap();
 46     Type type  = db.lookupType("ObjectMonitor");
 47     sun.jvm.hotspot.types.Field f = type.getField("_header");
 48     headerFieldOffset = f.getOffset();
 49     f = type.getField("_object");
 50     objectFieldOffset = f.getOffset();
 51     f = type.getField("_owner");
 52     ownerFieldOffset = f.getOffset();
 53     f = type.getField("_next_om");
 54     nextOMFieldOffset = f.getOffset();
 55     contentionsField  = new CIntField(type.getCIntegerField("_contentions"), 0);
 56     waitersField      = new CIntField(type.getCIntegerField("_waiters"), 0);
 57     recursionsField   = type.getCIntegerField("_recursions");
 58   }
 59 
 60   public ObjectMonitor(Address addr) {
 61     super(addr);
 62   }
 63 
 64   public Mark header() {
 65     return new Mark(addr.addOffsetTo(headerFieldOffset));
 66   }
 67 
 68   // FIXME
 69   //  void      set_header(markWord hdr);
 70 
 71   // FIXME: must implement and delegate to platform-dependent implementation
 72   //  public boolean isBusy();
 73   public boolean isEntered(sun.jvm.hotspot.runtime.Thread current) {
 74     Address o = owner();
 75     if (o.asLongValue() == 1) throw new InternalError("Check anonymous owner before calling isEntered()");
 76     if (current.threadObjectAddress().equals(o)) {
 77       return true;
 78     }
 79     return false;
 80   }
 81 
 82   public boolean isOwnedAnonymous() {
 83     return addr.getAddressAt(ownerFieldOffset).asLongValue() == 1;
 84   }
 85 
 86   public Address owner() {
 87     Address owner = addr.getAddressAt(ownerFieldOffset);
 88     if (owner.asLongValue() == 1) throw new InternalError("Check anonymous owner before calling isEntered()");
 89     return owner;
 90   }
 91 
 92   // FIXME
 93   //  void      set_owner(void* owner);
 94 
 95   public int    waiters() { return (int)waitersField.getValue(this); }
 96 
 97   public Address nextOM() { return addr.getAddressAt(nextOMFieldOffset); }
 98   // FIXME
 99   //  void      set_queue(void* owner);
100 
101   public long recursions() { return recursionsField.getValue(addr); }
102 
103   public OopHandle object() {
104     Address objAddr = addr.getAddressAt(objectFieldOffset);
105     if (objAddr == null) {
106       return null;
107     }
108     return objAddr.getOopHandleAt(0);
109   }
110 
111   public int contentions() {
112       return (int)contentionsField.getValue(this);
113   }
114 
115   // The following four either aren't expressed as typed fields in
116   // vmStructs.cpp because they aren't strongly typed in the VM, or
117   // would confuse the SA's type system.
118   private static ObjectHeap    heap;
119   private static long          headerFieldOffset;
120   private static long          objectFieldOffset;
121   private static long          ownerFieldOffset;
122   private static long          nextOMFieldOffset;
123   private static CIntField     contentionsField;
124   private static CIntField     waitersField;
125   private static CIntegerField recursionsField;
126   // FIXME: expose platform-dependent stuff
127 }