hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ThreadReferenceImpl.java
author kvn
Tue, 09 Jun 2009 16:19:10 -0700
changeset 3171 aa289b22b577
parent 1 489c9b5090e2
child 3261 c7d5aae8d3f7
permissions -rw-r--r--
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14 Summary: Disable escape analysis when jvmti/debugger is used. Add support for EA ibto SA. Reviewed-by: never
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
package sun.jvm.hotspot.jdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import sun.jvm.hotspot.debugger.OopHandle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
import sun.jvm.hotspot.runtime.VMObject;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import sun.jvm.hotspot.runtime.JavaThread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
import sun.jvm.hotspot.runtime.OSThread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
//import sun.jvm.hotspot.runtime.StackFrameStream;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.runtime.JavaVFrame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
import sun.jvm.hotspot.runtime.JavaThreadState;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
import sun.jvm.hotspot.runtime.MonitorInfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
import sun.jvm.hotspot.runtime.ObjectMonitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
import sun.jvm.hotspot.oops.Oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
import sun.jvm.hotspot.oops.ObjectHeap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
import sun.jvm.hotspot.oops.Instance;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
import sun.jvm.hotspot.oops.OopUtilities;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
import sun.jvm.hotspot.oops.Klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
import sun.jvm.hotspot.utilities.Assert;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
import com.sun.jdi.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
public class ThreadReferenceImpl extends ObjectReferenceImpl
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
             implements ThreadReference, /* imports */ JVMTIThreadState {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    private JavaThread myJavaThread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    private ArrayList frames;    // StackFrames
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    private List ownedMonitors; // List<ObjectReferenceImpl>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
    private List ownedMonitorsInfo; // List<MonitorInfo>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    private ObjectReferenceImpl currentContendingMonitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    ThreadReferenceImpl(VirtualMachine aVm, sun.jvm.hotspot.runtime.JavaThread aRef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
        // We are given a JavaThread and save it in our myJavaThread field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
        // But, our parent class is an ObjectReferenceImpl so we need an Oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
        // for it.  JavaThread is a wrapper around a Thread Oop so we get
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
        // that Oop and give it to our super.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
        // We can get it back again by calling ref().
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
        super(aVm, (Instance)aRef.getThreadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
        myJavaThread = aRef;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    ThreadReferenceImpl(VirtualMachine vm, Instance oRef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
        // Instance must be of type java.lang.Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
        super(vm, oRef);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
        // JavaThread retrieved from java.lang.Thread instance may be null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
        // This is the case for threads not-started and for zombies. Wherever
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
        // appropriate, check for null instead of resulting in NullPointerException.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
        myJavaThread = OopUtilities.threadOopGetJavaThread(oRef);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    // return value may be null. refer to the comment in constructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    JavaThread getJavaThread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
        return myJavaThread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    protected String description() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
        return "ThreadReference " + uniqueID();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    /**
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
     * Note that we only cache the name string while suspended because
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
     * it can change via Thread.setName arbitrarily
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
    public String name() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
        return OopUtilities.threadOopGetName(ref());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    public void suspend() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
        vm.throwNotReadOnlyException("ThreadReference.suspend()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    public void resume() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
        vm.throwNotReadOnlyException("ThreadReference.resume()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    public int suspendCount() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
        // all threads are "suspended" when we attach to process or core.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
        // we interpret this as one suspend.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
        return 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    public void stop(ObjectReference throwable) throws InvalidTypeException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
        vm.throwNotReadOnlyException("ThreadReference.stop()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    public void interrupt() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
        vm.throwNotReadOnlyException("ThreadReference.interrupt()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    // refer to jvmtiEnv::GetThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    private int jvmtiGetThreadState() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
        // get most state bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
        int state = OopUtilities.threadOopGetThreadStatus(ref());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
        // add more state bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
        if (myJavaThread != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
            JavaThreadState jts = myJavaThread.getThreadState();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
            if (myJavaThread.isBeingExtSuspended()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
                state |= JVMTI_THREAD_STATE_SUSPENDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
            if (jts == JavaThreadState.IN_NATIVE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
                state |= JVMTI_THREAD_STATE_IN_NATIVE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
            OSThread osThread = myJavaThread.getOSThread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
            if (osThread != null && osThread.interrupted()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
                state |= JVMTI_THREAD_STATE_INTERRUPTED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
        return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
    public int status() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
        int state = jvmtiGetThreadState();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
        int status = THREAD_STATUS_UNKNOWN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
        // refer to map2jdwpThreadStatus in util.c (back-end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
        if (! ((state & JVMTI_THREAD_STATE_ALIVE) != 0) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
            if ((state & JVMTI_THREAD_STATE_TERMINATED) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
                status = THREAD_STATUS_ZOMBIE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
                status = THREAD_STATUS_NOT_STARTED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
            if ((state & JVMTI_THREAD_STATE_SLEEPING) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
                status = THREAD_STATUS_SLEEPING;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
            } else if ((state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
                status = THREAD_STATUS_MONITOR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
            } else if ((state & JVMTI_THREAD_STATE_WAITING) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
                status = THREAD_STATUS_WAIT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
            } else if ((state & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
                status = THREAD_STATUS_RUNNING;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
        return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    public boolean isSuspended() { //fixme jjh
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
        // If we want to support doing this for a VM which was being
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
        // debugged, then we need to fix this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
        // In the meantime, we will say all threads are suspended,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
        // otherwise, some things won't work, like the jdb 'up' cmd.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    public boolean isAtBreakpoint() { //fixme jjh
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
        // If we want to support doing this for a VM which was being
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
        // debugged, then we need to fix this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    public ThreadGroupReference threadGroup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
        return (ThreadGroupReferenceImpl)vm.threadGroupMirror(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
               (Instance)OopUtilities.threadOopGetThreadGroup(ref()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    public int frameCount() throws IncompatibleThreadStateException  { //fixme jjh
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
        privateFrames(0, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
        return frames.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    public List frames() throws IncompatibleThreadStateException  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
        return privateFrames(0, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    public StackFrame frame(int index) throws IncompatibleThreadStateException  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
        List list = privateFrames(index, 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
        return (StackFrame)list.get(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    public List frames(int start, int length)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
                              throws IncompatibleThreadStateException  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
        if (length < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
            throw new IndexOutOfBoundsException(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
                "length must be greater than or equal to zero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
        return privateFrames(start, length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    /**
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
     * Private version of frames() allows "-1" to specify all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
     * remaining frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    private List privateFrames(int start, int length)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
                              throws IncompatibleThreadStateException  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
        if (myJavaThread == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
            // for zombies and yet-to-be-started threads we need to throw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
            throw new IncompatibleThreadStateException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
        if (frames == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
            frames = new ArrayList(10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
            JavaVFrame myvf = myJavaThread.getLastJavaVFrameDbg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
            while (myvf != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
                StackFrame myFrame = new StackFrameImpl(vm, this, myvf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
                //fixme jjh null should be a Location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
                frames.add(myFrame);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
                myvf = (JavaVFrame)myvf.javaSender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
        List retVal;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
        if (frames.size() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
            retVal = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
            int toIndex = start + length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
            if (length == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
                toIndex = frames.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
            retVal = frames.subList(start, toIndex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
        return Collections.unmodifiableList(retVal);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    // refer to JvmtiEnvBase::get_owned_monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    public List ownedMonitors()  throws IncompatibleThreadStateException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
        if (vm.canGetOwnedMonitorInfo() == false) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
            throw new UnsupportedOperationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
        if (myJavaThread == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
           throw new IncompatibleThreadStateException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
        if (ownedMonitors != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
            return ownedMonitors;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
        ownedMonitorsWithStackDepth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
        for (Iterator omi = ownedMonitorsInfo.iterator(); omi.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
            //FIXME : Change the MonitorInfoImpl cast to com.sun.jdi.MonitorInfo
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
            //        when hotspot start building with jdk1.6.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
            ownedMonitors.add(((MonitorInfoImpl)omi.next()).monitor());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
        return ownedMonitors;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    // new method since 1.6.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    // Real body will be supplied later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    public List ownedMonitorsAndFrames() throws IncompatibleThreadStateException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
        if (!vm.canGetMonitorFrameInfo()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
            throw new UnsupportedOperationException(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
                "target does not support getting Monitor Frame Info");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        if (myJavaThread == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
           throw new IncompatibleThreadStateException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
        if (ownedMonitorsInfo != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
            return ownedMonitorsInfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
        ownedMonitorsWithStackDepth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        return ownedMonitorsInfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    private void ownedMonitorsWithStackDepth() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
        ownedMonitorsInfo = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
        List lockedObjects = new ArrayList(); // List<OopHandle>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
        List stackDepth = new ArrayList(); // List<int>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
        ObjectMonitor waitingMonitor = myJavaThread.getCurrentWaitingMonitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
        ObjectMonitor pendingMonitor = myJavaThread.getCurrentPendingMonitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
        OopHandle waitingObj = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
        if (waitingMonitor != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
            // save object of current wait() call (if any) for later comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
            waitingObj = waitingMonitor.object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
        OopHandle pendingObj = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
        if (pendingMonitor != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
            // save object of current enter() call (if any) for later comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
            pendingObj = pendingMonitor.object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        JavaVFrame frame = myJavaThread.getLastJavaVFrameDbg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
        int depth=0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
        while (frame != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
            List frameMonitors = frame.getMonitors();  // List<MonitorInfo>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
            for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
                sun.jvm.hotspot.runtime.MonitorInfo mi = (sun.jvm.hotspot.runtime.MonitorInfo) miItr.next();
3171
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   304
                if (mi.eliminated() && frame.isCompiledFrame()) {
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   305
                  continue; // skip eliminated monitor
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   306
                }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
                OopHandle obj = mi.owner();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
                if (obj == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
                    // this monitor doesn't have an owning object so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
                    continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
                if (obj.equals(waitingObj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
                    // the thread is waiting on this monitor so it isn't really owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
                    continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
                if (obj.equals(pendingObj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
                    // the thread is pending on this monitor so it isn't really owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
                    continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
                boolean found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
                for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
                    // check for recursive locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
                    if (obj.equals(loItr.next())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
                        found = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
                        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
                    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
                if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
                    // already have this object so don't include it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
                    continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
                // add the owning object to our list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
                lockedObjects.add(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
                stackDepth.add(new Integer(depth));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
            frame = (JavaVFrame) frame.javaSender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
            depth++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
        // now convert List<OopHandle> to List<ObjectReference>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
        ObjectHeap heap = vm.saObjectHeap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
        Iterator stk = stackDepth.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
        for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
            Oop obj = heap.newOop((OopHandle)loItr.next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
            ownedMonitorsInfo.add(new MonitorInfoImpl(vm, vm.objectMirror(obj), this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
                                                              ((Integer)stk.next()).intValue()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    // refer to JvmtiEnvBase::get_current_contended_monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    public ObjectReference currentContendedMonitor()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
                              throws IncompatibleThreadStateException  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
        if (vm.canGetCurrentContendedMonitor() == false) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
            throw new UnsupportedOperationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
        if (myJavaThread == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
           throw new IncompatibleThreadStateException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
        ObjectMonitor mon = myJavaThread.getCurrentWaitingMonitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
        if (mon == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
           // thread is not doing an Object.wait() call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
           mon = myJavaThread.getCurrentPendingMonitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
           if (mon != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
               OopHandle handle = mon.object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
               // If obj == NULL, then ObjectMonitor is raw which doesn't count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
               // as contended for this API
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
               return vm.objectMirror(vm.saObjectHeap().newOop(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
           } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
               // no contended ObjectMonitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
               return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
           }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
           // thread is doing an Object.wait() call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
           OopHandle handle = mon.object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
           if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
               Assert.that(handle != null, "Object.wait() should have an object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
           }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
           Oop obj = vm.saObjectHeap().newOop(handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
           return vm.objectMirror(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    public void popFrames(StackFrame frame) throws IncompatibleThreadStateException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
        vm.throwNotReadOnlyException("ThreadReference.popFrames()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
    public void forceEarlyReturn(Value returnValue) throws IncompatibleThreadStateException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
        vm.throwNotReadOnlyException("ThreadReference.forceEarlyReturn()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
    public String toString() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
        return "instance of " + referenceType().name() +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
               "(name='" + name() + "', " + "id=" + uniqueID() + ")";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
}