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/RegisterMap.java
62930 views
1
/*
2
* Copyright (c) 2000, 2020, 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
30
import sun.jvm.hotspot.debugger.*;
31
import sun.jvm.hotspot.interpreter.*;
32
import sun.jvm.hotspot.code.*;
33
import sun.jvm.hotspot.types.*;
34
import sun.jvm.hotspot.utilities.*;
35
import sun.jvm.hotspot.utilities.Observable;
36
import sun.jvm.hotspot.utilities.Observer;
37
38
/** <P> A companion structure used for stack traversal. The
39
RegisterMap contains misc. information needed in order to do
40
correct stack traversal of stack frames. Hence, it must always be
41
passed in as an argument to Frame.sender(RegisterMap). </P>
42
43
<P> The use of RegisterMaps is slightly different in the
44
Serviceability Agent APIs than in the VM itself. In the VM, a
45
RegisterMap is created either for a particular thread or cloned
46
from another RegisterMap. In these APIs, a JavaThread is the
47
top-level factory for RegisterMaps, and RegisterMaps know how to
48
copy themselves (through either the clone() or copy()
49
methods). </P> */
50
51
public abstract class RegisterMap implements Cloneable {
52
/** Location of registers */
53
protected Address[] location;
54
// FIXME: don't know about LocationValidType
55
protected long[] locationValid;
56
/** Should include argument_oop marked locations for compiler */
57
protected boolean includeArgumentOops;
58
/** Reference to current thread */
59
protected JavaThread thread;
60
/** Tells if the register map needs to be updated when traversing the stack */
61
protected boolean updateMap;
62
/** Location of a frame where the pc is not at a call (NULL if no frame exists) */
63
protected static int regCount;
64
protected static int locationValidTypeSize;
65
protected static int locationValidSize;
66
67
static {
68
VM.registerVMInitializedObserver(new Observer() {
69
public void update(Observable o, Object data) {
70
initialize(VM.getVM().getTypeDataBase());
71
}
72
});
73
}
74
75
private static void initialize(TypeDataBase db) {
76
regCount = db.lookupIntConstant("ConcreteRegisterImpl::number_of_registers").intValue();
77
// FIXME: don't know about LocationValidType. The LocationValidType is typedef'ed as julong
78
// so used julong to get the size of LocationValidType.
79
locationValidTypeSize = (int)db.lookupType("julong").getSize() * 8;
80
locationValidSize = (regCount + locationValidTypeSize - 1) / locationValidTypeSize;
81
}
82
83
protected RegisterMap(JavaThread thread, boolean updateMap) {
84
this.thread = thread;
85
this.updateMap = updateMap;
86
location = new Address[regCount];
87
locationValid = new long[locationValidSize];
88
clear();
89
}
90
91
/** Makes a copy of map into this */
92
protected RegisterMap(RegisterMap map) {
93
if (Assert.ASSERTS_ENABLED) {
94
Assert.that(map != null, "RegisterMap must be present");
95
}
96
this.thread = map.getThread();
97
this.updateMap = map.getUpdateMap();
98
this.includeArgumentOops = map.getIncludeArgumentOops();
99
location = new Address[map.location.length];
100
locationValid = new long[map.locationValid.length];
101
initializeFromPD(map);
102
if (updateMap) {
103
for (int i = 0; i < locationValidSize; i++) {
104
long bits = (!getUpdateMap()) ? 0 : map.locationValid[i];
105
locationValid[i] = bits;
106
// for whichever bits are set, pull in the corresponding map->_location
107
int j = i*locationValidTypeSize;
108
while (bits != 0) {
109
if ((bits & 1) != 0) {
110
if (Assert.ASSERTS_ENABLED) {
111
Assert.that(0 <= j && j < regCount, "range check");
112
}
113
location[j] = map.location[j];
114
}
115
bits >>>= 1;
116
j += 1;
117
}
118
}
119
}
120
}
121
122
public abstract Object clone();
123
124
public RegisterMap copy() {
125
return (RegisterMap) clone();
126
}
127
128
public void clear() {
129
setIncludeArgumentOops(true);
130
if (!VM.getVM().isCore()) {
131
if (updateMap) {
132
for (int i = 0; i < locationValid.length; i++) {
133
locationValid[i] = 0;
134
}
135
clearPD();
136
} else {
137
initializePD();
138
}
139
}
140
}
141
142
public Address getLocation(VMReg reg) {
143
int i = reg.getValue();
144
int index = i / locationValidTypeSize;
145
if (Assert.ASSERTS_ENABLED) {
146
Assert.that(0 <= i && i < regCount, "sanity check");
147
Assert.that(0 <= index && index < locationValidSize, "sanity check");
148
}
149
if ((locationValid[index] & (1 << i % locationValidTypeSize)) != 0) {
150
return location[i];
151
} else {
152
return getLocationPD(reg);
153
}
154
}
155
156
public void setLocation(VMReg reg, Address loc) {
157
int i = reg.getValue();
158
int index = i / locationValidTypeSize;
159
if (Assert.ASSERTS_ENABLED) {
160
Assert.that(0 <= i && i < regCount, "sanity check");
161
Assert.that(0 <= index && index < locationValidSize, "sanity check");
162
Assert.that(updateMap, "updating map that does not need updating");
163
}
164
location[i] = loc;
165
locationValid[index] |= (1 << (i % locationValidTypeSize));
166
}
167
168
public boolean getIncludeArgumentOops() {
169
return includeArgumentOops;
170
}
171
172
public void setIncludeArgumentOops(boolean f) {
173
includeArgumentOops = f;
174
}
175
176
public JavaThread getThread() {
177
return thread;
178
}
179
180
public boolean getUpdateMap() {
181
return updateMap;
182
}
183
184
public void print() {
185
printOn(System.out);
186
}
187
188
public void printOn(PrintStream tty) {
189
tty.println("Register map");
190
for (int i = 0; i < location.length; i++) {
191
Address src = getLocation(new VMReg(i));
192
if (src != null) {
193
tty.print(" " + VMRegImpl.getRegisterName(i) +
194
" [" + src + "] = ");
195
if (src.andWithMask(VM.getVM().getAddressSize() - 1) != null) {
196
tty.print("<misaligned>");
197
} else {
198
tty.print(src.getAddressAt(0));
199
}
200
}
201
}
202
}
203
204
/** Platform-dependent clear() functionality */
205
protected abstract void clearPD();
206
/** Platform-dependent initialize() functionality */
207
protected abstract void initializePD();
208
/** Platform-dependent initializeFrom() functionality */
209
protected abstract void initializeFromPD(RegisterMap map);
210
/** Platform-dependent getLocation() functionality */
211
protected abstract Address getLocationPD(VMReg reg);
212
}
213
214