Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethod.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 5ddfcf4b079e |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1251
diff
changeset
|
2 * Copyright (c) 1999, 2010, 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/ciMethodKlass.hpp" | |
33 #include "ci/ciStreams.hpp" | |
34 #include "ci/ciSymbol.hpp" | |
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" | |
54 #include "oops/methodOop.hpp" | |
55 #endif | |
56 #ifdef SHARK | |
57 #include "ci/ciTypeFlow.hpp" | |
58 #include "oops/methodOop.hpp" | |
59 #endif | |
0 | 60 |
61 // ciMethod | |
62 // | |
63 // This class represents a methodOop in the HotSpot virtual | |
64 // machine. | |
65 | |
66 | |
67 // ------------------------------------------------------------------ | |
68 // ciMethod::ciMethod | |
69 // | |
70 // Loaded method. | |
71 ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) { | |
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(); | |
82 _handler_count = h_m()->exception_table()->length() / 4; | |
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 | |
109 if (instanceKlass::cast(h_m()->method_holder())->is_linked()) { | |
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. | |
125 _name = env->get_object(h_m()->name())->as_symbol(); | |
126 _holder = env->get_object(h_m()->method_holder())->as_instance_klass(); | |
127 ciSymbol* sig_symbol = env->get_object(h_m()->signature())->as_symbol(); | |
128 _signature = new (env->arena()) ciSignature(_holder, sig_symbol); | |
129 _method_data = NULL; | |
130 // Take a snapshot of these values, so they will be commensurate with the MDO. | |
1783 | 131 if (ProfileInterpreter || TieredCompilation) { |
0 | 132 int invcnt = h_m()->interpreter_invocation_count(); |
133 // if the value overflowed report it as max int | |
134 _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ; | |
135 _interpreter_throwout_count = h_m()->interpreter_throwout_count(); | |
136 } else { | |
137 _interpreter_invocation_count = 0; | |
138 _interpreter_throwout_count = 0; | |
139 } | |
140 if (_interpreter_invocation_count == 0) | |
141 _interpreter_invocation_count = 1; | |
142 } | |
143 | |
144 | |
145 // ------------------------------------------------------------------ | |
146 // ciMethod::ciMethod | |
147 // | |
148 // Unloaded method. | |
149 ciMethod::ciMethod(ciInstanceKlass* holder, | |
150 ciSymbol* name, | |
151 ciSymbol* signature) : ciObject(ciMethodKlass::make()) { | |
152 // These fields are always filled in. | |
153 _name = name; | |
154 _holder = holder; | |
155 _signature = new (CURRENT_ENV->arena()) ciSignature(_holder, signature); | |
156 _intrinsic_id = vmIntrinsics::_none; | |
157 _liveness = NULL; | |
158 _can_be_statically_bound = false; | |
159 _method_blocks = NULL; | |
160 _method_data = NULL; | |
1692 | 161 #if defined(COMPILER2) || defined(SHARK) |
0 | 162 _flow = NULL; |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
163 _bcea = NULL; |
1692 | 164 #endif // COMPILER2 || SHARK |
0 | 165 } |
166 | |
167 | |
168 // ------------------------------------------------------------------ | |
169 // ciMethod::load_code | |
170 // | |
171 // Load the bytecodes and exception handler table for this method. | |
172 void ciMethod::load_code() { | |
173 VM_ENTRY_MARK; | |
174 assert(is_loaded(), "only loaded methods have code"); | |
175 | |
176 methodOop me = get_methodOop(); | |
177 Arena* arena = CURRENT_THREAD_ENV->arena(); | |
178 | |
179 // Load the bytecodes. | |
180 _code = (address)arena->Amalloc(code_size()); | |
181 memcpy(_code, me->code_base(), code_size()); | |
182 | |
183 // 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
|
184 if (me->number_of_breakpoints() > 0) { |
0 | 185 BreakpointInfo* bp = instanceKlass::cast(me->method_holder())->breakpoints(); |
186 for (; bp != NULL; bp = bp->next()) { | |
187 if (bp->match(me)) { | |
188 code_at_put(bp->bci(), bp->orig_bytecode()); | |
189 } | |
190 } | |
191 } | |
192 | |
193 // And load the exception table. | |
194 typeArrayOop exc_table = me->exception_table(); | |
195 | |
196 // Allocate one extra spot in our list of exceptions. This | |
197 // last entry will be used to represent the possibility that | |
198 // an exception escapes the method. See ciExceptionHandlerStream | |
199 // for details. | |
200 _exception_handlers = | |
201 (ciExceptionHandler**)arena->Amalloc(sizeof(ciExceptionHandler*) | |
202 * (_handler_count + 1)); | |
203 if (_handler_count > 0) { | |
204 for (int i=0; i<_handler_count; i++) { | |
205 int base = i*4; | |
206 _exception_handlers[i] = new (arena) ciExceptionHandler( | |
207 holder(), | |
208 /* start */ exc_table->int_at(base), | |
209 /* limit */ exc_table->int_at(base+1), | |
210 /* goto pc */ exc_table->int_at(base+2), | |
211 /* cp index */ exc_table->int_at(base+3)); | |
212 } | |
213 } | |
214 | |
215 // Put an entry at the end of our list to represent the possibility | |
216 // of exceptional exit. | |
217 _exception_handlers[_handler_count] = | |
218 new (arena) ciExceptionHandler(holder(), 0, code_size(), -1, 0); | |
219 | |
220 if (CIPrintMethodCodes) { | |
221 print_codes(); | |
222 } | |
223 } | |
224 | |
225 | |
226 // ------------------------------------------------------------------ | |
227 // ciMethod::has_linenumber_table | |
228 // | |
229 // length unknown until decompression | |
230 bool ciMethod::has_linenumber_table() const { | |
231 check_is_loaded(); | |
232 VM_ENTRY_MARK; | |
233 return get_methodOop()->has_linenumber_table(); | |
234 } | |
235 | |
236 | |
237 // ------------------------------------------------------------------ | |
238 // ciMethod::compressed_linenumber_table | |
239 u_char* ciMethod::compressed_linenumber_table() const { | |
240 check_is_loaded(); | |
241 VM_ENTRY_MARK; | |
242 return get_methodOop()->compressed_linenumber_table(); | |
243 } | |
244 | |
245 | |
246 // ------------------------------------------------------------------ | |
247 // ciMethod::line_number_from_bci | |
248 int ciMethod::line_number_from_bci(int bci) const { | |
249 check_is_loaded(); | |
250 VM_ENTRY_MARK; | |
251 return get_methodOop()->line_number_from_bci(bci); | |
252 } | |
253 | |
254 | |
255 // ------------------------------------------------------------------ | |
256 // ciMethod::vtable_index | |
257 // | |
258 // Get the position of this method's entry in the vtable, if any. | |
259 int ciMethod::vtable_index() { | |
260 check_is_loaded(); | |
261 assert(holder()->is_linked(), "must be linked"); | |
262 VM_ENTRY_MARK; | |
263 return get_methodOop()->vtable_index(); | |
264 } | |
265 | |
266 | |
1692 | 267 #ifdef SHARK |
268 // ------------------------------------------------------------------ | |
269 // ciMethod::itable_index | |
270 // | |
271 // Get the position of this method's entry in the itable, if any. | |
272 int ciMethod::itable_index() { | |
273 check_is_loaded(); | |
274 assert(holder()->is_linked(), "must be linked"); | |
275 VM_ENTRY_MARK; | |
276 return klassItable::compute_itable_index(get_methodOop()); | |
277 } | |
278 #endif // SHARK | |
279 | |
280 | |
0 | 281 // ------------------------------------------------------------------ |
282 // ciMethod::native_entry | |
283 // | |
284 // Get the address of this method's native code, if any. | |
285 address ciMethod::native_entry() { | |
286 check_is_loaded(); | |
287 assert(flags().is_native(), "must be native method"); | |
288 VM_ENTRY_MARK; | |
289 methodOop method = get_methodOop(); | |
290 address entry = method->native_function(); | |
291 assert(entry != NULL, "must be valid entry point"); | |
292 return entry; | |
293 } | |
294 | |
295 | |
296 // ------------------------------------------------------------------ | |
297 // ciMethod::interpreter_entry | |
298 // | |
299 // Get the entry point for running this method in the interpreter. | |
300 address ciMethod::interpreter_entry() { | |
301 check_is_loaded(); | |
302 VM_ENTRY_MARK; | |
303 methodHandle mh(THREAD, get_methodOop()); | |
304 return Interpreter::entry_for_method(mh); | |
305 } | |
306 | |
307 | |
308 // ------------------------------------------------------------------ | |
309 // ciMethod::uses_balanced_monitors | |
310 // | |
311 // Does this method use monitors in a strict stack-disciplined manner? | |
312 bool ciMethod::has_balanced_monitors() { | |
313 check_is_loaded(); | |
314 if (_balanced_monitors) return true; | |
315 | |
316 // Analyze the method to see if monitors are used properly. | |
317 VM_ENTRY_MARK; | |
318 methodHandle method(THREAD, get_methodOop()); | |
319 assert(method->has_monitor_bytecodes(), "should have checked this"); | |
320 | |
321 // Check to see if a previous compilation computed the | |
322 // monitor-matching analysis. | |
323 if (method->guaranteed_monitor_matching()) { | |
324 _balanced_monitors = true; | |
325 return true; | |
326 } | |
327 | |
328 { | |
329 EXCEPTION_MARK; | |
330 ResourceMark rm(THREAD); | |
331 GeneratePairingInfo gpi(method); | |
332 gpi.compute_map(CATCH); | |
333 if (!gpi.monitor_safe()) { | |
334 return false; | |
335 } | |
336 method->set_guaranteed_monitor_matching(); | |
337 _balanced_monitors = true; | |
338 } | |
339 return true; | |
340 } | |
341 | |
342 | |
343 // ------------------------------------------------------------------ | |
344 // ciMethod::get_flow_analysis | |
345 ciTypeFlow* ciMethod::get_flow_analysis() { | |
1692 | 346 #if defined(COMPILER2) || defined(SHARK) |
0 | 347 if (_flow == NULL) { |
348 ciEnv* env = CURRENT_ENV; | |
349 _flow = new (env->arena()) ciTypeFlow(env, this); | |
350 _flow->do_flow(); | |
351 } | |
352 return _flow; | |
1692 | 353 #else // COMPILER2 || SHARK |
0 | 354 ShouldNotReachHere(); |
355 return NULL; | |
1692 | 356 #endif // COMPILER2 || SHARK |
0 | 357 } |
358 | |
359 | |
360 // ------------------------------------------------------------------ | |
361 // ciMethod::get_osr_flow_analysis | |
362 ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) { | |
1692 | 363 #if defined(COMPILER2) || defined(SHARK) |
0 | 364 // OSR entry points are always place after a call bytecode of some sort |
365 assert(osr_bci >= 0, "must supply valid OSR entry point"); | |
366 ciEnv* env = CURRENT_ENV; | |
367 ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci); | |
368 flow->do_flow(); | |
369 return flow; | |
1692 | 370 #else // COMPILER2 || SHARK |
0 | 371 ShouldNotReachHere(); |
372 return NULL; | |
1692 | 373 #endif // COMPILER2 || SHARK |
0 | 374 } |
375 | |
376 // ------------------------------------------------------------------ | |
991 | 377 // ciMethod::raw_liveness_at_bci |
0 | 378 // |
379 // Which local variables are live at a specific bci? | |
991 | 380 MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) { |
0 | 381 check_is_loaded(); |
382 if (_liveness == NULL) { | |
383 // Create the liveness analyzer. | |
384 Arena* arena = CURRENT_ENV->arena(); | |
385 _liveness = new (arena) MethodLiveness(arena, this); | |
386 _liveness->compute_liveness(); | |
387 } | |
991 | 388 return _liveness->get_liveness_at(bci); |
389 } | |
390 | |
391 // ------------------------------------------------------------------ | |
392 // ciMethod::liveness_at_bci | |
393 // | |
394 // Which local variables are live at a specific bci? When debugging | |
395 // will return true for all locals in some cases to improve debug | |
396 // information. | |
397 MethodLivenessResult ciMethod::liveness_at_bci(int bci) { | |
398 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
|
399 if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { |
0 | 400 // Keep all locals live for the user's edification and amusement. |
401 result.at_put_range(0, result.size(), true); | |
402 } | |
403 return result; | |
404 } | |
405 | |
406 // ciMethod::live_local_oops_at_bci | |
407 // | |
408 // find all the live oops in the locals array for a particular bci | |
409 // Compute what the interpreter believes by using the interpreter | |
410 // oopmap generator. This is used as a double check during osr to | |
411 // guard against conservative result from MethodLiveness making us | |
412 // think a dead oop is live. MethodLiveness is conservative in the | |
413 // sense that it may consider locals to be live which cannot be live, | |
414 // like in the case where a local could contain an oop or a primitive | |
415 // along different paths. In that case the local must be dead when | |
416 // those paths merge. Since the interpreter's viewpoint is used when | |
417 // gc'ing an interpreter frame we need to use its viewpoint during | |
418 // OSR when loading the locals. | |
419 | |
420 BitMap ciMethod::live_local_oops_at_bci(int bci) { | |
421 VM_ENTRY_MARK; | |
422 InterpreterOopMap mask; | |
423 OopMapCache::compute_one_oop_map(get_methodOop(), bci, &mask); | |
424 int mask_size = max_locals(); | |
425 BitMap result(mask_size); | |
426 result.clear(); | |
427 int i; | |
428 for (i = 0; i < mask_size ; i++ ) { | |
429 if (mask.is_oop(i)) result.set_bit(i); | |
430 } | |
431 return result; | |
432 } | |
433 | |
434 | |
435 #ifdef COMPILER1 | |
436 // ------------------------------------------------------------------ | |
437 // ciMethod::bci_block_start | |
438 // | |
439 // Marks all bcis where a new basic block starts | |
440 const BitMap ciMethod::bci_block_start() { | |
441 check_is_loaded(); | |
442 if (_liveness == NULL) { | |
443 // Create the liveness analyzer. | |
444 Arena* arena = CURRENT_ENV->arena(); | |
445 _liveness = new (arena) MethodLiveness(arena, this); | |
446 _liveness->compute_liveness(); | |
447 } | |
448 | |
449 return _liveness->get_bci_block_start(); | |
450 } | |
451 #endif // COMPILER1 | |
452 | |
453 | |
454 // ------------------------------------------------------------------ | |
455 // ciMethod::call_profile_at_bci | |
456 // | |
457 // Get the ciCallProfile for the invocation of this method. | |
458 // Also reports receiver types for non-call type checks (if TypeProfileCasts). | |
459 ciCallProfile ciMethod::call_profile_at_bci(int bci) { | |
460 ResourceMark rm; | |
461 ciCallProfile result; | |
462 if (method_data() != NULL && method_data()->is_mature()) { | |
463 ciProfileData* data = method_data()->bci_to_data(bci); | |
464 if (data != NULL && data->is_CounterData()) { | |
465 // Every profiled call site has a counter. | |
466 int count = data->as_CounterData()->count(); | |
467 | |
468 if (!data->is_ReceiverTypeData()) { | |
469 result._receiver_count[0] = 0; // that's a definite zero | |
470 } else { // ReceiverTypeData is a subclass of CounterData | |
471 ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData(); | |
472 // In addition, virtual call sites have receiver type information | |
473 int receivers_count_total = 0; | |
474 int morphism = 0; | |
1783 | 475 // Precompute morphism for the possible fixup |
0 | 476 for (uint i = 0; i < call->row_limit(); i++) { |
477 ciKlass* receiver = call->receiver(i); | |
478 if (receiver == NULL) continue; | |
1783 | 479 morphism++; |
480 } | |
481 int epsilon = 0; | |
482 if (TieredCompilation && ProfileInterpreter) { | |
483 // Interpreter and C1 treat final and special invokes differently. | |
484 // C1 will record a type, whereas the interpreter will just | |
485 // increment the count. Detect this case. | |
486 if (morphism == 1 && count > 0) { | |
487 epsilon = count; | |
488 count = 0; | |
489 } | |
490 } | |
491 for (uint i = 0; i < call->row_limit(); i++) { | |
492 ciKlass* receiver = call->receiver(i); | |
493 if (receiver == NULL) continue; | |
494 int rcount = call->receiver_count(i) + epsilon; | |
0 | 495 if (rcount == 0) rcount = 1; // Should be valid value |
496 receivers_count_total += rcount; | |
497 // Add the receiver to result data. | |
498 result.add_receiver(receiver, rcount); | |
499 // If we extend profiling to record methods, | |
500 // we will set result._method also. | |
501 } | |
502 // Determine call site's morphism. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
503 // 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
|
504 // 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
|
505 // 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
|
506 if (morphism > 0 && morphism == result._limit) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
507 // The morphism <= MorphismLimit. |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
508 if ((morphism < ciCallProfile::MorphismLimit) || |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
509 (morphism == ciCallProfile::MorphismLimit && count == 0)) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
510 #ifdef ASSERT |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
511 if (count > 0) { |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1206
diff
changeset
|
512 this->print_short_name(tty); |
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1206
diff
changeset
|
513 tty->print_cr(" @ bci:%d", bci); |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
514 this->print_codes(); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
515 assert(false, "this call site should not be polymorphic"); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
516 } |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
517 #endif |
0 | 518 result._morphism = morphism; |
519 } | |
520 } | |
521 // Make the count consistent if this is a call profile. If count is | |
522 // zero or less, presume that this is a typecheck profile and | |
523 // do nothing. Otherwise, increase count to be the sum of all | |
524 // receiver's counts. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
525 if (count >= 0) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1152
diff
changeset
|
526 count += receivers_count_total; |
0 | 527 } |
528 } | |
529 result._count = count; | |
530 } | |
531 } | |
532 return result; | |
533 } | |
534 | |
535 // ------------------------------------------------------------------ | |
536 // Add new receiver and sort data by receiver's profile count. | |
537 void ciCallProfile::add_receiver(ciKlass* receiver, int receiver_count) { | |
538 // Add new receiver and sort data by receiver's counts when we have space | |
539 // for it otherwise replace the less called receiver (less called receiver | |
540 // is placed to the last array element which is not used). | |
541 // First array's element contains most called receiver. | |
542 int i = _limit; | |
543 for (; i > 0 && receiver_count > _receiver_count[i-1]; i--) { | |
544 _receiver[i] = _receiver[i-1]; | |
545 _receiver_count[i] = _receiver_count[i-1]; | |
546 } | |
547 _receiver[i] = receiver; | |
548 _receiver_count[i] = receiver_count; | |
549 if (_limit < MorphismLimit) _limit++; | |
550 } | |
551 | |
552 // ------------------------------------------------------------------ | |
553 // ciMethod::find_monomorphic_target | |
554 // | |
555 // Given a certain calling environment, find the monomorphic target | |
556 // for the call. Return NULL if the call is not monomorphic in | |
557 // its calling environment, or if there are only abstract methods. | |
558 // The returned method is never abstract. | |
559 // Note: If caller uses a non-null result, it must inform dependencies | |
560 // via assert_unique_concrete_method or assert_leaf_type. | |
561 ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller, | |
562 ciInstanceKlass* callee_holder, | |
563 ciInstanceKlass* actual_recv) { | |
564 check_is_loaded(); | |
565 | |
566 if (actual_recv->is_interface()) { | |
567 // %%% We cannot trust interface types, yet. See bug 6312651. | |
568 return NULL; | |
569 } | |
570 | |
571 ciMethod* root_m = resolve_invoke(caller, actual_recv); | |
572 if (root_m == NULL) { | |
573 // Something went wrong looking up the actual receiver method. | |
574 return NULL; | |
575 } | |
576 assert(!root_m->is_abstract(), "resolve_invoke promise"); | |
577 | |
578 // Make certain quick checks even if UseCHA is false. | |
579 | |
580 // Is it private or final? | |
581 if (root_m->can_be_statically_bound()) { | |
582 return root_m; | |
583 } | |
584 | |
585 if (actual_recv->is_leaf_type() && actual_recv == root_m->holder()) { | |
586 // Easy case. There is no other place to put a method, so don't bother | |
587 // to go through the VM_ENTRY_MARK and all the rest. | |
588 return root_m; | |
589 } | |
590 | |
591 // Array methods (clone, hashCode, etc.) are always statically bound. | |
592 // If we were to see an array type here, we'd return root_m. | |
593 // However, this method processes only ciInstanceKlasses. (See 4962591.) | |
594 // The inline_native_clone intrinsic narrows Object to T[] properly, | |
595 // so there is no need to do the same job here. | |
596 | |
597 if (!UseCHA) return NULL; | |
598 | |
599 VM_ENTRY_MARK; | |
600 | |
601 methodHandle target; | |
602 { | |
603 MutexLocker locker(Compile_lock); | |
604 klassOop context = actual_recv->get_klassOop(); | |
605 target = Dependencies::find_unique_concrete_method(context, | |
606 root_m->get_methodOop()); | |
607 // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods. | |
608 } | |
609 | |
610 #ifndef PRODUCT | |
611 if (TraceDependencies && target() != NULL && target() != root_m->get_methodOop()) { | |
612 tty->print("found a non-root unique target method"); | |
613 tty->print_cr(" context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name()); | |
614 tty->print(" method = "); | |
615 target->print_short_name(tty); | |
616 tty->cr(); | |
617 } | |
618 #endif //PRODUCT | |
619 | |
620 if (target() == NULL) { | |
621 return NULL; | |
622 } | |
623 if (target() == root_m->get_methodOop()) { | |
624 return root_m; | |
625 } | |
626 if (!root_m->is_public() && | |
627 !root_m->is_protected()) { | |
628 // If we are going to reason about inheritance, it's easiest | |
629 // if the method in question is public, protected, or private. | |
630 // If the answer is not root_m, it is conservatively correct | |
631 // to return NULL, even if the CHA encountered irrelevant | |
632 // methods in other packages. | |
633 // %%% TO DO: Work out logic for package-private methods | |
634 // with the same name but different vtable indexes. | |
635 return NULL; | |
636 } | |
637 return CURRENT_THREAD_ENV->get_object(target())->as_method(); | |
638 } | |
639 | |
640 // ------------------------------------------------------------------ | |
641 // ciMethod::resolve_invoke | |
642 // | |
643 // Given a known receiver klass, find the target for the call. | |
644 // Return NULL if the call has no target or the target is abstract. | |
645 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) { | |
646 check_is_loaded(); | |
647 VM_ENTRY_MARK; | |
648 | |
649 KlassHandle caller_klass (THREAD, caller->get_klassOop()); | |
650 KlassHandle h_recv (THREAD, exact_receiver->get_klassOop()); | |
651 KlassHandle h_resolved (THREAD, holder()->get_klassOop()); | |
652 symbolHandle h_name (THREAD, name()->get_symbolOop()); | |
653 symbolHandle h_signature (THREAD, signature()->get_symbolOop()); | |
654 | |
655 methodHandle m; | |
656 // Only do exact lookup if receiver klass has been linked. Otherwise, | |
657 // the vtable has not been setup, and the LinkResolver will fail. | |
658 if (h_recv->oop_is_javaArray() | |
659 || | |
660 instanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { | |
661 if (holder()->is_interface()) { | |
662 m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); | |
663 } else { | |
664 m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); | |
665 } | |
666 } | |
667 | |
668 if (m.is_null()) { | |
669 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) | |
670 return NULL; | |
671 } | |
672 | |
673 ciMethod* result = this; | |
674 if (m() != get_methodOop()) { | |
675 result = CURRENT_THREAD_ENV->get_object(m())->as_method(); | |
676 } | |
677 | |
678 // Don't return abstract methods because they aren't | |
679 // optimizable or interesting. | |
680 if (result->is_abstract()) { | |
681 return NULL; | |
682 } else { | |
683 return result; | |
684 } | |
685 } | |
686 | |
687 // ------------------------------------------------------------------ | |
688 // ciMethod::resolve_vtable_index | |
689 // | |
690 // Given a known receiver klass, find the vtable index for the call. | |
691 // Return methodOopDesc::invalid_vtable_index if the vtable_index is unknown. | |
692 int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) { | |
693 check_is_loaded(); | |
694 | |
695 int vtable_index = methodOopDesc::invalid_vtable_index; | |
696 // Only do lookup if receiver klass has been linked. Otherwise, | |
697 // the vtable has not been setup, and the LinkResolver will fail. | |
698 if (!receiver->is_interface() | |
699 && (!receiver->is_instance_klass() || | |
700 receiver->as_instance_klass()->is_linked())) { | |
701 VM_ENTRY_MARK; | |
702 | |
703 KlassHandle caller_klass (THREAD, caller->get_klassOop()); | |
704 KlassHandle h_recv (THREAD, receiver->get_klassOop()); | |
705 symbolHandle h_name (THREAD, name()->get_symbolOop()); | |
706 symbolHandle h_signature (THREAD, signature()->get_symbolOop()); | |
707 | |
708 vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); | |
709 if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { | |
710 // A statically bound method. Return "no such index". | |
711 vtable_index = methodOopDesc::invalid_vtable_index; | |
712 } | |
713 } | |
714 | |
715 return vtable_index; | |
716 } | |
717 | |
718 // ------------------------------------------------------------------ | |
719 // ciMethod::interpreter_call_site_count | |
720 int ciMethod::interpreter_call_site_count(int bci) { | |
721 if (method_data() != NULL) { | |
722 ResourceMark rm; | |
723 ciProfileData* data = method_data()->bci_to_data(bci); | |
724 if (data != NULL && data->is_CounterData()) { | |
725 return scale_count(data->as_CounterData()->count()); | |
726 } | |
727 } | |
728 return -1; // unknown | |
729 } | |
730 | |
731 // ------------------------------------------------------------------ | |
732 // Adjust a CounterData count to be commensurate with | |
733 // interpreter_invocation_count. If the MDO exists for | |
734 // only 25% of the time the method exists, then the | |
735 // counts in the MDO should be scaled by 4X, so that | |
736 // they can be usefully and stably compared against the | |
737 // invocation counts in methods. | |
738 int ciMethod::scale_count(int count, float prof_factor) { | |
739 if (count > 0 && method_data() != NULL) { | |
1783 | 740 int counter_life; |
0 | 741 int method_life = interpreter_invocation_count(); |
1783 | 742 if (TieredCompilation) { |
743 // In tiered the MDO's life is measured directly, so just use the snapshotted counters | |
744 counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count()); | |
745 } else { | |
746 int current_mileage = method_data()->current_mileage(); | |
747 int creation_mileage = method_data()->creation_mileage(); | |
748 counter_life = current_mileage - creation_mileage; | |
749 } | |
750 | |
0 | 751 // counter_life due to backedge_counter could be > method_life |
752 if (counter_life > method_life) | |
753 counter_life = method_life; | |
754 if (0 < counter_life && counter_life <= method_life) { | |
755 count = (int)((double)count * prof_factor * method_life / counter_life + 0.5); | |
756 count = (count > 0) ? count : 1; | |
757 } | |
758 } | |
759 return count; | |
760 } | |
761 | |
762 // ------------------------------------------------------------------ | |
710 | 763 // invokedynamic support |
1564 | 764 |
765 // ------------------------------------------------------------------ | |
766 // ciMethod::is_method_handle_invoke | |
710 | 767 // |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1648
diff
changeset
|
768 // Return true if the method is an instance of one of the two |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1648
diff
changeset
|
769 // signature-polymorphic MethodHandle methods, invokeExact or invokeGeneric. |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
770 bool ciMethod::is_method_handle_invoke() const { |
1818
c93c652551b5
6986944: JSR 292 assert(caller_nm->is_method_handle_return(caller_frame.pc())) failed: must be MH call site
twisti
parents:
1783
diff
changeset
|
771 if (!is_loaded()) { |
c93c652551b5
6986944: JSR 292 assert(caller_nm->is_method_handle_return(caller_frame.pc())) failed: must be MH call site
twisti
parents:
1783
diff
changeset
|
772 bool flag = (holder()->name() == ciSymbol::java_dyn_MethodHandle() && |
c93c652551b5
6986944: JSR 292 assert(caller_nm->is_method_handle_return(caller_frame.pc())) failed: must be MH call site
twisti
parents:
1783
diff
changeset
|
773 methodOopDesc::is_method_handle_invoke_name(name()->sid())); |
c93c652551b5
6986944: JSR 292 assert(caller_nm->is_method_handle_return(caller_frame.pc())) failed: must be MH call site
twisti
parents:
1783
diff
changeset
|
774 return flag; |
c93c652551b5
6986944: JSR 292 assert(caller_nm->is_method_handle_return(caller_frame.pc())) failed: must be MH call site
twisti
parents:
1783
diff
changeset
|
775 } |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1648
diff
changeset
|
776 VM_ENTRY_MARK; |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1648
diff
changeset
|
777 return get_methodOop()->is_method_handle_invoke(); |
710 | 778 } |
779 | |
1564 | 780 // ------------------------------------------------------------------ |
781 // ciMethod::is_method_handle_adapter | |
782 // | |
783 // Return true if the method is a generated MethodHandle adapter. | |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1648
diff
changeset
|
784 // These are built by MethodHandleCompiler. |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
785 bool ciMethod::is_method_handle_adapter() const { |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1648
diff
changeset
|
786 if (!is_loaded()) return false; |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
787 VM_ENTRY_MARK; |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
788 return get_methodOop()->is_method_handle_adapter(); |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
789 } |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1137
diff
changeset
|
790 |
710 | 791 ciInstance* ciMethod::method_handle_type() { |
792 check_is_loaded(); | |
793 VM_ENTRY_MARK; | |
794 oop mtype = get_methodOop()->method_handle_type(); | |
795 return CURRENT_THREAD_ENV->get_object(mtype)->as_instance(); | |
796 } | |
797 | |
798 | |
799 // ------------------------------------------------------------------ | |
0 | 800 // ciMethod::build_method_data |
801 // | |
802 // Generate new methodDataOop objects at compile time. | |
803 void ciMethod::build_method_data(methodHandle h_m) { | |
804 EXCEPTION_CONTEXT; | |
805 if (is_native() || is_abstract() || h_m()->is_accessor()) return; | |
806 if (h_m()->method_data() == NULL) { | |
807 methodOopDesc::build_interpreter_method_data(h_m, THREAD); | |
808 if (HAS_PENDING_EXCEPTION) { | |
809 CLEAR_PENDING_EXCEPTION; | |
810 } | |
811 } | |
812 if (h_m()->method_data() != NULL) { | |
813 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); | |
814 _method_data->load_data(); | |
815 } else { | |
816 _method_data = CURRENT_ENV->get_empty_methodData(); | |
817 } | |
818 } | |
819 | |
820 // public, retroactive version | |
821 void ciMethod::build_method_data() { | |
822 if (_method_data == NULL || _method_data->is_empty()) { | |
823 GUARDED_VM_ENTRY({ | |
824 build_method_data(get_methodOop()); | |
825 }); | |
826 } | |
827 } | |
828 | |
829 | |
830 // ------------------------------------------------------------------ | |
831 // ciMethod::method_data | |
832 // | |
833 ciMethodData* ciMethod::method_data() { | |
834 if (_method_data != NULL) { | |
835 return _method_data; | |
836 } | |
837 VM_ENTRY_MARK; | |
838 ciEnv* env = CURRENT_ENV; | |
839 Thread* my_thread = JavaThread::current(); | |
840 methodHandle h_m(my_thread, get_methodOop()); | |
841 | |
1783 | 842 // Create an MDO for the inlinee |
843 if (TieredCompilation && is_c1_compile(env->comp_level())) { | |
0 | 844 build_method_data(h_m); |
845 } | |
846 | |
847 if (h_m()->method_data() != NULL) { | |
848 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); | |
849 _method_data->load_data(); | |
850 } else { | |
851 _method_data = CURRENT_ENV->get_empty_methodData(); | |
852 } | |
853 return _method_data; | |
854 | |
855 } | |
856 | |
857 | |
858 // ------------------------------------------------------------------ | |
859 // ciMethod::will_link | |
860 // | |
861 // Will this method link in a specific calling context? | |
862 bool ciMethod::will_link(ciKlass* accessing_klass, | |
863 ciKlass* declared_method_holder, | |
864 Bytecodes::Code bc) { | |
865 if (!is_loaded()) { | |
866 // Method lookup failed. | |
867 return false; | |
868 } | |
869 | |
870 // The link checks have been front-loaded into the get_method | |
871 // call. This method (ciMethod::will_link()) will be removed | |
872 // in the future. | |
873 | |
874 return true; | |
875 } | |
876 | |
877 // ------------------------------------------------------------------ | |
878 // ciMethod::should_exclude | |
879 // | |
880 // Should this method be excluded from compilation? | |
881 bool ciMethod::should_exclude() { | |
882 check_is_loaded(); | |
883 VM_ENTRY_MARK; | |
884 methodHandle mh(THREAD, get_methodOop()); | |
885 bool ignore; | |
886 return CompilerOracle::should_exclude(mh, ignore); | |
887 } | |
888 | |
889 // ------------------------------------------------------------------ | |
890 // ciMethod::should_inline | |
891 // | |
892 // Should this method be inlined during compilation? | |
893 bool ciMethod::should_inline() { | |
894 check_is_loaded(); | |
895 VM_ENTRY_MARK; | |
896 methodHandle mh(THREAD, get_methodOop()); | |
897 return CompilerOracle::should_inline(mh); | |
898 } | |
899 | |
900 // ------------------------------------------------------------------ | |
901 // ciMethod::should_not_inline | |
902 // | |
903 // Should this method be disallowed from inlining during compilation? | |
904 bool ciMethod::should_not_inline() { | |
905 check_is_loaded(); | |
906 VM_ENTRY_MARK; | |
907 methodHandle mh(THREAD, get_methodOop()); | |
908 return CompilerOracle::should_not_inline(mh); | |
909 } | |
910 | |
911 // ------------------------------------------------------------------ | |
912 // ciMethod::should_print_assembly | |
913 // | |
914 // Should the compiler print the generated code for this method? | |
915 bool ciMethod::should_print_assembly() { | |
916 check_is_loaded(); | |
917 VM_ENTRY_MARK; | |
918 methodHandle mh(THREAD, get_methodOop()); | |
919 return CompilerOracle::should_print(mh); | |
920 } | |
921 | |
922 // ------------------------------------------------------------------ | |
923 // ciMethod::break_at_execute | |
924 // | |
925 // Should the compiler insert a breakpoint into the generated code | |
926 // method? | |
927 bool ciMethod::break_at_execute() { | |
928 check_is_loaded(); | |
929 VM_ENTRY_MARK; | |
930 methodHandle mh(THREAD, get_methodOop()); | |
931 return CompilerOracle::should_break_at(mh); | |
932 } | |
933 | |
934 // ------------------------------------------------------------------ | |
935 // ciMethod::has_option | |
936 // | |
937 bool ciMethod::has_option(const char* option) { | |
938 check_is_loaded(); | |
939 VM_ENTRY_MARK; | |
940 methodHandle mh(THREAD, get_methodOop()); | |
941 return CompilerOracle::has_option_string(mh, option); | |
942 } | |
943 | |
944 // ------------------------------------------------------------------ | |
945 // ciMethod::can_be_compiled | |
946 // | |
947 // Have previous compilations of this method succeeded? | |
948 bool ciMethod::can_be_compiled() { | |
949 check_is_loaded(); | |
1783 | 950 ciEnv* env = CURRENT_ENV; |
951 if (is_c1_compile(env->comp_level())) { | |
952 return _is_c1_compilable; | |
953 } | |
954 return _is_c2_compilable; | |
0 | 955 } |
956 | |
957 // ------------------------------------------------------------------ | |
958 // ciMethod::set_not_compilable | |
959 // | |
960 // Tell the VM that this method cannot be compiled at all. | |
961 void ciMethod::set_not_compilable() { | |
962 check_is_loaded(); | |
963 VM_ENTRY_MARK; | |
1783 | 964 ciEnv* env = CURRENT_ENV; |
965 if (is_c1_compile(env->comp_level())) { | |
966 _is_c1_compilable = false; | |
967 } else { | |
968 _is_c2_compilable = false; | |
969 } | |
970 get_methodOop()->set_not_compilable(env->comp_level()); | |
0 | 971 } |
972 | |
973 // ------------------------------------------------------------------ | |
974 // ciMethod::can_be_osr_compiled | |
975 // | |
976 // Have previous compilations of this method succeeded? | |
977 // | |
978 // Implementation note: the VM does not currently keep track | |
979 // of failed OSR compilations per bci. The entry_bci parameter | |
980 // is currently unused. | |
981 bool ciMethod::can_be_osr_compiled(int entry_bci) { | |
982 check_is_loaded(); | |
983 VM_ENTRY_MARK; | |
1783 | 984 ciEnv* env = CURRENT_ENV; |
985 return !get_methodOop()->is_not_osr_compilable(env->comp_level()); | |
0 | 986 } |
987 | |
988 // ------------------------------------------------------------------ | |
989 // ciMethod::has_compiled_code | |
990 bool ciMethod::has_compiled_code() { | |
991 VM_ENTRY_MARK; | |
992 return get_methodOop()->code() != NULL; | |
993 } | |
994 | |
1783 | 995 int ciMethod::comp_level() { |
996 check_is_loaded(); | |
997 VM_ENTRY_MARK; | |
998 nmethod* nm = get_methodOop()->code(); | |
999 if (nm != NULL) return nm->comp_level(); | |
1000 return 0; | |
1001 } | |
1002 | |
0 | 1003 // ------------------------------------------------------------------ |
1004 // ciMethod::instructions_size | |
1748 | 1005 // |
1006 // This is a rough metric for "fat" methods, compared before inlining | |
1007 // with InlineSmallCode. The CodeBlob::code_size accessor includes | |
1008 // junk like exception handler, stubs, and constant table, which are | |
1009 // not highly relevant to an inlined method. So we use the more | |
1010 // specific accessor nmethod::insts_size. | |
1783 | 1011 int ciMethod::instructions_size(int comp_level) { |
0 | 1012 GUARDED_VM_ENTRY( |
1013 nmethod* code = get_methodOop()->code(); | |
1783 | 1014 if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) { |
1828
3f9a70eb8b1f
6989368: Regression in scimark2.MonteCarlo in jdk7_b112 on Linux
iveresov
parents:
1818
diff
changeset
|
1015 return code->insts_end() - code->verified_entry_point(); |
0 | 1016 } |
1783 | 1017 return 0; |
0 | 1018 ) |
1019 } | |
1020 | |
1021 // ------------------------------------------------------------------ | |
1022 // ciMethod::log_nmethod_identity | |
1023 void ciMethod::log_nmethod_identity(xmlStream* log) { | |
1024 GUARDED_VM_ENTRY( | |
1025 nmethod* code = get_methodOop()->code(); | |
1026 if (code != NULL) { | |
1027 code->log_identity(log); | |
1028 } | |
1029 ) | |
1030 } | |
1031 | |
1032 // ------------------------------------------------------------------ | |
1033 // ciMethod::is_not_reached | |
1034 bool ciMethod::is_not_reached(int bci) { | |
1035 check_is_loaded(); | |
1036 VM_ENTRY_MARK; | |
1037 return Interpreter::is_not_reached( | |
1038 methodHandle(THREAD, get_methodOop()), bci); | |
1039 } | |
1040 | |
1041 // ------------------------------------------------------------------ | |
1042 // ciMethod::was_never_executed | |
1043 bool ciMethod::was_executed_more_than(int times) { | |
1044 VM_ENTRY_MARK; | |
1045 return get_methodOop()->was_executed_more_than(times); | |
1046 } | |
1047 | |
1048 // ------------------------------------------------------------------ | |
1049 // ciMethod::has_unloaded_classes_in_signature | |
1050 bool ciMethod::has_unloaded_classes_in_signature() { | |
1051 VM_ENTRY_MARK; | |
1052 { | |
1053 EXCEPTION_MARK; | |
1054 methodHandle m(THREAD, get_methodOop()); | |
1055 bool has_unloaded = methodOopDesc::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD); | |
1056 if( HAS_PENDING_EXCEPTION ) { | |
1057 CLEAR_PENDING_EXCEPTION; | |
1058 return true; // Declare that we may have unloaded classes | |
1059 } | |
1060 return has_unloaded; | |
1061 } | |
1062 } | |
1063 | |
1064 // ------------------------------------------------------------------ | |
1065 // ciMethod::is_klass_loaded | |
1066 bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { | |
1067 VM_ENTRY_MARK; | |
1068 return get_methodOop()->is_klass_loaded(refinfo_index, must_be_resolved); | |
1069 } | |
1070 | |
1071 // ------------------------------------------------------------------ | |
1072 // ciMethod::check_call | |
1073 bool ciMethod::check_call(int refinfo_index, bool is_static) const { | |
1074 VM_ENTRY_MARK; | |
1075 { | |
1076 EXCEPTION_MARK; | |
1077 HandleMark hm(THREAD); | |
1078 constantPoolHandle pool (THREAD, get_methodOop()->constants()); | |
1079 methodHandle spec_method; | |
1080 KlassHandle spec_klass; | |
1081 LinkResolver::resolve_method(spec_method, spec_klass, pool, refinfo_index, THREAD); | |
1082 if (HAS_PENDING_EXCEPTION) { | |
1083 CLEAR_PENDING_EXCEPTION; | |
1084 return false; | |
1085 } else { | |
1086 return (spec_method->is_static() == is_static); | |
1087 } | |
1088 } | |
1089 return false; | |
1090 } | |
1091 | |
1092 // ------------------------------------------------------------------ | |
1093 // ciMethod::print_codes | |
1094 // | |
1095 // Print the bytecodes for this method. | |
1096 void ciMethod::print_codes_on(outputStream* st) { | |
1097 check_is_loaded(); | |
1098 GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(st);) | |
1099 } | |
1100 | |
1101 | |
1102 #define FETCH_FLAG_FROM_VM(flag_accessor) { \ | |
1103 check_is_loaded(); \ | |
1104 VM_ENTRY_MARK; \ | |
1105 return get_methodOop()->flag_accessor(); \ | |
1106 } | |
1107 | |
1108 bool ciMethod::is_empty_method() const { FETCH_FLAG_FROM_VM(is_empty_method); } | |
1109 bool ciMethod::is_vanilla_constructor() const { FETCH_FLAG_FROM_VM(is_vanilla_constructor); } | |
1110 bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); } | |
1111 bool ciMethod::has_jsrs () const { FETCH_FLAG_FROM_VM(has_jsrs); } | |
1112 bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); } | |
1113 bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); } | |
1114 | |
1115 BCEscapeAnalyzer *ciMethod::get_bcea() { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1116 #ifdef COMPILER2 |
0 | 1117 if (_bcea == NULL) { |
1118 _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL); | |
1119 } | |
1120 return _bcea; | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1121 #else // COMPILER2 |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1122 ShouldNotReachHere(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1123 return NULL; |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1124 #endif // COMPILER2 |
0 | 1125 } |
1126 | |
1127 ciMethodBlocks *ciMethod::get_method_blocks() { | |
1128 Arena *arena = CURRENT_ENV->arena(); | |
1129 if (_method_blocks == NULL) { | |
1130 _method_blocks = new (arena) ciMethodBlocks(arena, this); | |
1131 } | |
1132 return _method_blocks; | |
1133 } | |
1134 | |
1135 #undef FETCH_FLAG_FROM_VM | |
1136 | |
1137 | |
1138 // ------------------------------------------------------------------ | |
1139 // ciMethod::print_codes | |
1140 // | |
1141 // Print a range of the bytecodes for this method. | |
1142 void ciMethod::print_codes_on(int from, int to, outputStream* st) { | |
1143 check_is_loaded(); | |
1144 GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(from, to, st);) | |
1145 } | |
1146 | |
1147 // ------------------------------------------------------------------ | |
1148 // ciMethod::print_name | |
1149 // | |
1150 // Print the name of this method, including signature and some flags. | |
1151 void ciMethod::print_name(outputStream* st) { | |
1152 check_is_loaded(); | |
1153 GUARDED_VM_ENTRY(get_methodOop()->print_name(st);) | |
1154 } | |
1155 | |
1156 // ------------------------------------------------------------------ | |
1157 // ciMethod::print_short_name | |
1158 // | |
1159 // Print the name of this method, without signature. | |
1160 void ciMethod::print_short_name(outputStream* st) { | |
1161 check_is_loaded(); | |
1162 GUARDED_VM_ENTRY(get_methodOop()->print_short_name(st);) | |
1163 } | |
1164 | |
1165 // ------------------------------------------------------------------ | |
1166 // ciMethod::print_impl | |
1167 // | |
1168 // Implementation of the print method. | |
1169 void ciMethod::print_impl(outputStream* st) { | |
1170 ciObject::print_impl(st); | |
1171 st->print(" name="); | |
1172 name()->print_symbol_on(st); | |
1173 st->print(" holder="); | |
1174 holder()->print_name_on(st); | |
1175 st->print(" signature="); | |
1176 signature()->as_symbol()->print_symbol_on(st); | |
1177 if (is_loaded()) { | |
1178 st->print(" loaded=true flags="); | |
1179 flags().print_member_flags(st); | |
1180 } else { | |
1181 st->print(" loaded=false"); | |
1182 } | |
1183 } |