Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java
41161 views
1
/*
2
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
package sun.jvm.hotspot.runtime;
26
27
import java.io.*;
28
import java.util.*;
29
import sun.jvm.hotspot.oops.*;
30
import sun.jvm.hotspot.utilities.*;
31
import sun.jvm.hotspot.debugger.*;
32
33
public abstract class JavaVFrame extends VFrame {
34
35
private static final String ADDRESS_FORMAT = VM.getVM().isLP64() ? "0x%016x"
36
: "0x%08x";
37
38
/** JVM state */
39
public abstract Method getMethod();
40
public abstract int getBCI();
41
public abstract StackValueCollection getLocals();
42
public abstract StackValueCollection getExpressions();
43
public abstract List<MonitorInfo> getMonitors();
44
45
/** Test operation */
46
public boolean isJavaFrame() { return true; }
47
48
/** Package-internal constructor */
49
JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
50
super(fr, regMap, thread);
51
}
52
53
/** Get monitor (if any) that this JavaVFrame is trying to enter */
54
// FIXME: not yet implemented
55
// public Address getPendingMonitor(int frameCount);
56
57
public void printLockedObjectClassName(PrintStream tty,
58
OopHandle hobj, String lockState) {
59
if (hobj.asLongValue() != 0L) {
60
tty.format("\t- %s <" + ADDRESS_FORMAT + "> ",
61
lockState, hobj.asLongValue());
62
63
Klass klass = Oop.getKlassForOopHandle(hobj);
64
String klassName = klass.getName().asString();
65
tty.print("(a ");
66
if (klassName.equals("java/lang/Class")) {
67
Oop obj = VM.getVM().getObjectHeap().newOop(hobj);
68
klassName = java_lang_Class.asExternalName(obj);
69
tty.print("java.lang.Class for ");
70
}
71
tty.println(klassName.replace('/', '.') + ")");
72
}
73
}
74
75
private String identifyLockState(MonitorInfo monitor, String waitingState) {
76
Mark mark = new Mark(monitor.owner());
77
if (mark.hasMonitor() &&
78
( // we have marked ourself as pending on this monitor
79
mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
80
// we are not the owner of this monitor
81
!mark.monitor().isEntered(thread)
82
)) {
83
return waitingState;
84
}
85
return "locked";
86
}
87
88
/** Printing used during stack dumps */
89
public void printLockInfo(PrintStream tty, int frameCount) {
90
// If this is the first frame and it is java.lang.Object.wait(...)
91
// then print out the receiver. Locals are not always available,
92
// e.g., compiled native frames have no scope so there are no locals.
93
if (frameCount == 0) {
94
if (getMethod().getName().asString().equals("wait") &&
95
getMethod().getMethodHolder().getName().asString().equals("java/lang/Object")) {
96
String waitState = "waiting on"; // assume we are waiting
97
// If earlier in the output we reported java.lang.Thread.State ==
98
// "WAITING (on object monitor)" and now we report "waiting on", then
99
// we are still waiting for notification or timeout. Otherwise if
100
// we earlier reported java.lang.Thread.State == "BLOCKED (on object
101
// monitor)", then we are actually waiting to re-lock the monitor.
102
StackValueCollection locs = getLocals();
103
if (!locs.isEmpty()) {
104
StackValue sv = locs.get(0);
105
if (sv.getType() == BasicType.getTObject()) {
106
OopHandle o = sv.getObject();
107
if (OopUtilities.threadOopGetThreadStatus(thread.getThreadObj()) == OopUtilities.THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER) {
108
waitState = "waiting to re-lock in wait()";
109
}
110
printLockedObjectClassName(tty, o, waitState);
111
}
112
} else {
113
tty.println("\t- " + waitState + " <no object reference available>");
114
}
115
} else if (thread.getCurrentParkBlocker() != null) {
116
Oop obj = thread.getCurrentParkBlocker();
117
Klass k = obj.getKlass();
118
tty.format("\t- parking to wait for <" + ADDRESS_FORMAT + "> (a %s)",
119
obj.getHandle().asLongValue(), k.getName().asString());
120
tty.println();
121
}
122
}
123
124
// Print out all monitors that we have locked, or are trying to lock,
125
// including re-locking after being notified or timing out in a wait().
126
List<MonitorInfo> mons = getMonitors();
127
if (!mons.isEmpty()) {
128
boolean foundFirstMonitor = false;
129
for (int index = mons.size() - 1; index >= 0; index--) {
130
MonitorInfo monitor = mons.get(index);
131
if (monitor.eliminated() && isCompiledFrame()) { // Eliminated in compiled code
132
if (monitor.ownerIsScalarReplaced()) {
133
Klass k = Oop.getKlassForOopHandle(monitor.ownerKlass());
134
tty.println("\t- eliminated <owner is scalar replaced> (a " + k.getName().asString() + ")");
135
} else if (monitor.owner() != null) {
136
printLockedObjectClassName(tty, monitor.owner(), "eliminated");
137
}
138
continue;
139
}
140
if (monitor.owner() != null) {
141
// the monitor is associated with an object, i.e., it is locked
142
String lockState = "locked";
143
if (!foundFirstMonitor && frameCount == 0) {
144
// If this is the first frame and we haven't found an owned
145
// monitor before, then we need to see if we have completed
146
// the lock or if we are blocked trying to acquire it. Only
147
// an inflated monitor that is first on the monitor list in
148
// the first frame can block us on a monitor enter.
149
lockState = identifyLockState(monitor, "waiting to lock");
150
}
151
printLockedObjectClassName(tty, monitor.owner(), lockState);
152
foundFirstMonitor = true;
153
}
154
}
155
}
156
}
157
158
/** Printing operations */
159
160
//
161
// FIXME: implement visitor pattern for traversing vframe contents?
162
//
163
164
public void print() {
165
printOn(System.out);
166
}
167
168
public void printOn(PrintStream tty) {
169
super.printOn(tty);
170
171
tty.print("\t");
172
getMethod().printValueOn(tty);
173
tty.println();
174
tty.println("\tbci:\t" + getBCI());
175
176
printStackValuesOn(tty, "locals", getLocals());
177
printStackValuesOn(tty, "expressions", getExpressions());
178
}
179
180
public void printActivation(int index) {
181
printActivationOn(System.out, index);
182
}
183
184
public void printActivationOn(PrintStream tty, int index) {
185
// frame number and method
186
tty.print(index + " - ");
187
printValueOn(tty);
188
tty.println();
189
190
if (VM.getVM().wizardMode()) {
191
printOn(tty);
192
tty.println();
193
}
194
}
195
196
/** Verification operations */
197
public void verify() {
198
}
199
200
public boolean equals(Object o) {
201
if (o == null || !(o instanceof JavaVFrame)) {
202
return false;
203
}
204
205
JavaVFrame other = (JavaVFrame) o;
206
207
// Check static part
208
if (!getMethod().equals(other.getMethod())) {
209
return false;
210
}
211
212
if (getBCI() != other.getBCI()) {
213
return false;
214
}
215
216
// dynamic part - we just compare the frame pointer
217
if (! getFrame().equals(other.getFrame())) {
218
return false;
219
}
220
return true;
221
}
222
223
public int hashCode() {
224
return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();
225
}
226
227
/** Structural compare */
228
public boolean structuralCompare(JavaVFrame other) {
229
// Check static part
230
if (!getMethod().equals(other.getMethod())) {
231
return false;
232
}
233
234
if (getBCI() != other.getBCI()) {
235
return false;
236
}
237
238
// Check locals
239
StackValueCollection locs = getLocals();
240
StackValueCollection otherLocs = other.getLocals();
241
if (Assert.ASSERTS_ENABLED) {
242
Assert.that(locs.size() == otherLocs.size(), "sanity check");
243
}
244
for (int i = 0; i < locs.size(); i++) {
245
// it might happen the compiler reports a conflict and
246
// the interpreter reports a bogus int.
247
if ( isCompiledFrame() && (locs.get(i)).getType() == BasicType.getTConflict()) continue;
248
if (other.isCompiledFrame() && (otherLocs.get(i)).getType() == BasicType.getTConflict()) continue;
249
250
if (!locs.get(i).equals(otherLocs.get(i))) {
251
return false;
252
}
253
}
254
255
// Check expressions
256
StackValueCollection exprs = getExpressions();
257
StackValueCollection otherExprs = other.getExpressions();
258
if (Assert.ASSERTS_ENABLED) {
259
Assert.that(exprs.size() == otherExprs.size(), "sanity check");
260
}
261
for (int i = 0; i < exprs.size(); i++) {
262
if (!exprs.get(i).equals(otherExprs.get(i))) {
263
return false;
264
}
265
}
266
267
return true;
268
}
269
270
//--------------------------------------------------------------------------------
271
// Internals only below this point
272
//
273
274
private void printStackValuesOn(PrintStream tty, String title, StackValueCollection values) {
275
if (values.isEmpty()) {
276
return;
277
}
278
tty.println("\t" + title + ":");
279
for (int index = 0; index < values.size(); index++) {
280
tty.print("\t" + index + "\t");
281
values.get(index).printOn(tty);
282
tty.println();
283
}
284
}
285
}
286
287