Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethod.cpp @ 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 | 18fb7da42534 |
children | bb33c6fdcf0d |
rev | line source |
---|---|
0 | 1 /* |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
2 * Copyright (c) 1999, 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:
1251
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1251
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:
1251
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/ciCallProfile.hpp" | |
27 #include "ci/ciExceptionHandler.hpp" | |
28 #include "ci/ciInstanceKlass.hpp" | |
29 #include "ci/ciMethod.hpp" | |
30 #include "ci/ciMethodBlocks.hpp" | |
31 #include "ci/ciMethodData.hpp" | |
32 #include "ci/ciStreams.hpp" | |
33 #include "ci/ciSymbol.hpp" | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
34 #include "ci/ciReplay.hpp" |
1972 | 35 #include "ci/ciUtilities.hpp" |
36 #include "classfile/systemDictionary.hpp" | |
37 #include "compiler/abstractCompiler.hpp" | |
38 #include "compiler/compilerOracle.hpp" | |
39 #include "compiler/methodLiveness.hpp" | |
40 #include "interpreter/interpreter.hpp" | |
41 #include "interpreter/linkResolver.hpp" | |
42 #include "interpreter/oopMapCache.hpp" | |
43 #include "memory/allocation.inline.hpp" | |
44 #include "memory/resourceArea.hpp" | |
45 #include "oops/generateOopMap.hpp" | |
46 #include "oops/oop.inline.hpp" | |
47 #include "prims/nativeLookup.hpp" | |
48 #include "runtime/deoptimization.hpp" | |
49 #include "utilities/bitMap.inline.hpp" | |
50 #include "utilities/xmlstream.hpp" | |
51 #ifdef COMPILER2 | |
52 #include "ci/bcEscapeAnalyzer.hpp" | |
53 #include "ci/ciTypeFlow.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
54 #include "oops/method.hpp" |
1972 | 55 #endif |
56 #ifdef SHARK | |
57 #include "ci/ciTypeFlow.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
58 #include "oops/method.hpp" |
1972 | 59 #endif |
0 | 60 |
61 // ciMethod | |
62 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
63 // This class represents a Method* in the HotSpot virtual |
0 | 64 // machine. |
65 | |
66 | |
67 // ------------------------------------------------------------------ | |
68 // ciMethod::ciMethod | |
69 // | |
70 // Loaded method. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
71 ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { |
0 | 72 assert(h_m() != NULL, "no null method"); |
73 | |
74 // These fields are always filled in in loaded methods. | |
75 _flags = ciFlags(h_m()->access_flags()); | |
76 | |
77 // Easy to compute, so fill them in now. | |
78 _max_stack = h_m()->max_stack(); | |
79 _max_locals = h_m()->max_locals(); | |
80 _code_size = h_m()->code_size(); | |
81 _intrinsic_id = h_m()->intrinsic_id(); | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
82 _handler_count = h_m()->exception_table_length(); |
0 | 83 _uses_monitors = h_m()->access_flags().has_monitor_bytecodes(); |
84 _balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching(); | |
1783 | 85 _is_c1_compilable = !h_m()->is_not_c1_compilable(); |
86 _is_c2_compilable = !h_m()->is_not_c2_compilable(); | |
0 | 87 // Lazy fields, filled in on demand. Require allocation. |
88 _code = NULL; | |
89 _exception_handlers = NULL; | |
90 _liveness = NULL; | |
91 _method_blocks = NULL; | |
1692 | 92 #if defined(COMPILER2) || defined(SHARK) |
0 | 93 _flow = NULL; |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
94 _bcea = NULL; |
1692 | 95 #endif // COMPILER2 || SHARK |
0 | 96 |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
710
diff
changeset
|
97 ciEnv *env = CURRENT_ENV; |
1783 | 98 if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) { |
0 | 99 // 6328518 check hotswap conditions under the right lock. |
100 MutexLocker locker(Compile_lock); | |
101 if (Dependencies::check_evol_method(h_m()) != NULL) { | |
1783 | 102 _is_c1_compilable = false; |
103 _is_c2_compilable = false; | |
0 | 104 } |
105 } else { | |
106 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); | |
107 } | |
108 | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
109 if (h_m()->method_holder()->is_linked()) { |
0 | 110 _can_be_statically_bound = h_m()->can_be_statically_bound(); |
111 } else { | |
112 // Have to use a conservative value in this case. | |
113 _can_be_statically_bound = false; | |
114 } | |
115 | |
116 // Adjust the definition of this condition to be more useful: | |
117 // %%% take these conditions into account in vtable generation | |
118 if (!_can_be_statically_bound && h_m()->is_private()) | |
119 _can_be_statically_bound = true; | |
120 if (_can_be_statically_bound && h_m()->is_abstract()) | |
121 _can_be_statically_bound = false; | |
122 | |
123 // generating _signature may allow GC and therefore move m. | |
124 // These fields are always filled in. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2007
diff
changeset
|
125 _name = env->get_symbol(h_m()->name()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
126 _holder = env->get_instance_klass(h_m()->method_holder()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2007
diff
changeset
|
127 ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
2357
diff
changeset
|
128 constantPoolHandle cpool = h_m()->constants(); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
2357
diff
changeset
|
129 _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); |
0 | 130 _method_data = NULL; |
131 // Take a snapshot of these values, so they will be commensurate with the MDO. | |
1783 | 132 if (ProfileInterpreter || TieredCompilation) { |
0 | 133 int invcnt = h_m()->interpreter_invocation_count(); |
134 // if the value overflowed report it as max int | |
135 _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ; | |
136 _interpreter_throwout_count = h_m()->interpreter_throwout_count(); | |
137 } else { | |
138 _interpreter_invocation_count = 0; | |
139 _interpreter_throwout_count = 0; | |
140 } | |
141 if (_interpreter_invocation_count == 0) | |
142 _interpreter_invocation_count = 1; | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
143 _instructions_size = -1; |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
144 #ifdef ASSERT |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
145 if (ReplayCompiles) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
146 ciReplay::initialize(this); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
147 } |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
148 #endif |
0 | 149 } |
150 | |
151 | |
152 // ------------------------------------------------------------------ | |
153 // ciMethod::ciMethod | |
154 // | |
155 // Unloaded method. | |
156 ciMethod::ciMethod(ciInstanceKlass* holder, | |
4001
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
157 ciSymbol* name, |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
158 ciSymbol* signature, |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
159 ciInstanceKlass* accessor) : |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
160 ciMetadata((Metadata*)NULL), |
4001
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
161 _name( name), |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
162 _holder( holder), |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
163 _intrinsic_id( vmIntrinsics::_none), |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
164 _liveness( NULL), |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
165 _can_be_statically_bound(false), |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
166 _method_blocks( NULL), |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
167 _method_data( NULL) |
1692 | 168 #if defined(COMPILER2) || defined(SHARK) |
4001
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
169 , |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
170 _flow( NULL), |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
171 _bcea( NULL), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
172 _instructions_size(-1) |
1692 | 173 #endif // COMPILER2 || SHARK |
4001
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
174 { |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
175 // Usually holder and accessor are the same type but in some cases |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
176 // the holder has the wrong class loader (e.g. invokedynamic call |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
177 // sites) so we pass the accessor. |
5eb9169b1a14
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
twisti
parents:
3897
diff
changeset
|
178 _signature = new (CURRENT_ENV->arena()) ciSignature(accessor, constantPoolHandle(), signature); |
0 | 179 } |
180 | |
181 | |
182 // ------------------------------------------------------------------ | |
183 // ciMethod::load_code | |
184 // | |
185 // Load the bytecodes and exception handler table for this method. | |
186 void ciMethod::load_code() { | |
187 VM_ENTRY_MARK; | |
188 assert(is_loaded(), "only loaded methods have code"); | |
189 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
190 Method* me = get_Method(); |
0 | 191 Arena* arena = CURRENT_THREAD_ENV->arena(); |
192 | |
193 // Load the bytecodes. | |
194 _code = (address)arena->Amalloc(code_size()); | |
195 memcpy(_code, me->code_base(), code_size()); | |
196 | |
197 // Revert any breakpoint bytecodes in ci's copy | |
27
1f530c629c7d
6498878: client compiler crashes on windows when dealing with breakpoint instructions
kvn
parents:
0
diff
changeset
|
198 if (me->number_of_breakpoints() > 0) { |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
199 BreakpointInfo* bp = me->method_holder()->breakpoints(); |
0 | 200 for (; bp != NULL; bp = bp->next()) { |
201 if (bp->match(me)) { | |
202 code_at_put(bp->bci(), bp->orig_bytecode()); | |
203 } | |
204 } | |
205 } | |
206 | |
207 // And load the exception table. | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
208 ExceptionTable exc_table(me); |
0 | 209 |
210 // Allocate one extra spot in our list of exceptions. This | |
211 // last entry will be used to represent the possibility that | |
212 // an exception escapes the method. See ciExceptionHandlerStream | |
213 // for details. | |
214 _exception_handlers = | |
215 (ciExceptionHandler**)arena->Amalloc(sizeof(ciExceptionHandler*) | |
216 * (_handler_count + 1)); | |
217 if (_handler_count > 0) { | |
218 for (int i=0; i<_handler_count; i++) { | |
219 _exception_handlers[i] = new (arena) ciExceptionHandler( | |
220 holder(), | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
221 /* start */ exc_table.start_pc(i), |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
222 /* limit */ exc_table.end_pc(i), |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
223 /* goto pc */ exc_table.handler_pc(i), |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
4001
diff
changeset
|
224 /* cp index */ exc_table.catch_type_index(i)); |
0 | 225 } |
226 } | |
227 | |
228 // Put an entry at the end of our list to represent the possibility | |
229 // of exceptional exit. | |
230 _exception_handlers[_handler_count] = | |
231 new (arena) ciExceptionHandler(holder(), 0, code_size(), -1, 0); | |
232 | |
233 if (CIPrintMethodCodes) { | |
234 print_codes(); | |
235 } | |
236 } | |
237 | |
238 | |
239 // ------------------------------------------------------------------ | |
240 // ciMethod::has_linenumber_table | |
241 // | |
242 // length unknown until decompression | |
243 bool ciMethod::has_linenumber_table() const { | |
244 check_is_loaded(); | |
245 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
246 return get_Method()->has_linenumber_table(); |
0 | 247 } |
248 | |
249 | |
250 // ------------------------------------------------------------------ | |
251 // ciMethod::compressed_linenumber_table | |
252 u_char* ciMethod::compressed_linenumber_table() const { | |
253 check_is_loaded(); | |
254 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
255 return get_Method()->compressed_linenumber_table(); |
0 | 256 } |
257 | |
258 | |
259 // ------------------------------------------------------------------ | |
260 // ciMethod::line_number_from_bci | |
261 int ciMethod::line_number_from_bci(int bci) const { | |
262 check_is_loaded(); | |
263 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
264 return get_Method()->line_number_from_bci(bci); |
0 | 265 } |
266 | |
267 | |
268 // ------------------------------------------------------------------ | |
269 // ciMethod::vtable_index | |
270 // | |
271 // Get the position of this method's entry in the vtable, if any. | |
272 int ciMethod::vtable_index() { | |
273 check_is_loaded(); | |
274 assert(holder()->is_linked(), "must be linked"); | |
275 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
276 return get_Method()->vtable_index(); |
0 | 277 } |
278 | |
279 | |
1692 | 280 #ifdef SHARK |
281 // ------------------------------------------------------------------ | |
282 // ciMethod::itable_index | |
283 // | |
284 // Get the position of this method's entry in the itable, if any. | |
285 int ciMethod::itable_index() { | |
286 check_is_loaded(); | |
287 assert(holder()->is_linked(), "must be linked"); | |
288 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
289 return klassItable::compute_itable_index(get_Method()); |
1692 | 290 } |
291 #endif // SHARK | |
292 | |
293 | |
0 | 294 // ------------------------------------------------------------------ |
295 // ciMethod::native_entry | |
296 // | |
297 // Get the address of this method's native code, if any. | |
298 address ciMethod::native_entry() { | |
299 check_is_loaded(); | |
300 assert(flags().is_native(), "must be native method"); | |
301 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
302 Method* method = get_Method(); |
0 | 303 address entry = method->native_function(); |
304 assert(entry != NULL, "must be valid entry point"); | |
305 return entry; | |
306 } | |
307 | |
308 | |
309 // ------------------------------------------------------------------ | |
310 // ciMethod::interpreter_entry | |
311 // | |
312 // Get the entry point for running this method in the interpreter. | |
313 address ciMethod::interpreter_entry() { | |
314 check_is_loaded(); | |
315 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
316 methodHandle mh(THREAD, get_Method()); |
0 | 317 return Interpreter::entry_for_method(mh); |
318 } | |
319 | |
320 | |
321 // ------------------------------------------------------------------ | |
322 // ciMethod::uses_balanced_monitors | |
323 // | |
324 // Does this method use monitors in a strict stack-disciplined manner? | |
325 bool ciMethod::has_balanced_monitors() { | |
326 check_is_loaded(); | |
327 if (_balanced_monitors) return true; | |
328 | |
329 // Analyze the method to see if monitors are used properly. | |
330 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
331 methodHandle method(THREAD, get_Method()); |
0 | 332 assert(method->has_monitor_bytecodes(), "should have checked this"); |
333 | |
334 // Check to see if a previous compilation computed the | |
335 // monitor-matching analysis. | |
336 if (method->guaranteed_monitor_matching()) { | |
337 _balanced_monitors = true; | |
338 return true; | |
339 } | |
340 | |
341 { | |
342 EXCEPTION_MARK; | |
343 ResourceMark rm(THREAD); | |
344 GeneratePairingInfo gpi(method); | |
345 gpi.compute_map(CATCH); | |
346 if (!gpi.monitor_safe()) { | |
347 return false; | |
348 } | |
349 method->set_guaranteed_monitor_matching(); | |
350 _balanced_monitors = true; | |
351 } | |
352 return true; | |
353 } | |
354 | |
355 | |
356 // ------------------------------------------------------------------ | |
357 // ciMethod::get_flow_analysis | |
358 ciTypeFlow* ciMethod::get_flow_analysis() { | |
1692 | 359 #if defined(COMPILER2) || defined(SHARK) |
0 | 360 if (_flow == NULL) { |
361 ciEnv* env = CURRENT_ENV; | |
362 _flow = new (env->arena()) ciTypeFlow(env, this); | |
363 _flow->do_flow(); | |
364 } | |
365 return _flow; | |
1692 | 366 #else // COMPILER2 || SHARK |
0 | 367 ShouldNotReachHere(); |
368 return NULL; | |
1692 | 369 #endif // COMPILER2 || SHARK |
0 | 370 } |
371 | |
372 | |
373 // ------------------------------------------------------------------ | |
374 // ciMethod::get_osr_flow_analysis | |
375 ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) { | |
1692 | 376 #if defined(COMPILER2) || defined(SHARK) |
0 | 377 // OSR entry points are always place after a call bytecode of some sort |
378 assert(osr_bci >= 0, "must supply valid OSR entry point"); | |
379 ciEnv* env = CURRENT_ENV; | |
380 ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci); | |
381 flow->do_flow(); | |
382 return flow; | |
1692 | 383 #else // COMPILER2 || SHARK |
0 | 384 ShouldNotReachHere(); |
385 return NULL; | |
1692 | 386 #endif // COMPILER2 || SHARK |
0 | 387 } |
388 | |
389 // ------------------------------------------------------------------ | |
991 | 390 // ciMethod::raw_liveness_at_bci |
0 | 391 // |
392 // Which local variables are live at a specific bci? | |
991 | 393 MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) { |
0 | 394 check_is_loaded(); |
395 if (_liveness == NULL) { | |
396 // Create the liveness analyzer. | |
397 Arena* arena = CURRENT_ENV->arena(); | |
398 _liveness = new (arena) MethodLiveness(arena, this); | |
399 _liveness->compute_liveness(); | |
400 } | |
991 | 401 return _liveness->get_liveness_at(bci); |
402 } | |
403 | |
404 // ------------------------------------------------------------------ | |
405 // ciMethod::liveness_at_bci | |
406 // | |
407 // Which local variables are live at a specific bci? When debugging | |
408 // will return true for all locals in some cases to improve debug | |
409 // information. | |
410 MethodLivenessResult ciMethod::liveness_at_bci(int bci) { | |
411 MethodLivenessResult result = raw_liveness_at_bci(bci); | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
710
diff
changeset
|
412 if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { |
0 | 413 // Keep all locals live for the user's edification and amusement. |
414 result.at_put_range(0, result.size(), true); | |
415 } | |
416 return result; | |
417 } | |
418 | |
419 // ciMethod::live_local_oops_at_bci | |
420 // | |
421 // find all the live oops in the locals array for a particular bci | |
422 // Compute what the interpreter believes by using the interpreter | |
423 // oopmap generator. This is used as a double check during osr to | |
424 // guard against conservative result from MethodLiveness making us | |
425 // think a dead oop is live. MethodLiveness is conservative in the | |
426 // sense that it may consider locals to be live which cannot be live, | |
427 // like in the case where a local could contain an oop or a primitive | |
428 // along different paths. In that case the local must be dead when | |
429 // those paths merge. Since the interpreter's viewpoint is used when | |
430 // gc'ing an interpreter frame we need to use its viewpoint during | |
431 // OSR when loading the locals. | |
432 | |
433 BitMap ciMethod::live_local_oops_at_bci(int bci) { | |
434 VM_ENTRY_MARK; | |
435 InterpreterOopMap mask; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
436 OopMapCache::compute_one_oop_map(get_Method(), bci, &mask); |
0 | 437 int mask_size = max_locals(); |
438 BitMap result(mask_size); | |
439 result.clear(); | |
440 int i; | |
441 for (i = 0; i < mask_size ; i++ ) { | |
442 if (mask.is_oop(i)) result.set_bit(i); | |
443 } | |
444 return result; | |
445 } | |
446 | |
447 | |
448 #ifdef COMPILER1 | |
449 // ------------------------------------------------------------------ | |
450 // ciMethod::bci_block_start | |
451 // | |
452 // Marks all bcis where a new basic block starts | |
453 const BitMap ciMethod::bci_block_start() { | |
454 check_is_loaded(); | |
455 if (_liveness == NULL) { | |
456 // Create the liveness analyzer. | |
457 Arena* arena = CURRENT_ENV->arena(); | |
458 _liveness = new (arena) MethodLiveness(arena, this); | |
459 _liveness->compute_liveness(); | |
460 } | |
461 | |
462 return _liveness->get_bci_block_start(); | |
463 } | |
464 #endif // COMPILER1 | |
465 | |
466 | |
467 // ------------------------------------------------------------------ | |
468 // ciMethod::call_profile_at_bci | |
469 // | |
470 // Get the ciCallProfile for the invocation of this method. | |
471 // Also reports receiver types for non-call type checks (if TypeProfileCasts). | |
472 ciCallProfile ciMethod::call_profile_at_bci(int bci) { | |
473 ResourceMark rm; | |
474 ciCallProfile result; | |
475 if (method_data() != NULL && method_data()->is_mature()) { | |
476 ciProfileData* data = method_data()->bci_to_data(bci); | |
477 if (data != NULL && data->is_CounterData()) { | |
478 // Every profiled call site has a counter. | |
479 int count = data->as_CounterData()->count(); | |
480 | |
481 if (!data->is_ReceiverTypeData()) { | |
482 result._receiver_count[0] = 0; // that's a definite zero | |
483 } else { // ReceiverTypeData is a subclass of CounterData | |
484 ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData(); | |
485 // In addition, virtual call sites have receiver type information | |
486 int receivers_count_total = 0; | |
487 int morphism = 0; | |
1783 | 488 // Precompute morphism for the possible fixup |
0 | 489 for (uint i = 0; i < call->row_limit(); i++) { |
490 ciKlass* receiver = call->receiver(i); | |
491 if (receiver == NULL) continue; | |
1783 | 492 morphism++; |
493 } | |
494 int epsilon = 0; | |
495 if (TieredCompilation && ProfileInterpreter) { | |
496 // Interpreter and C1 treat final and special invokes differently. | |
497 // C1 will record a type, whereas the interpreter will just | |
498 // increment the count. Detect this case. | |
499 if (morphism == 1 && count > 0) { | |
500 epsilon = count; | |
501 count = 0; | |
502 } | |
503 } | |
504 for (uint i = 0; i < call->row_limit(); i++) { | |
505 ciKlass* receiver = call->receiver(i); | |
506 if (receiver == NULL) continue; | |
507 int rcount = call->receiver_count(i) + epsilon; | |
0 | 508 if (rcount == 0) rcount = 1; // Should be valid value |
509 receivers_count_total += rcount; | |
510 // Add the receiver to result data. | |
511 result.add_receiver(receiver, rcount); | |
512 // If we extend profiling to record methods, | |
513 // we will set result._method also. | |
514 } | |
515 // Determine call site's morphism. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
516 // The call site count is 0 with known morphism (onlt 1 or 2 receivers) |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
517 // or < 0 in the case of a type check failured for checkcast, aastore, instanceof. |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
518 // The call site count is > 0 in the case of a polymorphic virtual call. |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
519 if (morphism > 0 && morphism == result._limit) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
520 // The morphism <= MorphismLimit. |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
521 if ((morphism < ciCallProfile::MorphismLimit) || |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
522 (morphism == ciCallProfile::MorphismLimit && count == 0)) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
523 #ifdef ASSERT |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
524 if (count > 0) { |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1206
diff
changeset
|
525 this->print_short_name(tty); |
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1206
diff
changeset
|
526 tty->print_cr(" @ bci:%d", bci); |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
527 this->print_codes(); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
528 assert(false, "this call site should not be polymorphic"); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
529 } |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
530 #endif |
0 | 531 result._morphism = morphism; |
532 } | |
533 } | |
534 // Make the count consistent if this is a call profile. If count is | |
535 // zero or less, presume that this is a typecheck profile and | |
536 // do nothing. Otherwise, increase count to be the sum of all | |
537 // receiver's counts. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
538 if (count >= 0) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
539 count += receivers_count_total; |
0 | 540 } |
541 } | |
542 result._count = count; | |
543 } | |
544 } | |
545 return result; | |
546 } | |
547 | |
548 // ------------------------------------------------------------------ | |
549 // Add new receiver and sort data by receiver's profile count. | |
550 void ciCallProfile::add_receiver(ciKlass* receiver, int receiver_count) { | |
551 // Add new receiver and sort data by receiver's counts when we have space | |
552 // for it otherwise replace the less called receiver (less called receiver | |
553 // is placed to the last array element which is not used). | |
554 // First array's element contains most called receiver. | |
555 int i = _limit; | |
556 for (; i > 0 && receiver_count > _receiver_count[i-1]; i--) { | |
557 _receiver[i] = _receiver[i-1]; | |
558 _receiver_count[i] = _receiver_count[i-1]; | |
559 } | |
560 _receiver[i] = receiver; | |
561 _receiver_count[i] = receiver_count; | |
562 if (_limit < MorphismLimit) _limit++; | |
563 } | |
564 | |
565 // ------------------------------------------------------------------ | |
566 // ciMethod::find_monomorphic_target | |
567 // | |
568 // Given a certain calling environment, find the monomorphic target | |
569 // for the call. Return NULL if the call is not monomorphic in | |
570 // its calling environment, or if there are only abstract methods. | |
571 // The returned method is never abstract. | |
572 // Note: If caller uses a non-null result, it must inform dependencies | |
573 // via assert_unique_concrete_method or assert_leaf_type. | |
574 ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller, | |
575 ciInstanceKlass* callee_holder, | |
576 ciInstanceKlass* actual_recv) { | |
577 check_is_loaded(); | |
578 | |
579 if (actual_recv->is_interface()) { | |
580 // %%% We cannot trust interface types, yet. See bug 6312651. | |
581 return NULL; | |
582 } | |
583 | |
584 ciMethod* root_m = resolve_invoke(caller, actual_recv); | |
585 if (root_m == NULL) { | |
586 // Something went wrong looking up the actual receiver method. | |
587 return NULL; | |
588 } | |
589 assert(!root_m->is_abstract(), "resolve_invoke promise"); | |
590 | |
591 // Make certain quick checks even if UseCHA is false. | |
592 | |
593 // Is it private or final? | |
594 if (root_m->can_be_statically_bound()) { | |
595 return root_m; | |
596 } | |
597 | |
598 if (actual_recv->is_leaf_type() && actual_recv == root_m->holder()) { | |
599 // Easy case. There is no other place to put a method, so don't bother | |
600 // to go through the VM_ENTRY_MARK and all the rest. | |
601 return root_m; | |
602 } | |
603 | |
604 // Array methods (clone, hashCode, etc.) are always statically bound. | |
605 // If we were to see an array type here, we'd return root_m. | |
606 // However, this method processes only ciInstanceKlasses. (See 4962591.) | |
607 // The inline_native_clone intrinsic narrows Object to T[] properly, | |
608 // so there is no need to do the same job here. | |
609 | |
610 if (!UseCHA) return NULL; | |
611 | |
612 VM_ENTRY_MARK; | |
613 | |
614 methodHandle target; | |
615 { | |
616 MutexLocker locker(Compile_lock); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
617 Klass* context = actual_recv->get_Klass(); |
0 | 618 target = Dependencies::find_unique_concrete_method(context, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
619 root_m->get_Method()); |
0 | 620 // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods. |
621 } | |
622 | |
623 #ifndef PRODUCT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
624 if (TraceDependencies && target() != NULL && target() != root_m->get_Method()) { |
0 | 625 tty->print("found a non-root unique target method"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
626 tty->print_cr(" context = %s", InstanceKlass::cast(actual_recv->get_Klass())->external_name()); |
0 | 627 tty->print(" method = "); |
628 target->print_short_name(tty); | |
629 tty->cr(); | |
630 } | |
631 #endif //PRODUCT | |
632 | |
633 if (target() == NULL) { | |
634 return NULL; | |
635 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
636 if (target() == root_m->get_Method()) { |
0 | 637 return root_m; |
638 } | |
639 if (!root_m->is_public() && | |
640 !root_m->is_protected()) { | |
641 // If we are going to reason about inheritance, it's easiest | |
642 // if the method in question is public, protected, or private. | |
643 // If the answer is not root_m, it is conservatively correct | |
644 // to return NULL, even if the CHA encountered irrelevant | |
645 // methods in other packages. | |
646 // %%% TO DO: Work out logic for package-private methods | |
647 // with the same name but different vtable indexes. | |
648 return NULL; | |
649 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
650 return CURRENT_THREAD_ENV->get_method(target()); |
0 | 651 } |
652 | |
653 // ------------------------------------------------------------------ | |
654 // ciMethod::resolve_invoke | |
655 // | |
656 // Given a known receiver klass, find the target for the call. | |
657 // Return NULL if the call has no target or the target is abstract. | |
658 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) { | |
659 check_is_loaded(); | |
660 VM_ENTRY_MARK; | |
661 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
662 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
663 KlassHandle h_recv (THREAD, exact_receiver->get_Klass()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
664 KlassHandle h_resolved (THREAD, holder()->get_Klass()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2007
diff
changeset
|
665 Symbol* h_name = name()->get_symbol(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2007
diff
changeset
|
666 Symbol* h_signature = signature()->get_symbol(); |
0 | 667 |
668 methodHandle m; | |
669 // Only do exact lookup if receiver klass has been linked. Otherwise, | |
670 // the vtable has not been setup, and the LinkResolver will fail. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
671 if (h_recv->oop_is_array() |
0 | 672 || |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
673 InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { |
0 | 674 if (holder()->is_interface()) { |
675 m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); | |
676 } else { | |
677 m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); | |
678 } | |
679 } | |
680 | |
681 if (m.is_null()) { | |
682 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) | |
683 return NULL; | |
684 } | |
685 | |
686 ciMethod* result = this; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
687 if (m() != get_Method()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
688 result = CURRENT_THREAD_ENV->get_method(m()); |
0 | 689 } |
690 | |
691 // Don't return abstract methods because they aren't | |
692 // optimizable or interesting. | |
693 if (result->is_abstract()) { | |
694 return NULL; | |
695 } else { | |
696 return result; | |
697 } | |
698 } | |
699 | |
700 // ------------------------------------------------------------------ | |
701 // ciMethod::resolve_vtable_index | |
702 // | |
703 // Given a known receiver klass, find the vtable index for the call. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
704 // Return Method::invalid_vtable_index if the vtable_index is unknown. |
0 | 705 int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) { |
706 check_is_loaded(); | |
707 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
708 int vtable_index = Method::invalid_vtable_index; |
0 | 709 // Only do lookup if receiver klass has been linked. Otherwise, |
710 // the vtable has not been setup, and the LinkResolver will fail. | |
711 if (!receiver->is_interface() | |
712 && (!receiver->is_instance_klass() || | |
713 receiver->as_instance_klass()->is_linked())) { | |
714 VM_ENTRY_MARK; | |
715 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
716 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
717 KlassHandle h_recv (THREAD, receiver->get_Klass()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2007
diff
changeset
|
718 Symbol* h_name = name()->get_symbol(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2007
diff
changeset
|
719 Symbol* h_signature = signature()->get_symbol(); |
0 | 720 |
721 vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
722 if (vtable_index == Method::nonvirtual_vtable_index) { |
0 | 723 // A statically bound method. Return "no such index". |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
724 vtable_index = Method::invalid_vtable_index; |
0 | 725 } |
726 } | |
727 | |
728 return vtable_index; | |
729 } | |
730 | |
731 // ------------------------------------------------------------------ | |
732 // ciMethod::interpreter_call_site_count | |
733 int ciMethod::interpreter_call_site_count(int bci) { | |
734 if (method_data() != NULL) { | |
735 ResourceMark rm; | |
736 ciProfileData* data = method_data()->bci_to_data(bci); | |
737 if (data != NULL && data->is_CounterData()) { | |
738 return scale_count(data->as_CounterData()->count()); | |
739 } | |
740 } | |
741 return -1; // unknown | |
742 } | |
743 | |
744 // ------------------------------------------------------------------ | |
745 // Adjust a CounterData count to be commensurate with | |
746 // interpreter_invocation_count. If the MDO exists for | |
747 // only 25% of the time the method exists, then the | |
748 // counts in the MDO should be scaled by 4X, so that | |
749 // they can be usefully and stably compared against the | |
750 // invocation counts in methods. | |
751 int ciMethod::scale_count(int count, float prof_factor) { | |
752 if (count > 0 && method_data() != NULL) { | |
1783 | 753 int counter_life; |
0 | 754 int method_life = interpreter_invocation_count(); |
1783 | 755 if (TieredCompilation) { |
756 // In tiered the MDO's life is measured directly, so just use the snapshotted counters | |
757 counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count()); | |
758 } else { | |
759 int current_mileage = method_data()->current_mileage(); | |
760 int creation_mileage = method_data()->creation_mileage(); | |
761 counter_life = current_mileage - creation_mileage; | |
762 } | |
763 | |
0 | 764 // counter_life due to backedge_counter could be > method_life |
765 if (counter_life > method_life) | |
766 counter_life = method_life; | |
767 if (0 < counter_life && counter_life <= method_life) { | |
768 count = (int)((double)count * prof_factor * method_life / counter_life + 0.5); | |
769 count = (count > 0) ? count : 1; | |
770 } | |
771 } | |
772 return count; | |
773 } | |
774 | |
775 // ------------------------------------------------------------------ | |
710 | 776 // invokedynamic support |
1564 | 777 |
778 // ------------------------------------------------------------------ | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
779 // ciMethod::is_method_handle_intrinsic |
710 | 780 // |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
781 // Return true if the method is an instance of the JVM-generated |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
782 // signature-polymorphic MethodHandle methods, _invokeBasic, _linkToVirtual, etc. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
783 bool ciMethod::is_method_handle_intrinsic() const { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
784 vmIntrinsics::ID iid = _intrinsic_id; // do not check if loaded |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
785 return (MethodHandles::is_signature_polymorphic(iid) && |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
786 MethodHandles::is_signature_polymorphic_intrinsic(iid)); |
710 | 787 } |
788 | |
1564 | 789 // ------------------------------------------------------------------ |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
790 // ciMethod::is_compiled_lambda_form |
1564 | 791 // |
792 // Return true if the method is a generated MethodHandle adapter. | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
793 // These are built by Java code. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
794 bool ciMethod::is_compiled_lambda_form() const { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
795 vmIntrinsics::ID iid = _intrinsic_id; // do not check if loaded |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
796 return iid == vmIntrinsics::_compiledLambdaForm; |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
797 } |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
798 |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
799 // ------------------------------------------------------------------ |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
800 // ciMethod::has_member_arg |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
801 // |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
802 // Return true if the method is a linker intrinsic like _linkToVirtual. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
803 // These are built by the JVM. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
804 bool ciMethod::has_member_arg() const { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
805 vmIntrinsics::ID iid = _intrinsic_id; // do not check if loaded |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
806 return (MethodHandles::is_signature_polymorphic(iid) && |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
807 MethodHandles::has_member_arg(iid)); |
710 | 808 } |
809 | |
810 // ------------------------------------------------------------------ | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
811 // ciMethod::ensure_method_data |
0 | 812 // |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
813 // Generate new MethodData* objects at compile time. |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
814 // Return true if allocation was successful or no MDO is required. |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
815 bool ciMethod::ensure_method_data(methodHandle h_m) { |
0 | 816 EXCEPTION_CONTEXT; |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
817 if (is_native() || is_abstract() || h_m()->is_accessor()) return true; |
0 | 818 if (h_m()->method_data() == NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
819 Method::build_interpreter_method_data(h_m, THREAD); |
0 | 820 if (HAS_PENDING_EXCEPTION) { |
821 CLEAR_PENDING_EXCEPTION; | |
822 } | |
823 } | |
824 if (h_m()->method_data() != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
825 _method_data = CURRENT_ENV->get_method_data(h_m()->method_data()); |
0 | 826 _method_data->load_data(); |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
827 return true; |
0 | 828 } else { |
829 _method_data = CURRENT_ENV->get_empty_methodData(); | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
830 return false; |
0 | 831 } |
832 } | |
833 | |
834 // public, retroactive version | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
835 bool ciMethod::ensure_method_data() { |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
836 bool result = true; |
0 | 837 if (_method_data == NULL || _method_data->is_empty()) { |
838 GUARDED_VM_ENTRY({ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
839 result = ensure_method_data(get_Method()); |
0 | 840 }); |
841 } | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
842 return result; |
0 | 843 } |
844 | |
845 | |
846 // ------------------------------------------------------------------ | |
847 // ciMethod::method_data | |
848 // | |
849 ciMethodData* ciMethod::method_data() { | |
850 if (_method_data != NULL) { | |
851 return _method_data; | |
852 } | |
853 VM_ENTRY_MARK; | |
854 ciEnv* env = CURRENT_ENV; | |
855 Thread* my_thread = JavaThread::current(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
856 methodHandle h_m(my_thread, get_Method()); |
0 | 857 |
858 if (h_m()->method_data() != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
859 _method_data = CURRENT_ENV->get_method_data(h_m()->method_data()); |
0 | 860 _method_data->load_data(); |
861 } else { | |
862 _method_data = CURRENT_ENV->get_empty_methodData(); | |
863 } | |
864 return _method_data; | |
865 | |
866 } | |
867 | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
868 // ------------------------------------------------------------------ |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
869 // ciMethod::method_data_or_null |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
870 // Returns a pointer to ciMethodData if MDO exists on the VM side, |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
871 // NULL otherwise. |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
872 ciMethodData* ciMethod::method_data_or_null() { |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
873 ciMethodData *md = method_data(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
874 if (md->is_empty()) return NULL; |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
875 return md; |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
876 } |
0 | 877 |
878 // ------------------------------------------------------------------ | |
879 // ciMethod::will_link | |
880 // | |
881 // Will this method link in a specific calling context? | |
882 bool ciMethod::will_link(ciKlass* accessing_klass, | |
883 ciKlass* declared_method_holder, | |
884 Bytecodes::Code bc) { | |
885 if (!is_loaded()) { | |
886 // Method lookup failed. | |
887 return false; | |
888 } | |
889 | |
890 // The link checks have been front-loaded into the get_method | |
891 // call. This method (ciMethod::will_link()) will be removed | |
892 // in the future. | |
893 | |
894 return true; | |
895 } | |
896 | |
897 // ------------------------------------------------------------------ | |
898 // ciMethod::should_exclude | |
899 // | |
900 // Should this method be excluded from compilation? | |
901 bool ciMethod::should_exclude() { | |
902 check_is_loaded(); | |
903 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
904 methodHandle mh(THREAD, get_Method()); |
0 | 905 bool ignore; |
906 return CompilerOracle::should_exclude(mh, ignore); | |
907 } | |
908 | |
909 // ------------------------------------------------------------------ | |
910 // ciMethod::should_inline | |
911 // | |
912 // Should this method be inlined during compilation? | |
913 bool ciMethod::should_inline() { | |
914 check_is_loaded(); | |
915 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
916 methodHandle mh(THREAD, get_Method()); |
0 | 917 return CompilerOracle::should_inline(mh); |
918 } | |
919 | |
920 // ------------------------------------------------------------------ | |
921 // ciMethod::should_not_inline | |
922 // | |
923 // Should this method be disallowed from inlining during compilation? | |
924 bool ciMethod::should_not_inline() { | |
925 check_is_loaded(); | |
926 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
927 methodHandle mh(THREAD, get_Method()); |
0 | 928 return CompilerOracle::should_not_inline(mh); |
929 } | |
930 | |
931 // ------------------------------------------------------------------ | |
932 // ciMethod::should_print_assembly | |
933 // | |
934 // Should the compiler print the generated code for this method? | |
935 bool ciMethod::should_print_assembly() { | |
936 check_is_loaded(); | |
937 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
938 methodHandle mh(THREAD, get_Method()); |
0 | 939 return CompilerOracle::should_print(mh); |
940 } | |
941 | |
942 // ------------------------------------------------------------------ | |
943 // ciMethod::break_at_execute | |
944 // | |
945 // Should the compiler insert a breakpoint into the generated code | |
946 // method? | |
947 bool ciMethod::break_at_execute() { | |
948 check_is_loaded(); | |
949 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
950 methodHandle mh(THREAD, get_Method()); |
0 | 951 return CompilerOracle::should_break_at(mh); |
952 } | |
953 | |
954 // ------------------------------------------------------------------ | |
955 // ciMethod::has_option | |
956 // | |
957 bool ciMethod::has_option(const char* option) { | |
958 check_is_loaded(); | |
959 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
960 methodHandle mh(THREAD, get_Method()); |
0 | 961 return CompilerOracle::has_option_string(mh, option); |
962 } | |
963 | |
964 // ------------------------------------------------------------------ | |
965 // ciMethod::can_be_compiled | |
966 // | |
967 // Have previous compilations of this method succeeded? | |
968 bool ciMethod::can_be_compiled() { | |
969 check_is_loaded(); | |
1783 | 970 ciEnv* env = CURRENT_ENV; |
971 if (is_c1_compile(env->comp_level())) { | |
972 return _is_c1_compilable; | |
973 } | |
974 return _is_c2_compilable; | |
0 | 975 } |
976 | |
977 // ------------------------------------------------------------------ | |
978 // ciMethod::set_not_compilable | |
979 // | |
980 // Tell the VM that this method cannot be compiled at all. | |
981 void ciMethod::set_not_compilable() { | |
982 check_is_loaded(); | |
983 VM_ENTRY_MARK; | |
1783 | 984 ciEnv* env = CURRENT_ENV; |
985 if (is_c1_compile(env->comp_level())) { | |
986 _is_c1_compilable = false; | |
987 } else { | |
988 _is_c2_compilable = false; | |
989 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
990 get_Method()->set_not_compilable(env->comp_level()); |
0 | 991 } |
992 | |
993 // ------------------------------------------------------------------ | |
994 // ciMethod::can_be_osr_compiled | |
995 // | |
996 // Have previous compilations of this method succeeded? | |
997 // | |
998 // Implementation note: the VM does not currently keep track | |
999 // of failed OSR compilations per bci. The entry_bci parameter | |
1000 // is currently unused. | |
1001 bool ciMethod::can_be_osr_compiled(int entry_bci) { | |
1002 check_is_loaded(); | |
1003 VM_ENTRY_MARK; | |
1783 | 1004 ciEnv* env = CURRENT_ENV; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1005 return !get_Method()->is_not_osr_compilable(env->comp_level()); |
0 | 1006 } |
1007 | |
1008 // ------------------------------------------------------------------ | |
1009 // ciMethod::has_compiled_code | |
1010 bool ciMethod::has_compiled_code() { | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1011 return instructions_size() > 0; |
0 | 1012 } |
1013 | |
1783 | 1014 int ciMethod::comp_level() { |
1015 check_is_loaded(); | |
1016 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1017 nmethod* nm = get_Method()->code(); |
1783 | 1018 if (nm != NULL) return nm->comp_level(); |
1019 return 0; | |
1020 } | |
1021 | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1022 int ciMethod::highest_osr_comp_level() { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1023 check_is_loaded(); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1024 VM_ENTRY_MARK; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1025 return get_Method()->highest_osr_comp_level(); |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1026 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1027 |
0 | 1028 // ------------------------------------------------------------------ |
3897
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1029 // ciMethod::code_size_for_inlining |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1030 // |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1031 // Code size for inlining decisions. This method returns a code |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1032 // size of 1 for methods which has the ForceInline annotation. |
3897
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1033 int ciMethod::code_size_for_inlining() { |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1034 check_is_loaded(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1035 if (get_Method()->force_inline()) { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1036 return 1; |
3897
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1037 } |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1038 return code_size(); |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1039 } |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1040 |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1041 // ------------------------------------------------------------------ |
0 | 1042 // ciMethod::instructions_size |
1748 | 1043 // |
1044 // This is a rough metric for "fat" methods, compared before inlining | |
1045 // with InlineSmallCode. The CodeBlob::code_size accessor includes | |
1046 // junk like exception handler, stubs, and constant table, which are | |
1047 // not highly relevant to an inlined method. So we use the more | |
1048 // specific accessor nmethod::insts_size. | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1049 int ciMethod::instructions_size() { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1050 if (_instructions_size == -1) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1051 GUARDED_VM_ENTRY( |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1052 nmethod* code = get_Method()->code(); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1053 if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1054 _instructions_size = code->insts_end() - code->verified_entry_point(); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1055 } else { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1056 _instructions_size = 0; |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1057 } |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1058 ); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1059 } |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1060 return _instructions_size; |
0 | 1061 } |
1062 | |
1063 // ------------------------------------------------------------------ | |
1064 // ciMethod::log_nmethod_identity | |
1065 void ciMethod::log_nmethod_identity(xmlStream* log) { | |
1066 GUARDED_VM_ENTRY( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1067 nmethod* code = get_Method()->code(); |
0 | 1068 if (code != NULL) { |
1069 code->log_identity(log); | |
1070 } | |
1071 ) | |
1072 } | |
1073 | |
1074 // ------------------------------------------------------------------ | |
1075 // ciMethod::is_not_reached | |
1076 bool ciMethod::is_not_reached(int bci) { | |
1077 check_is_loaded(); | |
1078 VM_ENTRY_MARK; | |
1079 return Interpreter::is_not_reached( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1080 methodHandle(THREAD, get_Method()), bci); |
0 | 1081 } |
1082 | |
1083 // ------------------------------------------------------------------ | |
1084 // ciMethod::was_never_executed | |
1085 bool ciMethod::was_executed_more_than(int times) { | |
1086 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1087 return get_Method()->was_executed_more_than(times); |
0 | 1088 } |
1089 | |
1090 // ------------------------------------------------------------------ | |
1091 // ciMethod::has_unloaded_classes_in_signature | |
1092 bool ciMethod::has_unloaded_classes_in_signature() { | |
1093 VM_ENTRY_MARK; | |
1094 { | |
1095 EXCEPTION_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1096 methodHandle m(THREAD, get_Method()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1097 bool has_unloaded = Method::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD); |
0 | 1098 if( HAS_PENDING_EXCEPTION ) { |
1099 CLEAR_PENDING_EXCEPTION; | |
1100 return true; // Declare that we may have unloaded classes | |
1101 } | |
1102 return has_unloaded; | |
1103 } | |
1104 } | |
1105 | |
1106 // ------------------------------------------------------------------ | |
1107 // ciMethod::is_klass_loaded | |
1108 bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { | |
1109 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1110 return get_Method()->is_klass_loaded(refinfo_index, must_be_resolved); |
0 | 1111 } |
1112 | |
1113 // ------------------------------------------------------------------ | |
1114 // ciMethod::check_call | |
1115 bool ciMethod::check_call(int refinfo_index, bool is_static) const { | |
1116 VM_ENTRY_MARK; | |
1117 { | |
1118 EXCEPTION_MARK; | |
1119 HandleMark hm(THREAD); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1120 constantPoolHandle pool (THREAD, get_Method()->constants()); |
0 | 1121 methodHandle spec_method; |
1122 KlassHandle spec_klass; | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1123 Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1124 LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD); |
0 | 1125 if (HAS_PENDING_EXCEPTION) { |
1126 CLEAR_PENDING_EXCEPTION; | |
1127 return false; | |
1128 } else { | |
1129 return (spec_method->is_static() == is_static); | |
1130 } | |
1131 } | |
1132 return false; | |
1133 } | |
1134 | |
1135 // ------------------------------------------------------------------ | |
1136 // ciMethod::print_codes | |
1137 // | |
1138 // Print the bytecodes for this method. | |
1139 void ciMethod::print_codes_on(outputStream* st) { | |
1140 check_is_loaded(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1141 GUARDED_VM_ENTRY(get_Method()->print_codes_on(st);) |
0 | 1142 } |
1143 | |
1144 | |
1145 #define FETCH_FLAG_FROM_VM(flag_accessor) { \ | |
1146 check_is_loaded(); \ | |
1147 VM_ENTRY_MARK; \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1148 return get_Method()->flag_accessor(); \ |
0 | 1149 } |
1150 | |
1151 bool ciMethod::is_empty_method() const { FETCH_FLAG_FROM_VM(is_empty_method); } | |
1152 bool ciMethod::is_vanilla_constructor() const { FETCH_FLAG_FROM_VM(is_vanilla_constructor); } | |
1153 bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); } | |
1154 bool ciMethod::has_jsrs () const { FETCH_FLAG_FROM_VM(has_jsrs); } | |
1155 bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); } | |
1156 bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); } | |
1157 | |
1158 BCEscapeAnalyzer *ciMethod::get_bcea() { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1159 #ifdef COMPILER2 |
0 | 1160 if (_bcea == NULL) { |
1161 _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL); | |
1162 } | |
1163 return _bcea; | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1164 #else // COMPILER2 |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1165 ShouldNotReachHere(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1166 return NULL; |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1167 #endif // COMPILER2 |
0 | 1168 } |
1169 | |
1170 ciMethodBlocks *ciMethod::get_method_blocks() { | |
1171 Arena *arena = CURRENT_ENV->arena(); | |
1172 if (_method_blocks == NULL) { | |
1173 _method_blocks = new (arena) ciMethodBlocks(arena, this); | |
1174 } | |
1175 return _method_blocks; | |
1176 } | |
1177 | |
1178 #undef FETCH_FLAG_FROM_VM | |
1179 | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1180 void ciMethod::dump_replay_data(outputStream* st) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1181 ASSERT_IN_VM; |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1182 Method* method = get_Method(); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1183 Klass* holder = method->method_holder(); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1184 st->print_cr("ciMethod %s %s %s %d %d %d %d %d", |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1185 holder->name()->as_quoted_ascii(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1186 method->name()->as_quoted_ascii(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1187 method->signature()->as_quoted_ascii(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1188 method->invocation_counter()->raw_counter(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1189 method->backedge_counter()->raw_counter(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1190 interpreter_invocation_count(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1191 interpreter_throwout_count(), |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1192 _instructions_size); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1193 } |
0 | 1194 |
1195 // ------------------------------------------------------------------ | |
1196 // ciMethod::print_codes | |
1197 // | |
1198 // Print a range of the bytecodes for this method. | |
1199 void ciMethod::print_codes_on(int from, int to, outputStream* st) { | |
1200 check_is_loaded(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1201 GUARDED_VM_ENTRY(get_Method()->print_codes_on(from, to, st);) |
0 | 1202 } |
1203 | |
1204 // ------------------------------------------------------------------ | |
1205 // ciMethod::print_name | |
1206 // | |
1207 // Print the name of this method, including signature and some flags. | |
1208 void ciMethod::print_name(outputStream* st) { | |
1209 check_is_loaded(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1210 GUARDED_VM_ENTRY(get_Method()->print_name(st);) |
0 | 1211 } |
1212 | |
1213 // ------------------------------------------------------------------ | |
1214 // ciMethod::print_short_name | |
1215 // | |
1216 // Print the name of this method, without signature. | |
1217 void ciMethod::print_short_name(outputStream* st) { | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1218 if (is_loaded()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1219 GUARDED_VM_ENTRY(get_Method()->print_short_name(st);); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1220 } else { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1221 // Fall back if method is not loaded. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1222 holder()->print_name_on(st); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1223 st->print("::"); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1224 name()->print_symbol_on(st); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1225 if (WizardMode) |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1226 signature()->as_symbol()->print_symbol_on(st); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1227 } |
0 | 1228 } |
1229 | |
1230 // ------------------------------------------------------------------ | |
1231 // ciMethod::print_impl | |
1232 // | |
1233 // Implementation of the print method. | |
1234 void ciMethod::print_impl(outputStream* st) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1235 ciMetadata::print_impl(st); |
0 | 1236 st->print(" name="); |
1237 name()->print_symbol_on(st); | |
1238 st->print(" holder="); | |
1239 holder()->print_name_on(st); | |
1240 st->print(" signature="); | |
1241 signature()->as_symbol()->print_symbol_on(st); | |
1242 if (is_loaded()) { | |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
1243 st->print(" loaded=true"); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
1244 st->print(" arg_size=%d", arg_size()); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
1245 st->print(" flags="); |
0 | 1246 flags().print_member_flags(st); |
1247 } else { | |
1248 st->print(" loaded=false"); | |
1249 } | |
1250 } |