jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 836 d81b1f62fb82
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.tools.jdi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import com.sun.jdi.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import com.sun.jdi.request.BreakpointRequest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.lang.ref.WeakReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
public class ThreadReferenceImpl extends ObjectReferenceImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
             implements ThreadReference, VMListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
    static final int SUSPEND_STATUS_SUSPENDED = 0x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
    static final int SUSPEND_STATUS_BREAK = 0x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
    private ThreadGroupReference threadGroup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
    private int suspendedZombieCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    // This is cached only while the VM is suspended
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    private static class Cache extends ObjectReferenceImpl.Cache {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
        String name = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
        JDWP.ThreadReference.Status status = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
        List<StackFrame> frames = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
        int framesStart = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
        int framesLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
        int frameCount = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
        List<ObjectReference> ownedMonitors = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
        List<MonitorInfo> ownedMonitorsInfo = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
        ObjectReference contendedMonitor = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
        boolean triedCurrentContended = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    protected ObjectReferenceImpl.Cache newCache() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        return new Cache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    // Listeners - synchronized on vm.state()
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    private List<WeakReference<ThreadListener>> listeners = new ArrayList<WeakReference<ThreadListener>>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    ThreadReferenceImpl(VirtualMachine aVm, long aRef) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
        super(aVm,aRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        vm.state().addListener(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    protected String description() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        return "ThreadReference " + uniqueID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     * VMListener implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    public boolean vmNotSuspended(VMAction action) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            processThreadAction(new ThreadAction(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
                                   ThreadAction.THREAD_RESUMABLE));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        return super.vmNotSuspended(action);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     * Note that we only cache the name string while suspended because
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * it can change via Thread.setName arbitrarily
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    public String name() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        String name = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
                name = local.name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                name = JDWP.ThreadReference.Name.process(vm, this)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
                                                             .threadName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                    local.name = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * Sends a command to the back end which is defined to do an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * implicit vm-wide resume.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    PacketStream sendResumingCommand(CommandSender sender) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
            processThreadAction(new ThreadAction(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                                        ThreadAction.THREAD_RESUMABLE));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
            return sender.send();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    public void suspend() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            JDWP.ThreadReference.Suspend.process(vm, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        // Don't consider the thread suspended yet. On reply, notifySuspend()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        // will be called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    public void resume() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
         * If it's a zombie, we can just update internal state without
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
         * going to back end.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        if (suspendedZombieCount > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            suspendedZombieCount--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        PacketStream stream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            processThreadAction(new ThreadAction(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                      ThreadAction.THREAD_RESUMABLE));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            stream = JDWP.ThreadReference.Resume.enqueueCommand(vm, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            JDWP.ThreadReference.Resume.waitForReply(vm, stream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    public int suspendCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
         * If it's a zombie, we maintain the count in the front end.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        if (suspendedZombieCount > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            return suspendedZombieCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            return JDWP.ThreadReference.SuspendCount.process(vm, this).suspendCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    public void stop(ObjectReference throwable) throws InvalidTypeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        validateMirror(throwable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        // Verify that the given object is a Throwable instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        List list = vm.classesByName("java.lang.Throwable");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        ClassTypeImpl throwableClass = (ClassTypeImpl)list.get(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        if ((throwable == null) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            !throwableClass.isAssignableFrom(throwable)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
             throw new InvalidTypeException("Not an instance of Throwable");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            JDWP.ThreadReference.Stop.process(vm, this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                                         (ObjectReferenceImpl)throwable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    public void interrupt() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            JDWP.ThreadReference.Interrupt.process(vm, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    private JDWP.ThreadReference.Status jdwpStatus() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        JDWP.ThreadReference.Status status = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                status = local.status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            if (status == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                status = JDWP.ThreadReference.Status.process(vm, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                    local.status = status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        return status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    public int status() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        return jdwpStatus().threadStatus;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    public boolean isSuspended() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        return ((suspendedZombieCount > 0) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                ((jdwpStatus().suspendStatus & SUSPEND_STATUS_SUSPENDED) != 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    public boolean isAtBreakpoint() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
         * TO DO: This fails to take filters into account.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            StackFrame frame = frame(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            Location location = frame.location();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            List requests = vm.eventRequestManager().breakpointRequests();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            Iterator iter = requests.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                BreakpointRequest request = (BreakpointRequest)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                if (location.equals(request.location())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        } catch (IndexOutOfBoundsException iobe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            return false;  // no frames on stack => not at breakpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        } catch (IncompatibleThreadStateException itse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            // Per the javadoc, not suspended => return false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    public ThreadGroupReference threadGroup() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
         * Thread group can't change, so it's cached more conventionally
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
         * than other things in this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        if (threadGroup == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                threadGroup = JDWP.ThreadReference.ThreadGroup.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                    process(vm, this).group;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        return threadGroup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    public int frameCount() throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        int frameCount = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                frameCount = local.frameCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            if (frameCount == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                frameCount = JDWP.ThreadReference.FrameCount
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                                          .process(vm, this).frameCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                    local.frameCount = frameCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            switch (exc.errorCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            case JDWP.Error.THREAD_NOT_SUSPENDED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            case JDWP.Error.INVALID_THREAD:   /* zombie */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                throw new IncompatibleThreadStateException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        return frameCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    public List<StackFrame> frames() throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        return privateFrames(0, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    public StackFrame frame(int index) throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        List list = privateFrames(index, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        return (StackFrame)list.get(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * Is the requested subrange within what has been retrieved?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * local is known to be non-null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    private boolean isSubrange(Cache local,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                               int start, int length, List frames) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        if (start < local.framesStart) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        if (length == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            return (local.framesLength == -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        if (local.framesLength == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            if ((start + length) > (local.framesStart + frames.size())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                throw new IndexOutOfBoundsException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        return ((start + length) <= (local.framesStart + local.framesLength));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    public List<StackFrame> frames(int start, int length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                              throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        if (length < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            throw new IndexOutOfBoundsException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                "length must be greater than or equal to zero");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        return privateFrames(start, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * Private version of frames() allows "-1" to specify all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * remaining frames.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    private List<StackFrame> privateFrames(int start, int length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                              throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        List<StackFrame> frames = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                frames = local.frames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            if (frames == null || !isSubrange(local, start, length, frames)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                JDWP.ThreadReference.Frames.Frame[] jdwpFrames
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                    = JDWP.ThreadReference.Frames.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                          process(vm, this, start, length).frames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                int count = jdwpFrames.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                frames = new ArrayList<StackFrame>(count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                // Lock must be held while creating stack frames.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                // so that a resume will not resume a partially
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                // created stack.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                    for (int i = 0; i<count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                        if (jdwpFrames[i].location == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                            throw new InternalException("Invalid frame location");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                        StackFrame frame = new StackFrameImpl(vm, this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                                            jdwpFrames[i].frameID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                                            jdwpFrames[i].location);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                        // Add to the frame list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                        frames.add(frame);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                    local.frames = frames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                    local.framesStart = start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    local.framesLength = length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                int fromIndex = start - local.framesStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                int toIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                if (length == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                    toIndex = frames.size() - fromIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                    toIndex = fromIndex + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                frames = frames.subList(fromIndex, toIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            switch (exc.errorCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            case JDWP.Error.THREAD_NOT_SUSPENDED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            case JDWP.Error.INVALID_THREAD:   /* zombie */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                throw new IncompatibleThreadStateException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        return Collections.unmodifiableList(frames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    public List<ObjectReference> ownedMonitors()  throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        List<ObjectReference> monitors = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                monitors = local.ownedMonitors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            if (monitors == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                monitors = Arrays.asList(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                                 (ObjectReference[])JDWP.ThreadReference.OwnedMonitors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                                         process(vm, this).owned);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                    local.ownedMonitors = monitors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                    if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                        vm.printTrace(description() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                                      " temporarily caching owned monitors"+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                                      " (count = " + monitors.size() + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
            switch (exc.errorCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            case JDWP.Error.THREAD_NOT_SUSPENDED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            case JDWP.Error.INVALID_THREAD:   /* zombie */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                throw new IncompatibleThreadStateException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        return monitors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    public ObjectReference currentContendedMonitor()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                              throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        ObjectReference monitor = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            if (local != null && local.triedCurrentContended) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                monitor = local.contendedMonitor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                monitor = JDWP.ThreadReference.CurrentContendedMonitor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                    process(vm, this).monitor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                    local.triedCurrentContended = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                    local.contendedMonitor = monitor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                    if ((monitor != null) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                        ((vm.traceFlags & vm.TRACE_OBJREFS) != 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                        vm.printTrace(description() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                              " temporarily caching contended monitor"+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                              " (id = " + monitor.uniqueID() + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            switch (exc.errorCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            case JDWP.Error.INVALID_THREAD:   /* zombie */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                throw new IncompatibleThreadStateException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        return monitor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    public List<MonitorInfo> ownedMonitorsAndFrames()  throws IncompatibleThreadStateException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        List<MonitorInfo> monitors = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            Cache local = (Cache)getCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                monitors = local.ownedMonitorsInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            if (monitors == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor[] minfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                minfo = JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.process(vm, this).owned;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                monitors = new ArrayList<MonitorInfo>(minfo.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                for (int i=0; i < minfo.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                    JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor mi =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                                                                         minfo[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                    MonitorInfo mon = new MonitorInfoImpl(vm, minfo[i].monitor, this, minfo[i].stack_depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                    monitors.add(mon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                if (local != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                    local.ownedMonitorsInfo = monitors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                    if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                        vm.printTrace(description() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                                      " temporarily caching owned monitors"+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                                      " (count = " + monitors.size() + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            switch (exc.errorCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            case JDWP.Error.THREAD_NOT_SUSPENDED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            case JDWP.Error.INVALID_THREAD:   /* zombie */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                throw new IncompatibleThreadStateException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        return monitors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    public void popFrames(StackFrame frame) throws IncompatibleThreadStateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        // Note that interface-wise this functionality belongs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        // here in ThreadReference, but implementation-wise it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        // belongs in StackFrame, so we just forward it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        if (!frame.thread().equals(this)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            throw new IllegalArgumentException("frame does not belong to this thread");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        if (!vm.canPopFrames()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            throw new UnsupportedOperationException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                "target does not support popping frames");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        ((StackFrameImpl)frame).pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    public void forceEarlyReturn(Value  returnValue) throws InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                                             ClassNotLoadedException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                                             IncompatibleThreadStateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        if (!vm.canForceEarlyReturn()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            throw new UnsupportedOperationException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                "target does not support the forcing of a method to return early");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        validateMirrorOrNull(returnValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        StackFrameImpl sf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
           sf = (StackFrameImpl)frame(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        } catch (IndexOutOfBoundsException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
           throw new InvalidStackFrameException("No more frames on the stack");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        sf.validateStackFrame();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        MethodImpl meth = (MethodImpl)sf.location().method();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        ValueImpl convertedValue  = ValueImpl.prepareForAssignment(returnValue,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                                                                   meth.getReturnValueContainer());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            JDWP.ThreadReference.ForceEarlyReturn.process(vm, this, convertedValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        } catch (JDWPException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            switch (exc.errorCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            case JDWP.Error.OPAQUE_FRAME:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                throw new NativeMethodException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            case JDWP.Error.THREAD_NOT_SUSPENDED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                throw new IncompatibleThreadStateException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                         "Thread not suspended");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            case JDWP.Error.THREAD_NOT_ALIVE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                throw new IncompatibleThreadStateException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                                     "Thread has not started or has finished");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            case JDWP.Error.NO_MORE_FRAMES:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                throw new InvalidStackFrameException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                         "No more frames on the stack");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                throw exc.toJDIException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        return "instance of " + referenceType().name() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
               "(name='" + name() + "', " + "id=" + uniqueID() + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    byte typeValueKey() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        return JDWP.Tag.THREAD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    void addListener(ThreadListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            listeners.add(new WeakReference<ThreadListener>(listener));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    void removeListener(ThreadListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            Iterator iter = listeners.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                WeakReference ref = (WeakReference)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                if (listener.equals(ref.get())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                    iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
     * Propagate the the thread state change information
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     * to registered listeners.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * Must be entered while synchronized on vm.state()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    private void processThreadAction(ThreadAction action) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        synchronized (vm.state()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            Iterator iter = listeners.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                WeakReference ref = (WeakReference)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                ThreadListener listener = (ThreadListener)ref.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                if (listener != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                    switch (action.id()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                        case ThreadAction.THREAD_RESUMABLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                            if (!listener.threadResumable(action)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                                iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                    // Listener is unreachable; clean up
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                    iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
}