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/compiler/ImmutableOopMapSet.java
41171 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.compiler;
26
27
import java.util.*;
28
29
import sun.jvm.hotspot.code.*;
30
import sun.jvm.hotspot.debugger.*;
31
import sun.jvm.hotspot.runtime.*;
32
import sun.jvm.hotspot.types.*;
33
import sun.jvm.hotspot.utilities.*;
34
import sun.jvm.hotspot.utilities.Observable;
35
import sun.jvm.hotspot.utilities.Observer;
36
37
public class ImmutableOopMapSet extends VMObject {
38
private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.compiler.ImmutableOopMapSet.DEBUG") != null;
39
40
private static CIntegerField countField;
41
private static CIntegerField sizeField;
42
private static AddressField omDataField;
43
private static int REG_COUNT;
44
private static int SAVED_ON_ENTRY_REG_COUNT;
45
private static int C_SAVED_ON_ENTRY_REG_COUNT;
46
private static long classSize;
47
48
private static class MyVisitor implements OopMapVisitor {
49
private AddressVisitor addressVisitor;
50
51
public MyVisitor(AddressVisitor oopVisitor) {
52
setAddressVisitor(oopVisitor);
53
}
54
55
public void setAddressVisitor(AddressVisitor addressVisitor) {
56
this.addressVisitor = addressVisitor;
57
}
58
59
public void visitOopLocation(Address oopAddr) {
60
addressVisitor.visitAddress(oopAddr);
61
}
62
63
public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr) {
64
if (VM.getVM().isClientCompiler()) {
65
Assert.that(false, "should not reach here");
66
} else if (VM.getVM().isServerCompiler() &&
67
VM.getVM().useDerivedPointerTable()) {
68
Assert.that(false, "FIXME: add derived pointer table");
69
}
70
}
71
72
public void visitNarrowOopLocation(Address narrowOopAddr) {
73
addressVisitor.visitCompOopAddress(narrowOopAddr);
74
}
75
}
76
77
static {
78
VM.registerVMInitializedObserver(new Observer() {
79
public void update(Observable o, Object data) {
80
initialize(VM.getVM().getTypeDataBase());
81
}
82
});
83
}
84
85
private static void initialize(TypeDataBase db) {
86
Type type = db.lookupType("ImmutableOopMapSet");
87
88
countField = type.getCIntegerField("_count");
89
sizeField = type.getCIntegerField("_size");
90
classSize = type.getSize();
91
92
if (!VM.getVM().isCore()) {
93
REG_COUNT = db.lookupIntConstant("REG_COUNT").intValue();
94
if (VM.getVM().isServerCompiler()) {
95
SAVED_ON_ENTRY_REG_COUNT = (int) db.lookupIntConstant("SAVED_ON_ENTRY_REG_COUNT").intValue();
96
C_SAVED_ON_ENTRY_REG_COUNT = (int) db.lookupIntConstant("C_SAVED_ON_ENTRY_REG_COUNT").intValue();
97
}
98
}
99
}
100
101
public ImmutableOopMapSet(Address addr) {
102
super(addr);
103
}
104
105
/**
106
* Returns the number of OopMaps in this ImmutableOopMapSet
107
*/
108
public int getCount() { return (int) countField.getValue(addr); }
109
110
private Address dataStart() {
111
return (pairStart().addOffsetTo(ImmutableOopMapPair.classSize() * getCount()));
112
}
113
114
private Address pairStart() {
115
return addr.addOffsetTo(ImmutableOopMapSet.classSize);
116
}
117
118
public ImmutableOopMapPair pairAt(int index) {
119
Assert.that((index >= 0) && (index < getCount()), "bad index");
120
return new ImmutableOopMapPair(pairStart().addOffsetTo(index * ImmutableOopMapPair.classSize()));
121
}
122
123
/**
124
* returns the OopMap at a given index
125
*/
126
public ImmutableOopMap getMapAt(int index) {
127
if (Assert.ASSERTS_ENABLED) {
128
Assert.that((index >= 0) && (index <= getCount()), "bad index");
129
}
130
131
ImmutableOopMapPair immutableOopMapPair = pairAt(index);
132
return getMap(immutableOopMapPair);
133
}
134
135
public ImmutableOopMap findMapAtOffset(long pcOffset, boolean debugging) {
136
int i;
137
int len = getCount();
138
if (Assert.ASSERTS_ENABLED) {
139
Assert.that(len > 0, "must have pointer maps");
140
}
141
142
// Scan through oopmaps. Stop when current offset is either equal or greater
143
// than the one we are looking for.
144
for (i = 0; i < len; i++) {
145
if (pairAt(i).getPC() >= pcOffset) {
146
break;
147
}
148
}
149
150
if (!debugging) {
151
if (Assert.ASSERTS_ENABLED) {
152
Assert.that(i < len, "oopmap not found for pcOffset = " + pcOffset + "; len = " + len);
153
Assert.that(pairAt(i).getPC() == pcOffset, "oopmap not found");
154
}
155
} else {
156
if (i == len) {
157
if (DEBUG) {
158
System.out.println("can't find oopmap at " + pcOffset);
159
System.out.print("Oopmap offsets are [ ");
160
for (i = 0; i < len; i++) {
161
System.out.print(pairAt(i).getPC());
162
}
163
System.out.println("]");
164
}
165
i = len - 1;
166
return getMapAt(i);
167
}
168
}
169
170
ImmutableOopMap m = getMapAt(i);
171
return m;
172
}
173
174
/**
175
* Visitation -- iterates through the frame for a compiled method.
176
* This is a very generic mechanism that requires the Address to be
177
* dereferenced by the callee. Other, more specialized, visitation
178
* mechanisms are given below.
179
*/
180
public static void oopsDo(Frame fr, CodeBlob cb, RegisterMap regMap, AddressVisitor oopVisitor, boolean debugging) {
181
allDo(fr, cb, regMap, new MyVisitor(oopVisitor), debugging);
182
}
183
184
/**
185
* Note that there are 4 required AddressVisitors: one for oops,
186
* one for derived oops, one for values, and one for dead values
187
*/
188
public static void allDo(Frame fr, CodeBlob cb, RegisterMap regMap, OopMapVisitor visitor, boolean debugging) {
189
if (Assert.ASSERTS_ENABLED) {
190
CodeBlob tmpCB = VM.getVM().getCodeCache().findBlob(fr.getPC());
191
Assert.that(tmpCB != null && cb.equals(tmpCB), "wrong codeblob passed in");
192
}
193
194
ImmutableOopMapSet maps = cb.getOopMaps();
195
ImmutableOopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
196
if (Assert.ASSERTS_ENABLED) {
197
Assert.that(map != null, "no ptr map found");
198
}
199
200
// handle derived pointers first (otherwise base pointer may be
201
// changed before derived pointer offset has been collected)
202
OopMapValue omv;
203
{
204
for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); !oms.isDone(); oms.next()) {
205
if (VM.getVM().isClientCompiler()) {
206
Assert.that(false, "should not reach here");
207
}
208
omv = oms.getCurrent();
209
Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
210
if (loc != null) {
211
Address baseLoc = fr.oopMapRegToLocation(omv.getContentReg(), regMap);
212
Address derivedLoc = loc;
213
visitor.visitDerivedOopLocation(baseLoc, derivedLoc);
214
}
215
}
216
}
217
218
// We want narow oop and oop oop_types
219
OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
220
OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
221
};
222
223
{
224
for (OopMapStream oms = new OopMapStream(map, values); !oms.isDone(); oms.next()) {
225
omv = oms.getCurrent();
226
Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
227
if (loc != null) {
228
if (omv.getType() == OopMapValue.OopTypes.OOP_VALUE) {
229
// This assert commented out because this will be useful
230
// to detect in the debugging system
231
// assert(Universe::is_heap_or_null(*loc), "found non oop pointer");
232
visitor.visitOopLocation(loc);
233
} else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
234
visitor.visitNarrowOopLocation(loc);
235
}
236
}
237
}
238
}
239
}
240
241
/**
242
* Update callee-saved register info for the following frame.
243
* Should only be called in non-core builds.
244
*/
245
public static void updateRegisterMap(Frame fr, CodeBlob cb, RegisterMap regMap, boolean debugging) {
246
if (Assert.ASSERTS_ENABLED) {
247
Assert.that(!VM.getVM().isCore(), "non-core builds only");
248
}
249
250
if (!VM.getVM().isDebugging()) {
251
if (Assert.ASSERTS_ENABLED) {
252
ImmutableOopMapSet maps = cb.getOopMaps();
253
Assert.that((maps != null) && (maps.getCount() > 0), "found null or empty ImmutableOopMapSet for CodeBlob");
254
}
255
} else {
256
// Hack for some topmost frames that have been found with empty
257
// OopMapSets. (Actually have not seen the null case, but don't
258
// want to take any chances.) See HSDB.showThreadStackMemory().
259
ImmutableOopMapSet maps = cb.getOopMaps();
260
if ((maps == null) || (maps.getCount() == 0)) {
261
return;
262
}
263
}
264
265
// Check if caller must update oop argument
266
regMap.setIncludeArgumentOops(cb.callerMustGCArguments());
267
268
int nofCallee = 0;
269
Address[] locs = new Address[2 * REG_COUNT + 1];
270
VMReg[] regs = new VMReg[2 * REG_COUNT + 1];
271
// ("+1" because REG_COUNT might be zero)
272
273
// Scan through oopmap and find location of all callee-saved registers
274
// (we do not do update in place, since info could be overwritten)
275
ImmutableOopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
276
if (Assert.ASSERTS_ENABLED) {
277
Assert.that(map != null, "no ptr map found");
278
}
279
280
OopMapValue omv = null;
281
for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); !oms.isDone(); oms.next()) {
282
omv = oms.getCurrent();
283
if (Assert.ASSERTS_ENABLED) {
284
Assert.that(nofCallee < 2 * REG_COUNT, "overflow");
285
}
286
regs[nofCallee] = omv.getContentReg();
287
locs[nofCallee] = fr.oopMapRegToLocation(omv.getReg(), regMap);
288
nofCallee++;
289
}
290
291
// Check that runtime stubs save all callee-saved registers
292
// After adapter frames were deleted C2 doesn't use callee save registers at present
293
if (Assert.ASSERTS_ENABLED) {
294
if (VM.getVM().isServerCompiler()) {
295
Assert.that(!cb.isRuntimeStub() ||
296
(nofCallee >= SAVED_ON_ENTRY_REG_COUNT || nofCallee >= C_SAVED_ON_ENTRY_REG_COUNT),
297
"must save all");
298
}
299
}
300
301
// Copy found callee-saved register to reg_map
302
for (int i = 0; i < nofCallee; i++) {
303
regMap.setLocation(regs[i], locs[i]);
304
}
305
}
306
307
public ImmutableOopMapPair getPairAt(int index) {
308
return pairAt(index);
309
}
310
311
private int getSize() {
312
return (int) sizeField.getValue(addr);
313
}
314
315
public ImmutableOopMap getMap(ImmutableOopMapPair pair) {
316
Assert.that(pair.getOffset() < getSize(), "boundary check: this: " + this + " offset: " + pair);
317
return new ImmutableOopMap(dataStart().addOffsetTo(pair.getOffset()));
318
}
319
320
public String toString() {
321
StringBuilder builder = new StringBuilder();
322
builder.append("Set{ ")
323
.append("addr = ").append(addr)
324
.append(", count = ").append(getCount())
325
.append(", size = ").append(getSize())
326
.append(", pairs = [");
327
328
for (int i = 0; i < getCount(); ++i) {
329
builder.append(getPairAt(i));
330
}
331
332
builder.append("]");
333
return builder.toString();
334
}
335
}
336
337