alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ThreadReferenceImpl.java)

This example Java source code file (ThreadReferenceImpl.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arraylist, incompatiblethreadstateexception, info, iterator, javathread, javavframe, jdi, list, objectmonitor, objectreferenceimpl, oophandle, stackframe, string, threadreferenceimpl, unsupportedoperationexception, util

The ThreadReferenceImpl.java Java example source code

/*
 * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.jdi;

import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.runtime.JavaThread;
import sun.jvm.hotspot.runtime.OSThread;
//import sun.jvm.hotspot.runtime.StackFrameStream;
import sun.jvm.hotspot.runtime.JavaVFrame;
import sun.jvm.hotspot.runtime.JavaThreadState;
import sun.jvm.hotspot.runtime.MonitorInfo;
import sun.jvm.hotspot.runtime.ObjectMonitor;
import sun.jvm.hotspot.oops.Oop;
import sun.jvm.hotspot.oops.ObjectHeap;
import sun.jvm.hotspot.oops.Instance;
import sun.jvm.hotspot.oops.OopUtilities;
import sun.jvm.hotspot.oops.Klass;
import sun.jvm.hotspot.utilities.Assert;
import com.sun.jdi.*;
import java.util.*;

public class ThreadReferenceImpl extends ObjectReferenceImpl
             implements ThreadReference, /* imports */ JVMTIThreadState {

    private JavaThread myJavaThread;
    private ArrayList frames;    // StackFrames
    private List ownedMonitors; // List<ObjectReferenceImpl>
    private List ownedMonitorsInfo; // List<MonitorInfo>
    private ObjectReferenceImpl currentContendingMonitor;

    ThreadReferenceImpl(VirtualMachine aVm, sun.jvm.hotspot.runtime.JavaThread aRef) {
        // We are given a JavaThread and save it in our myJavaThread field.
        // But, our parent class is an ObjectReferenceImpl so we need an Oop
        // for it.  JavaThread is a wrapper around a Thread Oop so we get
        // that Oop and give it to our super.
        // We can get it back again by calling ref().
        super(aVm, (Instance)aRef.getThreadObj());
        myJavaThread = aRef;
    }

    ThreadReferenceImpl(VirtualMachine vm, Instance oRef) {
        // Instance must be of type java.lang.Thread
        super(vm, oRef);

        // JavaThread retrieved from java.lang.Thread instance may be null.
        // This is the case for threads not-started and for zombies. Wherever
        // appropriate, check for null instead of resulting in NullPointerException.
        myJavaThread = OopUtilities.threadOopGetJavaThread(oRef);
    }

    // return value may be null. refer to the comment in constructor.
    JavaThread getJavaThread() {
        return myJavaThread;
    }

    protected String description() {
        return "ThreadReference " + uniqueID();
    }

    /**
     * Note that we only cache the name string while suspended because
     * it can change via Thread.setName arbitrarily
     */
    public String name() {
        return OopUtilities.threadOopGetName(ref());
    }

    public void suspend() {
        vm.throwNotReadOnlyException("ThreadReference.suspend()");
    }

    public void resume() {
        vm.throwNotReadOnlyException("ThreadReference.resume()");
    }

    public int suspendCount() {
        // all threads are "suspended" when we attach to process or core.
        // we interpret this as one suspend.
        return 1;
    }

    public void stop(ObjectReference throwable) throws InvalidTypeException {
        vm.throwNotReadOnlyException("ThreadReference.stop()");
    }

    public void interrupt() {
        vm.throwNotReadOnlyException("ThreadReference.interrupt()");
    }

    // refer to jvmtiEnv::GetThreadState
    private int jvmtiGetThreadState() {
        // get most state bits
        int state = OopUtilities.threadOopGetThreadStatus(ref());
        // add more state bits
        if (myJavaThread != null) {
            JavaThreadState jts = myJavaThread.getThreadState();
            if (myJavaThread.isBeingExtSuspended()) {
                state |= JVMTI_THREAD_STATE_SUSPENDED;
            }
            if (jts == JavaThreadState.IN_NATIVE) {
                state |= JVMTI_THREAD_STATE_IN_NATIVE;
            }
            OSThread osThread = myJavaThread.getOSThread();
            if (osThread != null && osThread.interrupted()) {
                state |= JVMTI_THREAD_STATE_INTERRUPTED;
            }
        }
        return state;
    }

    public int status() {
        int state = jvmtiGetThreadState();
        int status = THREAD_STATUS_UNKNOWN;
        // refer to map2jdwpThreadStatus in util.c (back-end)
        if (! ((state & JVMTI_THREAD_STATE_ALIVE) != 0) ) {
            if ((state & JVMTI_THREAD_STATE_TERMINATED) != 0) {
                status = THREAD_STATUS_ZOMBIE;
            } else {
                status = THREAD_STATUS_NOT_STARTED;
            }
        } else {
            if ((state & JVMTI_THREAD_STATE_SLEEPING) != 0) {
                status = THREAD_STATUS_SLEEPING;
            } else if ((state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
                status = THREAD_STATUS_MONITOR;
            } else if ((state & JVMTI_THREAD_STATE_WAITING) != 0) {
                status = THREAD_STATUS_WAIT;
            } else if ((state & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
                status = THREAD_STATUS_RUNNING;
            }
        }
        return status;
    }

    public boolean isSuspended() { //fixme jjh
        // If we want to support doing this for a VM which was being
        // debugged, then we need to fix this.
        // In the meantime, we will say all threads are suspended,
        // otherwise, some things won't work, like the jdb 'up' cmd.
        return true;
    }

    public boolean isAtBreakpoint() { //fixme jjh
        // If we want to support doing this for a VM which was being
        // debugged, then we need to fix this.
        return false;
    }

    public ThreadGroupReference threadGroup() {
        return (ThreadGroupReferenceImpl)vm.threadGroupMirror(
               (Instance)OopUtilities.threadOopGetThreadGroup(ref()));
    }

    public int frameCount() throws IncompatibleThreadStateException  { //fixme jjh
        privateFrames(0, -1);
        return frames.size();
    }

    public List frames() throws IncompatibleThreadStateException  {
        return privateFrames(0, -1);
    }

    public StackFrame frame(int index) throws IncompatibleThreadStateException  {
        List list = privateFrames(index, 1);
        return (StackFrame)list.get(0);
    }

    public List frames(int start, int length)
                              throws IncompatibleThreadStateException  {
        if (length < 0) {
            throw new IndexOutOfBoundsException(
                "length must be greater than or equal to zero");
        }
        return privateFrames(start, length);
    }

    /**
     * Private version of frames() allows "-1" to specify all
     * remaining frames.
     */

    private List privateFrames(int start, int length)
                              throws IncompatibleThreadStateException  {
        if (myJavaThread == null) {
            // for zombies and yet-to-be-started threads we need to throw exception
            throw new IncompatibleThreadStateException();
        }
        if (frames == null) {
            frames = new ArrayList(10);
            JavaVFrame myvf = myJavaThread.getLastJavaVFrameDbg();
            while (myvf != null) {
                StackFrame myFrame = new StackFrameImpl(vm, this, myvf);
                //fixme jjh null should be a Location
                frames.add(myFrame);
                myvf = (JavaVFrame)myvf.javaSender();
            }
        }

        List retVal;
        if (frames.size() == 0) {
            retVal = new ArrayList(0);
        } else {
            int toIndex = start + length;
            if (length == -1) {
                toIndex = frames.size();
            }
            retVal = frames.subList(start, toIndex);
        }
        return Collections.unmodifiableList(retVal);
    }

    // refer to JvmtiEnvBase::get_owned_monitors
    public List ownedMonitors()  throws IncompatibleThreadStateException {
        if (vm.canGetOwnedMonitorInfo() == false) {
            throw new UnsupportedOperationException();
        }

        if (myJavaThread == null) {
           throw new IncompatibleThreadStateException();
        }

        if (ownedMonitors != null) {
            return ownedMonitors;
        }

        ownedMonitorsWithStackDepth();

        for (Iterator omi = ownedMonitorsInfo.iterator(); omi.hasNext(); ) {
            //FIXME : Change the MonitorInfoImpl cast to com.sun.jdi.MonitorInfo
            //        when hotspot start building with jdk1.6.
            ownedMonitors.add(((MonitorInfoImpl)omi.next()).monitor());
        }

        return ownedMonitors;
    }

    // new method since 1.6.
    // Real body will be supplied later.
    public List ownedMonitorsAndFrames() throws IncompatibleThreadStateException {
        if (!vm.canGetMonitorFrameInfo()) {
            throw new UnsupportedOperationException(
                "target does not support getting Monitor Frame Info");
        }

        if (myJavaThread == null) {
           throw new IncompatibleThreadStateException();
        }

        if (ownedMonitorsInfo != null) {
            return ownedMonitorsInfo;
        }

        ownedMonitorsWithStackDepth();
        return ownedMonitorsInfo;
    }

    private void ownedMonitorsWithStackDepth() {

        ownedMonitorsInfo = new ArrayList();
        List lockedObjects = new ArrayList(); // List<OopHandle>
        List stackDepth = new ArrayList(); // List<int>
        ObjectMonitor waitingMonitor = myJavaThread.getCurrentWaitingMonitor();
        ObjectMonitor pendingMonitor = myJavaThread.getCurrentPendingMonitor();
        OopHandle waitingObj = null;
        if (waitingMonitor != null) {
            // save object of current wait() call (if any) for later comparison
            waitingObj = waitingMonitor.object();
        }
        OopHandle pendingObj = null;
        if (pendingMonitor != null) {
            // save object of current enter() call (if any) for later comparison
            pendingObj = pendingMonitor.object();
        }

        JavaVFrame frame = myJavaThread.getLastJavaVFrameDbg();
        int depth=0;
        while (frame != null) {
            List frameMonitors = frame.getMonitors();  // List<MonitorInfo>
            for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
                sun.jvm.hotspot.runtime.MonitorInfo mi = (sun.jvm.hotspot.runtime.MonitorInfo) miItr.next();
                if (mi.eliminated() && frame.isCompiledFrame()) {
                  continue; // skip eliminated monitor
                }
                OopHandle obj = mi.owner();
                if (obj == null) {
                    // this monitor doesn't have an owning object so skip it
                    continue;
                }

                if (obj.equals(waitingObj)) {
                    // the thread is waiting on this monitor so it isn't really owned
                    continue;
                }

                if (obj.equals(pendingObj)) {
                    // the thread is pending on this monitor so it isn't really owned
                    continue;
                }

                boolean found = false;
                for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
                    // check for recursive locks
                    if (obj.equals(loItr.next())) {
                        found = true;
                        break;
                    }
                }
                if (found) {
                    // already have this object so don't include it
                    continue;
                }
                // add the owning object to our list
                lockedObjects.add(obj);
                stackDepth.add(new Integer(depth));
            }
            frame = (JavaVFrame) frame.javaSender();
            depth++;
        }

        // now convert List<OopHandle> to List
        ObjectHeap heap = vm.saObjectHeap();
        Iterator stk = stackDepth.iterator();
        for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
            Oop obj = heap.newOop((OopHandle)loItr.next());
            ownedMonitorsInfo.add(new MonitorInfoImpl(vm, vm.objectMirror(obj), this,
                                                              ((Integer)stk.next()).intValue()));
        }
    }

    // refer to JvmtiEnvBase::get_current_contended_monitor
    public ObjectReference currentContendedMonitor()
                              throws IncompatibleThreadStateException  {
        if (vm.canGetCurrentContendedMonitor() == false) {
            throw new UnsupportedOperationException();
        }

        if (myJavaThread == null) {
           throw new IncompatibleThreadStateException();
        }
        ObjectMonitor mon = myJavaThread.getCurrentWaitingMonitor();
        if (mon == null) {
           // thread is not doing an Object.wait() call
           mon = myJavaThread.getCurrentPendingMonitor();
           if (mon != null) {
               OopHandle handle = mon.object();
               // If obj == NULL, then ObjectMonitor is raw which doesn't count
               // as contended for this API
               return vm.objectMirror(vm.saObjectHeap().newOop(handle));
           } else {
               // no contended ObjectMonitor
               return null;
           }
        } else {
           // thread is doing an Object.wait() call
           OopHandle handle = mon.object();
           if (Assert.ASSERTS_ENABLED) {
               Assert.that(handle != null, "Object.wait() should have an object");
           }
           Oop obj = vm.saObjectHeap().newOop(handle);
           return vm.objectMirror(obj);
        }
    }


    public void popFrames(StackFrame frame) throws IncompatibleThreadStateException {
        vm.throwNotReadOnlyException("ThreadReference.popFrames()");
    }

    public void forceEarlyReturn(Value returnValue) throws IncompatibleThreadStateException {
        vm.throwNotReadOnlyException("ThreadReference.forceEarlyReturn()");
    }

    public String toString() {
        return "instance of " + referenceType().name() +
               "(name='" + name() + "', " + "id=" + uniqueID() + ")";
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ThreadReferenceImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.