< prev index next >

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java

Print this page
@@ -42,18 +42,21 @@
  
  public class JavaThread extends Thread {
    private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.JavaThread.DEBUG") != null;
  
    private static long          threadObjFieldOffset;
+   private static long          lockStackTopOffset;
+   private static long          lockStackBaseOffset;
    private static AddressField  anchorField;
    private static AddressField  lastJavaSPField;
    private static AddressField  lastJavaPCField;
    private static CIntegerField threadStateField;
    private static AddressField  osThreadField;
    private static AddressField  stackBaseField;
    private static CIntegerField stackSizeField;
    private static CIntegerField terminatedField;
+   private static long oopPtrSize;
  
    private static JavaThreadPDAccess access;
  
    // JavaThreadStates read from underlying process
    private static int           UNINITIALIZED;

@@ -82,10 +85,11 @@
    }
  
    private static synchronized void initialize(TypeDataBase db) {
      Type type = db.lookupType("JavaThread");
      Type anchorType = db.lookupType("JavaFrameAnchor");
+     Type typeLockStack = db.lookupType("LockStack");
  
      threadObjFieldOffset = type.getField("_threadObj").getOffset();
  
      anchorField       = type.getAddressField("_anchor");
      lastJavaSPField   = anchorType.getAddressField("_last_Java_sp");

@@ -94,10 +98,14 @@
      osThreadField     = type.getAddressField("_osthread");
      stackBaseField    = type.getAddressField("_stack_base");
      stackSizeField    = type.getCIntegerField("_stack_size");
      terminatedField   = type.getCIntegerField("_terminated");
  
+     lockStackTopOffset = type.getField("_lock_stack").getOffset() + typeLockStack.getField("_top").getOffset();
+     lockStackBaseOffset = type.getField("_lock_stack").getOffset() + typeLockStack.getField("_base[0]").getOffset();
+     oopPtrSize = VM.getVM().getAddressSize();
+ 
      UNINITIALIZED     = db.lookupIntConstant("_thread_uninitialized").intValue();
      NEW               = db.lookupIntConstant("_thread_new").intValue();
      NEW_TRANS         = db.lookupIntConstant("_thread_new_trans").intValue();
      IN_NATIVE         = db.lookupIntConstant("_thread_in_native").intValue();
      IN_NATIVE_TRANS   = db.lookupIntConstant("_thread_in_native_trans").intValue();

@@ -390,10 +398,27 @@
      // Be robust
      if (sp == null) return false;
      return stackBase.greaterThan(a) && sp.lessThanOrEqual(a);
    }
  
+   public boolean isLockOwned(OopHandle obj) {
+     long current = lockStackBaseOffset;
+     long end = addr.getJIntAt(lockStackTopOffset);
+     if (Assert.ASSERTS_ENABLED) {
+       Assert.that(current <= end, "current stack offset must be above base offset");
+     }
+ 
+     while (current < end) {
+       Address oop = addr.getAddressAt(current);
+       if (oop.equals(obj)) {
+         return true;
+       }
+       current += oopPtrSize;
+     }
+     return false;
+   }
+ 
    public boolean isLockOwned(Address a) {
      Address stackBase = getStackBase();
      Address stackLimit = stackBase.addOffsetTo(-getStackSize());
  
      return stackBase.greaterThan(a) && stackLimit.lessThanOrEqual(a);
< prev index next >