Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethod.cpp @ 8733:9def4075da6d
8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord
Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate().
Reviewed-by: johnc, ysr
Contributed-by: tamao <tao.mao@oracle.com>
author | tamao |
---|---|
date | Tue, 05 Mar 2013 15:36:56 -0800 |
parents | 6a51fc70a15e |
children | 5fc51c1ecdeb 16885e702c88 |
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 // ------------------------------------------------------------------ | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
745 // ciMethod::get_field_at_bci |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
746 ciField* ciMethod::get_field_at_bci(int bci, bool &will_link) { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
747 ciBytecodeStream iter(this); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
748 iter.reset_to_bci(bci); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
749 iter.next(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
750 return iter.get_field(will_link); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
751 } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
752 |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
753 // ------------------------------------------------------------------ |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
754 // ciMethod::get_method_at_bci |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
755 ciMethod* ciMethod::get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature) { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
756 ciBytecodeStream iter(this); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
757 iter.reset_to_bci(bci); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
758 iter.next(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
759 return iter.get_method(will_link, declared_signature); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
760 } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
761 |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6973
diff
changeset
|
762 // ------------------------------------------------------------------ |
0 | 763 // Adjust a CounterData count to be commensurate with |
764 // interpreter_invocation_count. If the MDO exists for | |
765 // only 25% of the time the method exists, then the | |
766 // counts in the MDO should be scaled by 4X, so that | |
767 // they can be usefully and stably compared against the | |
768 // invocation counts in methods. | |
769 int ciMethod::scale_count(int count, float prof_factor) { | |
770 if (count > 0 && method_data() != NULL) { | |
1783 | 771 int counter_life; |
0 | 772 int method_life = interpreter_invocation_count(); |
1783 | 773 if (TieredCompilation) { |
774 // In tiered the MDO's life is measured directly, so just use the snapshotted counters | |
775 counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count()); | |
776 } else { | |
777 int current_mileage = method_data()->current_mileage(); | |
778 int creation_mileage = method_data()->creation_mileage(); | |
779 counter_life = current_mileage - creation_mileage; | |
780 } | |
781 | |
0 | 782 // counter_life due to backedge_counter could be > method_life |
783 if (counter_life > method_life) | |
784 counter_life = method_life; | |
785 if (0 < counter_life && counter_life <= method_life) { | |
786 count = (int)((double)count * prof_factor * method_life / counter_life + 0.5); | |
787 count = (count > 0) ? count : 1; | |
788 } | |
789 } | |
790 return count; | |
791 } | |
792 | |
793 // ------------------------------------------------------------------ | |
710 | 794 // invokedynamic support |
1564 | 795 |
796 // ------------------------------------------------------------------ | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
797 // ciMethod::is_method_handle_intrinsic |
710 | 798 // |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
799 // 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
|
800 // 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
|
801 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
|
802 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
|
803 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
|
804 MethodHandles::is_signature_polymorphic_intrinsic(iid)); |
710 | 805 } |
806 | |
1564 | 807 // ------------------------------------------------------------------ |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
808 // ciMethod::is_compiled_lambda_form |
1564 | 809 // |
810 // 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
|
811 // 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
|
812 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
|
813 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
|
814 return iid == vmIntrinsics::_compiledLambdaForm; |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
815 } |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
816 |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
817 // ------------------------------------------------------------------ |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
818 // ciMethod::has_member_arg |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
819 // |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
820 // 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
|
821 // 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
|
822 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
|
823 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
|
824 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
|
825 MethodHandles::has_member_arg(iid)); |
710 | 826 } |
827 | |
828 // ------------------------------------------------------------------ | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
829 // ciMethod::ensure_method_data |
0 | 830 // |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
831 // 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
|
832 // 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
|
833 bool ciMethod::ensure_method_data(methodHandle h_m) { |
0 | 834 EXCEPTION_CONTEXT; |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
835 if (is_native() || is_abstract() || h_m()->is_accessor()) return true; |
0 | 836 if (h_m()->method_data() == NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
837 Method::build_interpreter_method_data(h_m, THREAD); |
0 | 838 if (HAS_PENDING_EXCEPTION) { |
839 CLEAR_PENDING_EXCEPTION; | |
840 } | |
841 } | |
842 if (h_m()->method_data() != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
843 _method_data = CURRENT_ENV->get_method_data(h_m()->method_data()); |
0 | 844 _method_data->load_data(); |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
845 return true; |
0 | 846 } else { |
847 _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
|
848 return false; |
0 | 849 } |
850 } | |
851 | |
852 // public, retroactive version | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
853 bool ciMethod::ensure_method_data() { |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
854 bool result = true; |
0 | 855 if (_method_data == NULL || _method_data->is_empty()) { |
856 GUARDED_VM_ENTRY({ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
857 result = ensure_method_data(get_Method()); |
0 | 858 }); |
859 } | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
860 return result; |
0 | 861 } |
862 | |
863 | |
864 // ------------------------------------------------------------------ | |
865 // ciMethod::method_data | |
866 // | |
867 ciMethodData* ciMethod::method_data() { | |
868 if (_method_data != NULL) { | |
869 return _method_data; | |
870 } | |
871 VM_ENTRY_MARK; | |
872 ciEnv* env = CURRENT_ENV; | |
873 Thread* my_thread = JavaThread::current(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
874 methodHandle h_m(my_thread, get_Method()); |
0 | 875 |
876 if (h_m()->method_data() != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
877 _method_data = CURRENT_ENV->get_method_data(h_m()->method_data()); |
0 | 878 _method_data->load_data(); |
879 } else { | |
880 _method_data = CURRENT_ENV->get_empty_methodData(); | |
881 } | |
882 return _method_data; | |
883 | |
884 } | |
885 | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
886 // ------------------------------------------------------------------ |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
887 // ciMethod::method_data_or_null |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
888 // 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
|
889 // NULL otherwise. |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
890 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
|
891 ciMethodData *md = method_data(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
892 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
|
893 return md; |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
894 } |
0 | 895 |
896 // ------------------------------------------------------------------ | |
897 // ciMethod::should_exclude | |
898 // | |
899 // Should this method be excluded from compilation? | |
900 bool ciMethod::should_exclude() { | |
901 check_is_loaded(); | |
902 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
903 methodHandle mh(THREAD, get_Method()); |
0 | 904 bool ignore; |
905 return CompilerOracle::should_exclude(mh, ignore); | |
906 } | |
907 | |
908 // ------------------------------------------------------------------ | |
909 // ciMethod::should_inline | |
910 // | |
911 // Should this method be inlined during compilation? | |
912 bool ciMethod::should_inline() { | |
913 check_is_loaded(); | |
914 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
915 methodHandle mh(THREAD, get_Method()); |
0 | 916 return CompilerOracle::should_inline(mh); |
917 } | |
918 | |
919 // ------------------------------------------------------------------ | |
920 // ciMethod::should_not_inline | |
921 // | |
922 // Should this method be disallowed from inlining during compilation? | |
923 bool ciMethod::should_not_inline() { | |
924 check_is_loaded(); | |
925 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
926 methodHandle mh(THREAD, get_Method()); |
0 | 927 return CompilerOracle::should_not_inline(mh); |
928 } | |
929 | |
930 // ------------------------------------------------------------------ | |
931 // ciMethod::should_print_assembly | |
932 // | |
933 // Should the compiler print the generated code for this method? | |
934 bool ciMethod::should_print_assembly() { | |
935 check_is_loaded(); | |
936 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
937 methodHandle mh(THREAD, get_Method()); |
0 | 938 return CompilerOracle::should_print(mh); |
939 } | |
940 | |
941 // ------------------------------------------------------------------ | |
942 // ciMethod::break_at_execute | |
943 // | |
944 // Should the compiler insert a breakpoint into the generated code | |
945 // method? | |
946 bool ciMethod::break_at_execute() { | |
947 check_is_loaded(); | |
948 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
949 methodHandle mh(THREAD, get_Method()); |
0 | 950 return CompilerOracle::should_break_at(mh); |
951 } | |
952 | |
953 // ------------------------------------------------------------------ | |
954 // ciMethod::has_option | |
955 // | |
956 bool ciMethod::has_option(const char* option) { | |
957 check_is_loaded(); | |
958 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
959 methodHandle mh(THREAD, get_Method()); |
0 | 960 return CompilerOracle::has_option_string(mh, option); |
961 } | |
962 | |
963 // ------------------------------------------------------------------ | |
964 // ciMethod::can_be_compiled | |
965 // | |
966 // Have previous compilations of this method succeeded? | |
967 bool ciMethod::can_be_compiled() { | |
968 check_is_loaded(); | |
1783 | 969 ciEnv* env = CURRENT_ENV; |
970 if (is_c1_compile(env->comp_level())) { | |
971 return _is_c1_compilable; | |
972 } | |
973 return _is_c2_compilable; | |
0 | 974 } |
975 | |
976 // ------------------------------------------------------------------ | |
977 // ciMethod::set_not_compilable | |
978 // | |
979 // Tell the VM that this method cannot be compiled at all. | |
7998 | 980 void ciMethod::set_not_compilable(const char* reason) { |
0 | 981 check_is_loaded(); |
982 VM_ENTRY_MARK; | |
1783 | 983 ciEnv* env = CURRENT_ENV; |
984 if (is_c1_compile(env->comp_level())) { | |
985 _is_c1_compilable = false; | |
986 } else { | |
987 _is_c2_compilable = false; | |
988 } | |
7998 | 989 get_Method()->set_not_compilable(env->comp_level(), true, reason); |
0 | 990 } |
991 | |
992 // ------------------------------------------------------------------ | |
993 // ciMethod::can_be_osr_compiled | |
994 // | |
995 // Have previous compilations of this method succeeded? | |
996 // | |
997 // Implementation note: the VM does not currently keep track | |
998 // of failed OSR compilations per bci. The entry_bci parameter | |
999 // is currently unused. | |
1000 bool ciMethod::can_be_osr_compiled(int entry_bci) { | |
1001 check_is_loaded(); | |
1002 VM_ENTRY_MARK; | |
1783 | 1003 ciEnv* env = CURRENT_ENV; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1004 return !get_Method()->is_not_osr_compilable(env->comp_level()); |
0 | 1005 } |
1006 | |
1007 // ------------------------------------------------------------------ | |
1008 // ciMethod::has_compiled_code | |
1009 bool ciMethod::has_compiled_code() { | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1010 return instructions_size() > 0; |
0 | 1011 } |
1012 | |
1783 | 1013 int ciMethod::comp_level() { |
1014 check_is_loaded(); | |
1015 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1016 nmethod* nm = get_Method()->code(); |
1783 | 1017 if (nm != NULL) return nm->comp_level(); |
1018 return 0; | |
1019 } | |
1020 | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1021 int ciMethod::highest_osr_comp_level() { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1022 check_is_loaded(); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1023 VM_ENTRY_MARK; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1024 return get_Method()->highest_osr_comp_level(); |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1025 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3785
diff
changeset
|
1026 |
0 | 1027 // ------------------------------------------------------------------ |
3897
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1028 // ciMethod::code_size_for_inlining |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1029 // |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1030 // 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
|
1031 // 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
|
1032 int ciMethod::code_size_for_inlining() { |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1033 check_is_loaded(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1034 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
|
1035 return 1; |
3897
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1036 } |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1037 return code_size(); |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
3791
diff
changeset
|
1038 } |
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 // ------------------------------------------------------------------ |
0 | 1041 // ciMethod::instructions_size |
1748 | 1042 // |
1043 // This is a rough metric for "fat" methods, compared before inlining | |
1044 // with InlineSmallCode. The CodeBlob::code_size accessor includes | |
1045 // junk like exception handler, stubs, and constant table, which are | |
1046 // not highly relevant to an inlined method. So we use the more | |
1047 // specific accessor nmethod::insts_size. | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1048 int ciMethod::instructions_size() { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1049 if (_instructions_size == -1) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1050 GUARDED_VM_ENTRY( |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1051 nmethod* code = get_Method()->code(); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1052 if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1053 _instructions_size = code->insts_end() - code->verified_entry_point(); |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1054 } else { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1055 _instructions_size = 0; |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1056 } |
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 return _instructions_size; |
0 | 1060 } |
1061 | |
1062 // ------------------------------------------------------------------ | |
1063 // ciMethod::log_nmethod_identity | |
1064 void ciMethod::log_nmethod_identity(xmlStream* log) { | |
1065 GUARDED_VM_ENTRY( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1066 nmethod* code = get_Method()->code(); |
0 | 1067 if (code != NULL) { |
1068 code->log_identity(log); | |
1069 } | |
1070 ) | |
1071 } | |
1072 | |
1073 // ------------------------------------------------------------------ | |
1074 // ciMethod::is_not_reached | |
1075 bool ciMethod::is_not_reached(int bci) { | |
1076 check_is_loaded(); | |
1077 VM_ENTRY_MARK; | |
1078 return Interpreter::is_not_reached( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1079 methodHandle(THREAD, get_Method()), bci); |
0 | 1080 } |
1081 | |
1082 // ------------------------------------------------------------------ | |
1083 // ciMethod::was_never_executed | |
1084 bool ciMethod::was_executed_more_than(int times) { | |
1085 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1086 return get_Method()->was_executed_more_than(times); |
0 | 1087 } |
1088 | |
1089 // ------------------------------------------------------------------ | |
1090 // ciMethod::has_unloaded_classes_in_signature | |
1091 bool ciMethod::has_unloaded_classes_in_signature() { | |
1092 VM_ENTRY_MARK; | |
1093 { | |
1094 EXCEPTION_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1095 methodHandle m(THREAD, get_Method()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1096 bool has_unloaded = Method::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD); |
0 | 1097 if( HAS_PENDING_EXCEPTION ) { |
1098 CLEAR_PENDING_EXCEPTION; | |
1099 return true; // Declare that we may have unloaded classes | |
1100 } | |
1101 return has_unloaded; | |
1102 } | |
1103 } | |
1104 | |
1105 // ------------------------------------------------------------------ | |
1106 // ciMethod::is_klass_loaded | |
1107 bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { | |
1108 VM_ENTRY_MARK; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1109 return get_Method()->is_klass_loaded(refinfo_index, must_be_resolved); |
0 | 1110 } |
1111 | |
1112 // ------------------------------------------------------------------ | |
1113 // ciMethod::check_call | |
1114 bool ciMethod::check_call(int refinfo_index, bool is_static) const { | |
1115 VM_ENTRY_MARK; | |
1116 { | |
1117 EXCEPTION_MARK; | |
1118 HandleMark hm(THREAD); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1119 constantPoolHandle pool (THREAD, get_Method()->constants()); |
0 | 1120 methodHandle spec_method; |
1121 KlassHandle spec_klass; | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6213
diff
changeset
|
1122 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
|
1123 LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD); |
0 | 1124 if (HAS_PENDING_EXCEPTION) { |
1125 CLEAR_PENDING_EXCEPTION; | |
1126 return false; | |
1127 } else { | |
1128 return (spec_method->is_static() == is_static); | |
1129 } | |
1130 } | |
1131 return false; | |
1132 } | |
1133 | |
1134 // ------------------------------------------------------------------ | |
1135 // ciMethod::print_codes | |
1136 // | |
1137 // Print the bytecodes for this method. | |
1138 void ciMethod::print_codes_on(outputStream* st) { | |
1139 check_is_loaded(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1140 GUARDED_VM_ENTRY(get_Method()->print_codes_on(st);) |
0 | 1141 } |
1142 | |
1143 | |
1144 #define FETCH_FLAG_FROM_VM(flag_accessor) { \ | |
1145 check_is_loaded(); \ | |
1146 VM_ENTRY_MARK; \ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1147 return get_Method()->flag_accessor(); \ |
0 | 1148 } |
1149 | |
1150 bool ciMethod::is_empty_method() const { FETCH_FLAG_FROM_VM(is_empty_method); } | |
1151 bool ciMethod::is_vanilla_constructor() const { FETCH_FLAG_FROM_VM(is_vanilla_constructor); } | |
1152 bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); } | |
1153 bool ciMethod::has_jsrs () const { FETCH_FLAG_FROM_VM(has_jsrs); } | |
1154 bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); } | |
1155 bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); } | |
1156 | |
1157 BCEscapeAnalyzer *ciMethod::get_bcea() { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1158 #ifdef COMPILER2 |
0 | 1159 if (_bcea == NULL) { |
1160 _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL); | |
1161 } | |
1162 return _bcea; | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1163 #else // COMPILER2 |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1164 ShouldNotReachHere(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1165 return NULL; |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1166 #endif // COMPILER2 |
0 | 1167 } |
1168 | |
1169 ciMethodBlocks *ciMethod::get_method_blocks() { | |
1170 Arena *arena = CURRENT_ENV->arena(); | |
1171 if (_method_blocks == NULL) { | |
1172 _method_blocks = new (arena) ciMethodBlocks(arena, this); | |
1173 } | |
1174 return _method_blocks; | |
1175 } | |
1176 | |
1177 #undef FETCH_FLAG_FROM_VM | |
1178 | |
6972
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1179 void ciMethod::dump_replay_data(outputStream* st) { |
bd7a7ce2e264
6830717: replay of compilations would help with debugging
minqi
parents:
6940
diff
changeset
|
1180 ASSERT_IN_VM; |
7990
fcc9e7681d63
8006410: allocating without ResourceMark when CompileCommand was specified
vlivanov
parents:
7194
diff
changeset
|
1181 ResourceMark rm; |
6972
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 } |