author | rbackman |
Tue, 26 Apr 2016 10:28:51 +0200 | |
changeset 38133 | 78b95467b9f1 |
parent 36818 | b40330c06dea |
child 46707 | cbfdbefc6ea3 |
permissions | -rw-r--r-- |
1 | 1 |
/* |
38133
78b95467b9f1
8151956: Support non-continuous CodeBlobs in HotSpot
rbackman
parents:
36818
diff
changeset
|
2 |
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. |
1 | 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 |
* |
|
5547
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
4095
diff
changeset
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
4095
diff
changeset
|
20 |
* or visit www.oracle.com if you need additional information or have any |
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
4095
diff
changeset
|
21 |
* questions. |
1 | 22 |
* |
23 |
*/ |
|
24 |
||
25 |
package sun.jvm.hotspot.code; |
|
26 |
||
27 |
import java.io.*; |
|
28 |
import java.util.*; |
|
29 |
import sun.jvm.hotspot.debugger.*; |
|
30 |
import sun.jvm.hotspot.oops.*; |
|
31 |
import sun.jvm.hotspot.runtime.*; |
|
32 |
import sun.jvm.hotspot.types.*; |
|
33 |
import sun.jvm.hotspot.utilities.*; |
|
34 |
||
38133
78b95467b9f1
8151956: Support non-continuous CodeBlobs in HotSpot
rbackman
parents:
36818
diff
changeset
|
35 |
public class NMethod extends CompiledMethod { |
1 | 36 |
private static long pcDescSize; |
37 |
/** != InvocationEntryBci if this nmethod is an on-stack replacement method */ |
|
38 |
private static CIntegerField entryBCIField; |
|
39 |
/** To support simple linked-list chaining of nmethods */ |
|
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
40 |
private static AddressField osrLinkField; |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
41 |
private static AddressField scavengeRootLinkField; |
4095
6e0acfda1d47
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
3908
diff
changeset
|
42 |
private static JByteField scavengeRootStateField; |
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
43 |
|
1 | 44 |
/** Offsets for different nmethod parts */ |
45 |
private static CIntegerField exceptionOffsetField; |
|
46 |
private static CIntegerField origPCOffsetField; |
|
47 |
private static CIntegerField stubOffsetField; |
|
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
48 |
private static CIntegerField oopsOffsetField; |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
49 |
private static CIntegerField metadataOffsetField; |
1 | 50 |
private static CIntegerField scopesPCsOffsetField; |
51 |
private static CIntegerField dependenciesOffsetField; |
|
52 |
private static CIntegerField handlerTableOffsetField; |
|
53 |
private static CIntegerField nulChkTableOffsetField; |
|
54 |
private static CIntegerField nmethodEndOffsetField; |
|
55 |
||
56 |
/** Offsets for entry points */ |
|
57 |
/** Entry point with class check */ |
|
58 |
private static AddressField entryPointField; |
|
59 |
/** Entry point without class check */ |
|
60 |
private static AddressField verifiedEntryPointField; |
|
61 |
/** Entry point for on stack replacement */ |
|
62 |
private static AddressField osrEntryPointField; |
|
63 |
||
64 |
// FIXME: add access to flags (how?) |
|
65 |
||
66 |
/** NMethod Flushing lock (if non-zero, then the nmethod is not removed) */ |
|
67 |
private static JIntField lockCountField; |
|
68 |
||
69 |
/** not_entrant method removal. Each mark_sweep pass will update |
|
70 |
this mark to current sweep invocation count if it is seen on the |
|
71 |
stack. An not_entrant method can be removed when there is no |
|
72 |
more activations, i.e., when the _stack_traversal_mark is less than |
|
73 |
current sweep traversal index. */ |
|
74 |
private static CIntegerField stackTraversalMarkField; |
|
75 |
||
17123
a8e62eed2e3e
8011675: adding compilation level to replay data
iignatyev
parents:
14477
diff
changeset
|
76 |
private static CIntegerField compLevelField; |
a8e62eed2e3e
8011675: adding compilation level to replay data
iignatyev
parents:
14477
diff
changeset
|
77 |
|
1 | 78 |
static { |
79 |
VM.registerVMInitializedObserver(new Observer() { |
|
80 |
public void update(Observable o, Object data) { |
|
81 |
initialize(VM.getVM().getTypeDataBase()); |
|
82 |
} |
|
83 |
}); |
|
84 |
} |
|
85 |
||
86 |
private static void initialize(TypeDataBase db) { |
|
87 |
Type type = db.lookupType("nmethod"); |
|
88 |
||
89 |
entryBCIField = type.getCIntegerField("_entry_bci"); |
|
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
90 |
osrLinkField = type.getAddressField("_osr_link"); |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
91 |
scavengeRootLinkField = type.getAddressField("_scavenge_root_link"); |
4095
6e0acfda1d47
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
3908
diff
changeset
|
92 |
scavengeRootStateField = type.getJByteField("_scavenge_root_state"); |
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
93 |
|
1 | 94 |
exceptionOffsetField = type.getCIntegerField("_exception_offset"); |
95 |
origPCOffsetField = type.getCIntegerField("_orig_pc_offset"); |
|
96 |
stubOffsetField = type.getCIntegerField("_stub_offset"); |
|
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
97 |
oopsOffsetField = type.getCIntegerField("_oops_offset"); |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
98 |
metadataOffsetField = type.getCIntegerField("_metadata_offset"); |
1 | 99 |
scopesPCsOffsetField = type.getCIntegerField("_scopes_pcs_offset"); |
100 |
dependenciesOffsetField = type.getCIntegerField("_dependencies_offset"); |
|
101 |
handlerTableOffsetField = type.getCIntegerField("_handler_table_offset"); |
|
102 |
nulChkTableOffsetField = type.getCIntegerField("_nul_chk_table_offset"); |
|
103 |
nmethodEndOffsetField = type.getCIntegerField("_nmethod_end_offset"); |
|
104 |
entryPointField = type.getAddressField("_entry_point"); |
|
105 |
verifiedEntryPointField = type.getAddressField("_verified_entry_point"); |
|
106 |
osrEntryPointField = type.getAddressField("_osr_entry_point"); |
|
107 |
lockCountField = type.getJIntField("_lock_count"); |
|
108 |
stackTraversalMarkField = type.getCIntegerField("_stack_traversal_mark"); |
|
17123
a8e62eed2e3e
8011675: adding compilation level to replay data
iignatyev
parents:
14477
diff
changeset
|
109 |
compLevelField = type.getCIntegerField("_comp_level"); |
1 | 110 |
pcDescSize = db.lookupType("PcDesc").getSize(); |
111 |
} |
|
112 |
||
113 |
public NMethod(Address addr) { |
|
114 |
super(addr); |
|
115 |
} |
|
116 |
||
117 |
// Accessors |
|
118 |
public Address getAddress() { |
|
119 |
return addr; |
|
120 |
} |
|
121 |
||
122 |
// Type info |
|
123 |
public boolean isNMethod() { return true; } |
|
124 |
public boolean isJavaMethod() { return !getMethod().isNative(); } |
|
125 |
public boolean isNativeMethod() { return getMethod().isNative(); } |
|
126 |
public boolean isOSRMethod() { return getEntryBCI() != VM.getVM().getInvocationEntryBCI(); } |
|
127 |
||
128 |
/** Boundaries for different parts */ |
|
6418 | 129 |
public Address constantsBegin() { return contentBegin(); } |
1 | 130 |
public Address constantsEnd() { return getEntryPoint(); } |
10517
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
131 |
public Address instsBegin() { return codeBegin(); } |
6418 | 132 |
public Address instsEnd() { return headerBegin().addOffsetTo(getStubOffset()); } |
1 | 133 |
public Address exceptionBegin() { return headerBegin().addOffsetTo(getExceptionOffset()); } |
134 |
public Address stubBegin() { return headerBegin().addOffsetTo(getStubOffset()); } |
|
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
135 |
public Address stubEnd() { return headerBegin().addOffsetTo(getOopsOffset()); } |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
136 |
public Address oopsBegin() { return headerBegin().addOffsetTo(getOopsOffset()); } |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
137 |
public Address oopsEnd() { return headerBegin().addOffsetTo(getMetadataOffset()); } |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
138 |
public Address metadataBegin() { return headerBegin().addOffsetTo(getMetadataOffset()); } |
38133
78b95467b9f1
8151956: Support non-continuous CodeBlobs in HotSpot
rbackman
parents:
36818
diff
changeset
|
139 |
public Address metadataEnd() { return scopesDataBegin(); } |
1 | 140 |
public Address scopesDataEnd() { return headerBegin().addOffsetTo(getScopesPCsOffset()); } |
141 |
public Address scopesPCsBegin() { return headerBegin().addOffsetTo(getScopesPCsOffset()); } |
|
142 |
public Address scopesPCsEnd() { return headerBegin().addOffsetTo(getDependenciesOffset()); } |
|
143 |
public Address dependenciesBegin() { return headerBegin().addOffsetTo(getDependenciesOffset()); } |
|
144 |
public Address dependenciesEnd() { return headerBegin().addOffsetTo(getHandlerTableOffset()); } |
|
145 |
public Address handlerTableBegin() { return headerBegin().addOffsetTo(getHandlerTableOffset()); } |
|
146 |
public Address handlerTableEnd() { return headerBegin().addOffsetTo(getNulChkTableOffset()); } |
|
147 |
public Address nulChkTableBegin() { return headerBegin().addOffsetTo(getNulChkTableOffset()); } |
|
148 |
public Address nulChkTableEnd() { return headerBegin().addOffsetTo(getNMethodEndOffset()); } |
|
149 |
||
150 |
public int constantsSize() { return (int) constantsEnd() .minus(constantsBegin()); } |
|
6418 | 151 |
public int instsSize() { return (int) instsEnd() .minus(instsBegin()); } |
1 | 152 |
public int stubSize() { return (int) stubEnd() .minus(stubBegin()); } |
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
153 |
public int oopsSize() { return (int) oopsEnd() .minus(oopsBegin()); } |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
154 |
public int metadataSize() { return (int) metadataEnd() .minus(metadataBegin()); } |
1 | 155 |
public int scopesDataSize() { return (int) scopesDataEnd() .minus(scopesDataBegin()); } |
156 |
public int scopesPCsSize() { return (int) scopesPCsEnd() .minus(scopesPCsBegin()); } |
|
157 |
public int dependenciesSize() { return (int) dependenciesEnd().minus(dependenciesBegin()); } |
|
158 |
public int handlerTableSize() { return (int) handlerTableEnd().minus(handlerTableBegin()); } |
|
159 |
public int nulChkTableSize() { return (int) nulChkTableEnd() .minus(nulChkTableBegin()); } |
|
160 |
public int origPCOffset() { return (int) origPCOffsetField.getValue(addr); } |
|
161 |
||
162 |
public int totalSize() { |
|
163 |
return |
|
164 |
constantsSize() + |
|
6418 | 165 |
instsSize() + |
1 | 166 |
stubSize() + |
167 |
scopesDataSize() + |
|
168 |
scopesPCsSize() + |
|
169 |
dependenciesSize() + |
|
170 |
handlerTableSize() + |
|
171 |
nulChkTableSize(); |
|
172 |
} |
|
173 |
||
174 |
public boolean constantsContains (Address addr) { return constantsBegin() .lessThanOrEqual(addr) && constantsEnd() .greaterThan(addr); } |
|
6418 | 175 |
public boolean instsContains (Address addr) { return instsBegin() .lessThanOrEqual(addr) && instsEnd() .greaterThan(addr); } |
1 | 176 |
public boolean stubContains (Address addr) { return stubBegin() .lessThanOrEqual(addr) && stubEnd() .greaterThan(addr); } |
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
177 |
public boolean oopsContains (Address addr) { return oopsBegin() .lessThanOrEqual(addr) && oopsEnd() .greaterThan(addr); } |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
178 |
public boolean metadataContains (Address addr) { return metadataBegin() .lessThanOrEqual(addr) && metadataEnd() .greaterThan(addr); } |
1 | 179 |
public boolean scopesDataContains (Address addr) { return scopesDataBegin() .lessThanOrEqual(addr) && scopesDataEnd() .greaterThan(addr); } |
180 |
public boolean scopesPCsContains (Address addr) { return scopesPCsBegin() .lessThanOrEqual(addr) && scopesPCsEnd() .greaterThan(addr); } |
|
181 |
public boolean handlerTableContains(Address addr) { return handlerTableBegin().lessThanOrEqual(addr) && handlerTableEnd().greaterThan(addr); } |
|
182 |
public boolean nulChkTableContains (Address addr) { return nulChkTableBegin() .lessThanOrEqual(addr) && nulChkTableEnd() .greaterThan(addr); } |
|
183 |
||
10547 | 184 |
public int getOopsLength() { return (int) (oopsSize() / VM.getVM().getOopSize()); } |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
185 |
public int getMetadataLength() { return (int) (metadataSize() / VM.getVM().getOopSize()); } |
10547 | 186 |
|
1 | 187 |
/** Entry points */ |
188 |
public Address getEntryPoint() { return entryPointField.getValue(addr); } |
|
189 |
public Address getVerifiedEntryPoint() { return verifiedEntryPointField.getValue(addr); } |
|
190 |
||
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
191 |
/** Support for oops in scopes and relocs. Note: index 0 is reserved for null. */ |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
192 |
public OopHandle getOopAt(int index) { |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
193 |
if (index == 0) return null; |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
194 |
if (Assert.ASSERTS_ENABLED) { |
10547 | 195 |
Assert.that(index > 0 && index <= getOopsLength(), "must be a valid non-zero index"); |
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
196 |
} |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
197 |
return oopsBegin().getOopHandleAt((index - 1) * VM.getVM().getOopSize()); |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
198 |
} |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
199 |
|
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
200 |
/** Support for metadata in scopes and relocs. Note: index 0 is reserved for null. */ |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
201 |
public Address getMetadataAt(int index) { |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
202 |
if (index == 0) return null; |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
203 |
if (Assert.ASSERTS_ENABLED) { |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
204 |
Assert.that(index > 0 && index <= getMetadataLength(), "must be a valid non-zero index"); |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
205 |
} |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
206 |
return metadataBegin().getAddressAt((index - 1) * VM.getVM().getOopSize()); |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
207 |
} |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
208 |
|
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
209 |
public Method getMethodAt(int index) { |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
210 |
return (Method)Metadata.instantiateWrapperFor(getMetadataAt(index)); |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
211 |
} |
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
212 |
|
1 | 213 |
// FIXME: add interpreter_entry_point() |
214 |
// FIXME: add lazy_interpreter_entry_point() for C2 |
|
215 |
||
216 |
// ********** |
|
217 |
// * FIXME: * ADD ACCESS TO FLAGS!!!! |
|
218 |
// ********** |
|
219 |
// public boolean isInUse(); |
|
220 |
// public boolean isAlive(); |
|
221 |
// public boolean isNotEntrant(); |
|
222 |
// public boolean isZombie(); |
|
223 |
||
224 |
// ******************************** |
|
225 |
// * MAJOR FIXME: MAJOR HACK HERE * |
|
226 |
// ******************************** |
|
227 |
public boolean isZombie() { return false; } |
|
228 |
||
229 |
// public boolean isUnloaded(); |
|
230 |
// public boolean isYoung(); |
|
231 |
// public boolean isOld(); |
|
232 |
// public int age(); |
|
233 |
// public boolean isMarkedForDeoptimization(); |
|
234 |
// public boolean isMarkedForUnloading(); |
|
235 |
// public int level(); |
|
236 |
// public int version(); |
|
237 |
||
238 |
// FIXME: add mutators for above |
|
239 |
// FIXME: add exception cache access? |
|
240 |
||
241 |
/** On-stack replacement support */ |
|
242 |
// FIXME: add mutators |
|
243 |
public int getOSREntryBCI() { |
|
244 |
if (Assert.ASSERTS_ENABLED) { |
|
245 |
Assert.that(getEntryBCI() != VM.getVM().getInvocationEntryBCI(), "wrong kind of nmethod"); |
|
246 |
} |
|
247 |
return getEntryBCI(); |
|
248 |
} |
|
249 |
||
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
250 |
public NMethod getOSRLink() { |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
251 |
return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr)); |
1 | 252 |
} |
253 |
||
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
254 |
public NMethod getScavengeRootLink() { |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
255 |
return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootLinkField.getValue(addr)); |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
256 |
} |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
257 |
|
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
258 |
public int getScavengeRootState() { |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
259 |
return (int) scavengeRootStateField.getValue(addr); |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
260 |
} |
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
261 |
|
10517
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
262 |
// MethodHandle |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
263 |
public boolean isMethodHandleReturn(Address returnPc) { |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
264 |
// Hard to read a bit fields from Java and it's only there for performance |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
265 |
// so just go directly to the PCDesc |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
266 |
// if (!hasMethodHandleInvokes()) return false; |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
267 |
PCDesc pd = getPCDescAt(returnPc); |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
268 |
if (pd == null) |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
269 |
return false; |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
270 |
return pd.isMethodHandleInvoke(); |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
271 |
} |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
272 |
|
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
273 |
// Deopt |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
274 |
// Return true is the PC is one would expect if the frame is being deopted. |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
275 |
public boolean isDeoptPc (Address pc) { return isDeoptEntry(pc) || isDeoptMhEntry(pc); } |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
276 |
public boolean isDeoptEntry (Address pc) { return pc == deoptHandlerBegin(); } |
f92c9ff3a15f
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
6418
diff
changeset
|
277 |
public boolean isDeoptMhEntry (Address pc) { return pc == deoptMhHandlerBegin(); } |
3908
24b55ad4c228
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
3686
diff
changeset
|
278 |
|
1 | 279 |
/** Tells whether frames described by this nmethod can be |
280 |
deoptimized. Note: native wrappers cannot be deoptimized. */ |
|
281 |
public boolean canBeDeoptimized() { return isJavaMethod(); } |
|
282 |
||
283 |
// FIXME: add inline cache support |
|
284 |
// FIXME: add flush() |
|
285 |
||
286 |
public boolean isLockedByVM() { return lockCountField.getValue(addr) > 0; } |
|
287 |
||
288 |
// FIXME: add mark_as_seen_on_stack |
|
289 |
// FIXME: add can_not_entrant_be_converted |
|
290 |
||
291 |
// FIXME: add GC support |
|
292 |
// void follow_roots_or_mark_for_unloading(bool unloading_occurred, bool& marked_for_unloading); |
|
293 |
// void follow_root_or_mark_for_unloading(oop* root, bool unloading_occurred, bool& marked_for_unloading); |
|
294 |
// void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, void f(oop*)); |
|
295 |
// void adjust_pointers(); |
|
296 |
||
297 |
/** Finds a PCDesc with real-pc equal to "pc" */ |
|
298 |
public PCDesc getPCDescAt(Address pc) { |
|
299 |
// FIXME: consider adding cache like the one down in the VM |
|
300 |
for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) { |
|
301 |
PCDesc pcDesc = new PCDesc(p); |
|
302 |
if (pcDesc.getRealPC(this).equals(pc)) { |
|
303 |
return pcDesc; |
|
304 |
} |
|
305 |
} |
|
306 |
return null; |
|
307 |
} |
|
308 |
||
309 |
/** ScopeDesc for an instruction */ |
|
310 |
public ScopeDesc getScopeDescAt(Address pc) { |
|
311 |
PCDesc pd = getPCDescAt(pc); |
|
312 |
if (Assert.ASSERTS_ENABLED) { |
|
313 |
Assert.that(pd != null, "scope must be present"); |
|
314 |
} |
|
4095
6e0acfda1d47
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
3908
diff
changeset
|
315 |
return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute()); |
1 | 316 |
} |
317 |
||
318 |
/** This is only for use by the debugging system, and is only |
|
319 |
intended for use in the topmost frame, where we are not |
|
320 |
guaranteed to be at a PC for which we have a PCDesc. It finds |
|
321 |
the PCDesc with realPC closest to the current PC. */ |
|
322 |
public PCDesc getPCDescNearDbg(Address pc) { |
|
323 |
PCDesc bestGuessPCDesc = null; |
|
324 |
long bestDistance = 0; |
|
325 |
for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) { |
|
326 |
PCDesc pcDesc = new PCDesc(p); |
|
327 |
// In case pc is null |
|
328 |
long distance = -pcDesc.getRealPC(this).minus(pc); |
|
329 |
if ((bestGuessPCDesc == null) || |
|
330 |
((distance >= 0) && (distance < bestDistance))) { |
|
331 |
bestGuessPCDesc = pcDesc; |
|
332 |
bestDistance = distance; |
|
333 |
} |
|
334 |
} |
|
335 |
return bestGuessPCDesc; |
|
336 |
} |
|
337 |
||
13873 | 338 |
PCDesc find_pc_desc(long pc, boolean approximate) { |
339 |
return find_pc_desc_internal(pc, approximate); |
|
340 |
} |
|
341 |
||
342 |
// Finds a PcDesc with real-pc equal to "pc" |
|
343 |
PCDesc find_pc_desc_internal(long pc, boolean approximate) { |
|
344 |
long base_address = VM.getAddressValue(codeBegin()); |
|
345 |
int pc_offset = (int) (pc - base_address); |
|
346 |
||
347 |
// Fallback algorithm: quasi-linear search for the PcDesc |
|
348 |
// Find the last pc_offset less than the given offset. |
|
349 |
// The successor must be the required match, if there is a match at all. |
|
350 |
// (Use a fixed radix to avoid expensive affine pointer arithmetic.) |
|
351 |
Address lower = scopesPCsBegin(); |
|
352 |
Address upper = scopesPCsEnd(); |
|
353 |
upper = upper.addOffsetTo(-pcDescSize); // exclude final sentinel |
|
354 |
if (lower.greaterThan(upper)) return null; // native method; no PcDescs at all |
|
355 |
||
356 |
// Take giant steps at first (4096, then 256, then 16, then 1) |
|
357 |
int LOG2_RADIX = 4; |
|
358 |
int RADIX = (1 << LOG2_RADIX); |
|
359 |
Address mid; |
|
360 |
for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) { |
|
361 |
while ((mid = lower.addOffsetTo(step * pcDescSize)).lessThan(upper)) { |
|
362 |
PCDesc m = new PCDesc(mid); |
|
363 |
if (m.getPCOffset() < pc_offset) { |
|
364 |
lower = mid; |
|
365 |
} else { |
|
366 |
upper = mid; |
|
367 |
break; |
|
368 |
} |
|
369 |
} |
|
370 |
} |
|
371 |
// Sneak up on the value with a linear search of length ~16. |
|
372 |
while (true) { |
|
373 |
mid = lower.addOffsetTo(pcDescSize); |
|
374 |
PCDesc m = new PCDesc(mid); |
|
375 |
if (m.getPCOffset() < pc_offset) { |
|
376 |
lower = mid; |
|
377 |
} else { |
|
378 |
upper = mid; |
|
379 |
break; |
|
380 |
} |
|
381 |
} |
|
382 |
||
383 |
PCDesc u = new PCDesc(upper); |
|
384 |
if (match_desc(u, pc_offset, approximate)) { |
|
385 |
return u; |
|
386 |
} else { |
|
387 |
return null; |
|
388 |
} |
|
389 |
} |
|
390 |
||
391 |
// ScopeDesc retrieval operation |
|
392 |
PCDesc pc_desc_at(long pc) { return find_pc_desc(pc, false); } |
|
393 |
// pc_desc_near returns the first PCDesc at or after the givne pc. |
|
394 |
PCDesc pc_desc_near(long pc) { return find_pc_desc(pc, true); } |
|
395 |
||
396 |
// Return a the last scope in (begin..end] |
|
397 |
public ScopeDesc scope_desc_in(long begin, long end) { |
|
398 |
PCDesc p = pc_desc_near(begin+1); |
|
399 |
if (p != null && VM.getAddressValue(p.getRealPC(this)) <= end) { |
|
400 |
return new ScopeDesc(this, p.getScopeDecodeOffset(), p.getObjDecodeOffset(), p.getReexecute()); |
|
401 |
} |
|
402 |
return null; |
|
403 |
} |
|
404 |
||
405 |
static boolean match_desc(PCDesc pc, int pc_offset, boolean approximate) { |
|
406 |
if (!approximate) { |
|
407 |
return pc.getPCOffset() == pc_offset; |
|
408 |
} else { |
|
409 |
PCDesc prev = new PCDesc(pc.getAddress().addOffsetTo(-pcDescSize)); |
|
410 |
return prev.getPCOffset() < pc_offset && pc_offset <= pc.getPCOffset(); |
|
411 |
} |
|
412 |
} |
|
413 |
||
1 | 414 |
/** This is only for use by the debugging system, and is only |
415 |
intended for use in the topmost frame, where we are not |
|
416 |
guaranteed to be at a PC for which we have a PCDesc. It finds |
|
417 |
the ScopeDesc closest to the current PC. NOTE that this may |
|
418 |
return NULL for compiled methods which don't have any |
|
419 |
ScopeDescs! */ |
|
420 |
public ScopeDesc getScopeDescNearDbg(Address pc) { |
|
421 |
PCDesc pd = getPCDescNearDbg(pc); |
|
422 |
if (pd == null) return null; |
|
4095
6e0acfda1d47
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
3908
diff
changeset
|
423 |
return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute()); |
1 | 424 |
} |
425 |
||
4095
6e0acfda1d47
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
3908
diff
changeset
|
426 |
public Map/*<Address, PCDesc>*/ getSafepoints() { |
6e0acfda1d47
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
3908
diff
changeset
|
427 |
Map safepoints = new HashMap(); // Map<Address, PCDesc> |
1 | 428 |
sun.jvm.hotspot.debugger.Address p = null; |
429 |
for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); |
|
430 |
p = p.addOffsetTo(pcDescSize)) { |
|
431 |
PCDesc pcDesc = new PCDesc(p); |
|
432 |
sun.jvm.hotspot.debugger.Address pc = pcDesc.getRealPC(this); |
|
433 |
safepoints.put(pc, pcDesc); |
|
434 |
} |
|
435 |
return safepoints; |
|
436 |
} |
|
437 |
||
438 |
// FIXME: add getPCOffsetForBCI() |
|
439 |
// FIXME: add embeddedOopAt() |
|
440 |
// FIXME: add isDependentOn() |
|
441 |
// FIXME: add isPatchableAt() |
|
442 |
||
443 |
/** Support for code generation. Only here for proof-of-concept. */ |
|
444 |
public static int getEntryPointOffset() { return (int) entryPointField.getOffset(); } |
|
445 |
public static int getVerifiedEntryPointOffset() { return (int) verifiedEntryPointField.getOffset(); } |
|
446 |
public static int getOSREntryPointOffset() { return (int) osrEntryPointField.getOffset(); } |
|
447 |
public static int getEntryBCIOffset() { return (int) entryBCIField.getOffset(); } |
|
448 |
||
449 |
public void print() { |
|
450 |
printOn(System.out); |
|
451 |
} |
|
452 |
||
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
453 |
protected void printComponentsOn(PrintStream tty) { |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
454 |
// FIXME: add relocation information |
6418 | 455 |
tty.println(" content: [" + contentBegin() + ", " + contentEnd() + "), " + |
456 |
" code: [" + codeBegin() + ", " + codeEnd() + "), " + |
|
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
457 |
" data: [" + dataBegin() + ", " + dataEnd() + "), " + |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
458 |
" oops: [" + oopsBegin() + ", " + oopsEnd() + "), " + |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
459 |
" frame size: " + getFrameSize()); |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
460 |
} |
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
461 |
|
1 | 462 |
public String toString() { |
463 |
Method method = getMethod(); |
|
464 |
return "NMethod for " + |
|
465 |
method.getMethodHolder().getName().asString() + "." + |
|
466 |
method.getName().asString() + method.getSignature().asString() + "==>n" + |
|
467 |
super.toString(); |
|
468 |
} |
|
469 |
||
470 |
public String flagsToString() { |
|
471 |
// FIXME need access to flags... |
|
472 |
return ""; |
|
473 |
} |
|
474 |
||
475 |
public String getName() { |
|
476 |
Method method = getMethod(); |
|
477 |
return "NMethod for " + |
|
478 |
method.getMethodHolder().getName().asString() + "." + |
|
479 |
method.getName().asString() + |
|
480 |
method.getSignature().asString(); |
|
481 |
} |
|
482 |
||
14477
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
483 |
public void dumpReplayData(PrintStream out) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
484 |
HashMap h = new HashMap(); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
485 |
for (int i = 1; i < getMetadataLength(); i++) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
486 |
Metadata meta = Metadata.instantiateWrapperFor(getMetadataAt(i)); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
487 |
System.err.println(meta); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
488 |
if (h.get(meta) != null) continue; |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
489 |
h.put(meta, meta); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
490 |
if (meta instanceof InstanceKlass) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
491 |
((InstanceKlass)meta).dumpReplayData(out); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
492 |
} else if (meta instanceof Method) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
493 |
((Method)meta).dumpReplayData(out); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
494 |
MethodData mdo = ((Method)meta).getMethodData(); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
495 |
if (mdo != null) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
496 |
mdo.dumpReplayData(out); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
497 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
498 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
499 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
500 |
Method method = getMethod(); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
501 |
if (h.get(method) == null) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
502 |
method.dumpReplayData(out); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
503 |
MethodData mdo = method.getMethodData(); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
504 |
if (mdo != null) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
505 |
mdo.dumpReplayData(out); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
506 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
507 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
508 |
if (h.get(method.getMethodHolder()) == null) { |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
509 |
((InstanceKlass)method.getMethodHolder()).dumpReplayData(out); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
510 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
511 |
Klass holder = method.getMethodHolder(); |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
512 |
out.println("compile " + holder.getName().asString() + " " + |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
513 |
OopUtilities.escapeString(method.getName().asString()) + " " + |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
514 |
method.getSignature().asString() + " " + |
17123
a8e62eed2e3e
8011675: adding compilation level to replay data
iignatyev
parents:
14477
diff
changeset
|
515 |
getEntryBCI() + " " + getCompLevel()); |
14477
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
516 |
|
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
517 |
} |
95e66ea71f71
6830717: replay of compilations would help with debugging
minqi
parents:
13873
diff
changeset
|
518 |
|
1 | 519 |
//-------------------------------------------------------------------------------- |
520 |
// Internals only below this point |
|
521 |
// |
|
522 |
||
523 |
private int getEntryBCI() { return (int) entryBCIField .getValue(addr); } |
|
524 |
private int getExceptionOffset() { return (int) exceptionOffsetField .getValue(addr); } |
|
525 |
private int getStubOffset() { return (int) stubOffsetField .getValue(addr); } |
|
5686
5435e77aa3df
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
4095
diff
changeset
|
526 |
private int getOopsOffset() { return (int) oopsOffsetField .getValue(addr); } |
13728
882756847a04
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
10547
diff
changeset
|
527 |
private int getMetadataOffset() { return (int) metadataOffsetField .getValue(addr); } |
1 | 528 |
private int getScopesPCsOffset() { return (int) scopesPCsOffsetField .getValue(addr); } |
529 |
private int getDependenciesOffset() { return (int) dependenciesOffsetField.getValue(addr); } |
|
530 |
private int getHandlerTableOffset() { return (int) handlerTableOffsetField.getValue(addr); } |
|
531 |
private int getNulChkTableOffset() { return (int) nulChkTableOffsetField .getValue(addr); } |
|
532 |
private int getNMethodEndOffset() { return (int) nmethodEndOffsetField .getValue(addr); } |
|
17123
a8e62eed2e3e
8011675: adding compilation level to replay data
iignatyev
parents:
14477
diff
changeset
|
533 |
private int getCompLevel() { return (int) compLevelField .getValue(addr); } |
1 | 534 |
} |