hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaThread.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 2004-2007 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.utilities.soql;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
import sun.jvm.hotspot.debugger.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import sun.jvm.hotspot.oops.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
import sun.jvm.hotspot.runtime.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
/**
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
 * Wraps a JavaThread instance in the target VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
public class JSJavaThread extends JSJavaInstance {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
    public JSJavaThread(Instance threadOop, JSJavaFactory fac) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
        super(threadOop, fac);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
        // JavaThread retrieved from java.lang.Thread instance may be null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
        // This is the case for threads not-started and for zombies. Wherever
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
        // appropriate, check for null instead of resulting in NullPointerException.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
        this.jthread = OopUtilities.threadOopGetJavaThread(threadOop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    public JSJavaThread(JavaThread jt, JSJavaFactory fac) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
        super((Instance) jt.getThreadObj(), fac);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
        this.jthread = jt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    public String toString() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
        String name = getName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
        StringBuffer buf = new StringBuffer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
        buf.append("Thread (address=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
        buf.append(getOop().getHandle());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
        buf.append(", name=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
        if (name != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
            buf.append(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
            buf.append("<unnamed>");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
        buf.append(')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
        return buf.toString();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    protected Object getFieldValue(String name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
        if (name.equals("name")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
            return getName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
        } else if (name.equals("frames")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
            return getFrames();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
        } else if (name.equals("monitors")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
            return getOwnedMonitors();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
            return super.getFieldValue(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    protected String[] getFieldNames() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
        String[] flds = super.getFieldNames();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
        String[] res = new String[flds.length + 2];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
        System.arraycopy(flds, 0, res, 0, flds.length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
        res[flds.length] = "frames";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
        res[flds.length + 1] = "monitors";
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
        return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    protected boolean hasField(String name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
        if (name.equals("frames") || name.equals("monitors")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
            return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
            return super.hasField(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    //-- Internals only below this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    private String getName() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
        return OopUtilities.threadOopGetName(getOop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    private synchronized JSList getFrames() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
        if (framesCache == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
            final List list = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
            if (jthread != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
                JavaVFrame jvf = jthread.getLastJavaVFrameDbg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
                while (jvf != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
                    list.add(jvf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
                    jvf = jvf.javaSender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
            framesCache = factory.newJSList(list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
        return framesCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    private synchronized JSList getOwnedMonitors() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
        if (monitorsCache == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
            final List ownedMonitors = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
            if (jthread != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
                List lockedObjects = new ArrayList(); // List<OopHandle>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
                ObjectMonitor waitingMonitor = jthread.getCurrentWaitingMonitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
                OopHandle waitingObj = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
                if (waitingMonitor != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
                   // save object of current wait() call (if any) for later comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
                   waitingObj = waitingMonitor.object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
                ObjectMonitor pendingMonitor = jthread.getCurrentPendingMonitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
                OopHandle pendingObj = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
                if (pendingMonitor != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
                    // save object of current enter() call (if any) for later comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
                    pendingObj = pendingMonitor.object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
                JavaVFrame frame = jthread.getLastJavaVFrameDbg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
                while (frame != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
                    List frameMonitors = frame.getMonitors();  // List<MonitorInfo>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
                    for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
                        MonitorInfo mi = (MonitorInfo) miItr.next();
3171
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   138
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   139
                        if (mi.eliminated() && frame.isCompiledFrame()) {
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   140
                          continue; // skip eliminated monitor
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 1
diff changeset
   141
                        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
                        OopHandle obj = mi.owner();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
                        if (obj == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
                            // this monitor doesn't have an owning object so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
                            continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
                        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
                        if (obj.equals(waitingObj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
                           // the thread is waiting on this monitor so it isn't really owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
                           continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
                        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
                        if (obj.equals(pendingObj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
                            // the thread is pending on this monitor so it isn't really owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
                            continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
                        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
                        boolean found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
                        for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
                            // check for recursive locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
                            if (obj.equals(loItr.next())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
                                found = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
                                break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
                            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
                        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
                        if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
                            // already have this object so don't include it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
                            continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
                        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
                        // add the owning object to our list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
                        lockedObjects.add(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
                    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
                    frame = (JavaVFrame) frame.javaSender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
                // now convert List<OopHandle> to List<Oop>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
                ObjectHeap heap = VM.getVM().getObjectHeap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
                for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
                    ownedMonitors.add(heap.newOop((OopHandle)loItr.next()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
            monitorsCache = factory.newJSList(ownedMonitors);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
        return monitorsCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    private JavaThread jthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    private JSList framesCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    private JSList monitorsCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
}