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/code/CodeCache.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.code;
26
27
import java.util.*;
28
import sun.jvm.hotspot.debugger.*;
29
import sun.jvm.hotspot.memory.*;
30
import sun.jvm.hotspot.runtime.*;
31
import sun.jvm.hotspot.types.*;
32
import sun.jvm.hotspot.utilities.*;
33
import sun.jvm.hotspot.utilities.Observable;
34
import sun.jvm.hotspot.utilities.Observer;
35
36
public class CodeCache {
37
private static GrowableArray<CodeHeap> heapArray;
38
private static VirtualConstructor virtualConstructor;
39
40
static {
41
VM.registerVMInitializedObserver(new Observer() {
42
public void update(Observable o, Object data) {
43
initialize(VM.getVM().getTypeDataBase());
44
}
45
});
46
}
47
48
private static synchronized void initialize(TypeDataBase db) {
49
Type type = db.lookupType("CodeCache");
50
51
// Get array of CodeHeaps
52
// Note: CodeHeap may be subclassed with optional private heap mechanisms.
53
Type codeHeapType = db.lookupType("CodeHeap");
54
VirtualBaseConstructor<CodeHeap> heapConstructor =
55
new VirtualBaseConstructor<>(db, codeHeapType, "sun.jvm.hotspot.memory", CodeHeap.class);
56
57
AddressField heapsField = type.getAddressField("_heaps");
58
heapArray = GrowableArray.create(heapsField.getValue(), heapConstructor);
59
60
virtualConstructor = new VirtualConstructor(db);
61
// Add mappings for all possible CodeBlob subclasses
62
virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
63
virtualConstructor.addMapping("nmethod", NMethod.class);
64
virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
65
virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
66
virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
67
virtualConstructor.addMapping("VtableBlob", VtableBlob.class);
68
virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
69
virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
70
if (VM.getVM().isServerCompiler()) {
71
virtualConstructor.addMapping("ExceptionBlob", ExceptionBlob.class);
72
virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
73
}
74
}
75
76
public boolean contains(Address p) {
77
for (int i = 0; i < heapArray.length(); ++i) {
78
if (heapArray.at(i).contains(p)) {
79
return true;
80
}
81
}
82
return false;
83
}
84
85
/** When VM.getVM().isDebugging() returns true, this behaves like
86
findBlobUnsafe */
87
public CodeBlob findBlob(Address start) {
88
CodeBlob result = findBlobUnsafe(start);
89
if (result == null) return null;
90
if (VM.getVM().isDebugging()) {
91
return result;
92
}
93
// We could potientially look up non_entrant methods
94
// NOTE: this is effectively a "guarantee", and is slightly different from the one in the VM
95
if (Assert.ASSERTS_ENABLED) {
96
Assert.that(!(result.isZombie() || result.isLockedByVM()), "unsafe access to zombie method");
97
}
98
return result;
99
}
100
101
public CodeBlob findBlobUnsafe(Address start) {
102
CodeBlob result = null;
103
CodeHeap containing_heap = null;
104
for (int i = 0; i < heapArray.length(); ++i) {
105
if (heapArray.at(i).contains(start)) {
106
containing_heap = heapArray.at(i);
107
break;
108
}
109
}
110
if (containing_heap == null) {
111
return null;
112
}
113
114
try {
115
result = (CodeBlob) virtualConstructor.instantiateWrapperFor(containing_heap.findStart(start));
116
}
117
catch (WrongTypeException wte) {
118
Address cbAddr = null;
119
try {
120
cbAddr = containing_heap.findStart(start);
121
}
122
catch (Exception findEx) {
123
findEx.printStackTrace();
124
}
125
126
String message = "Couldn't deduce type of CodeBlob ";
127
if (cbAddr != null) {
128
message = message + "@" + cbAddr + " ";
129
}
130
message = message + "for PC=" + start;
131
132
throw new RuntimeException(message, wte);
133
}
134
if (result == null) return null;
135
if (Assert.ASSERTS_ENABLED) {
136
// The pointer to the HeapBlock that contains this blob is outside of the blob,
137
// but it shouldn't be an error to find a blob based on the pointer to the HeapBlock.
138
// The heap block header is padded out to an 8-byte boundary. See heap.hpp. The
139
// simplest way to compute the header size is just 2 * addressSize.
140
Assert.that(result.blobContains(start) ||
141
result.blobContains(start.addOffsetTo(2 * VM.getVM().getAddressSize())),
142
"found wrong CodeBlob");
143
}
144
return result;
145
}
146
147
public NMethod findNMethod(Address start) {
148
CodeBlob cb = findBlob(start);
149
if (Assert.ASSERTS_ENABLED) {
150
Assert.that(cb == null || cb.isNMethod(), "did not find an nmethod");
151
}
152
return (NMethod) cb;
153
}
154
155
public NMethod findNMethodUnsafe(Address start) {
156
CodeBlob cb = findBlobUnsafe(start);
157
if (Assert.ASSERTS_ENABLED) {
158
Assert.that(cb == null || cb.isNMethod(), "did not find an nmethod");
159
}
160
return (NMethod) cb;
161
}
162
163
/** Routine for instantiating appropriately-typed wrapper for a
164
CodeBlob. Used by CodeCache, Runtime1, etc. */
165
public CodeBlob createCodeBlobWrapper(Address codeBlobAddr) {
166
try {
167
return (CodeBlob) virtualConstructor.instantiateWrapperFor(codeBlobAddr);
168
}
169
catch (Exception e) {
170
String message = "Unable to deduce type of CodeBlob from address " + codeBlobAddr +
171
" (expected type nmethod, RuntimeStub, VtableBlob, ";
172
if (VM.getVM().isClientCompiler()) {
173
message = message + " or ";
174
}
175
message = message + "SafepointBlob";
176
if (VM.getVM().isServerCompiler()) {
177
message = message + ", DeoptimizationBlob, or ExceptionBlob";
178
}
179
message = message + ")";
180
throw new RuntimeException(message);
181
}
182
}
183
184
public void iterate(CodeCacheVisitor visitor) {
185
visitor.prologue(lowBound(), highBound());
186
for (int i = 0; i < heapArray.length(); ++i) {
187
CodeHeap current_heap = heapArray.at(i);
188
current_heap.iterate(visitor, this);
189
}
190
visitor.epilogue();
191
}
192
193
//--------------------------------------------------------------------------------
194
// Internals only below this point
195
//
196
197
private Address lowBound() {
198
Address low = heapArray.at(0).begin();
199
for (int i = 1; i < heapArray.length(); ++i) {
200
if (heapArray.at(i).begin().lessThan(low)) {
201
low = heapArray.at(i).begin();
202
}
203
}
204
return low;
205
}
206
207
private Address highBound() {
208
Address high = heapArray.at(0).end();
209
for (int i = 1; i < heapArray.length(); ++i) {
210
if (heapArray.at(i).end().greaterThan(high)) {
211
high = heapArray.at(i).end();
212
}
213
}
214
return high;
215
}
216
}
217
218