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