Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethod.cpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | f95d63e2154a |
children | 3582bf76420e |
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 // ------------------------------------------------------------------ | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
800 // ciMethod::ensure_method_data |
0 | 801 // |
802 // Generate new methodDataOop objects at compile time. | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
803 // 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
|
804 bool ciMethod::ensure_method_data(methodHandle h_m) { |
0 | 805 EXCEPTION_CONTEXT; |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
806 if (is_native() || is_abstract() || h_m()->is_accessor()) return true; |
0 | 807 if (h_m()->method_data() == NULL) { |
808 methodOopDesc::build_interpreter_method_data(h_m, THREAD); | |
809 if (HAS_PENDING_EXCEPTION) { | |
810 CLEAR_PENDING_EXCEPTION; | |
811 } | |
812 } | |
813 if (h_m()->method_data() != NULL) { | |
814 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); | |
815 _method_data->load_data(); | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
816 return true; |
0 | 817 } else { |
818 _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
|
819 return false; |
0 | 820 } |
821 } | |
822 | |
823 // public, retroactive version | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
824 bool ciMethod::ensure_method_data() { |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
825 bool result = true; |
0 | 826 if (_method_data == NULL || _method_data->is_empty()) { |
827 GUARDED_VM_ENTRY({ | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
828 result = ensure_method_data(get_methodOop()); |
0 | 829 }); |
830 } | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
831 return result; |
0 | 832 } |
833 | |
834 | |
835 // ------------------------------------------------------------------ | |
836 // ciMethod::method_data | |
837 // | |
838 ciMethodData* ciMethod::method_data() { | |
839 if (_method_data != NULL) { | |
840 return _method_data; | |
841 } | |
842 VM_ENTRY_MARK; | |
843 ciEnv* env = CURRENT_ENV; | |
844 Thread* my_thread = JavaThread::current(); | |
845 methodHandle h_m(my_thread, get_methodOop()); | |
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 | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
857 // ------------------------------------------------------------------ |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
858 // ciMethod::method_data_or_null |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
859 // 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
|
860 // NULL otherwise. |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
861 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
|
862 ciMethodData *md = method_data(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
863 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
|
864 return md; |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
865 } |
0 | 866 |
867 // ------------------------------------------------------------------ | |
868 // ciMethod::will_link | |
869 // | |
870 // Will this method link in a specific calling context? | |
871 bool ciMethod::will_link(ciKlass* accessing_klass, | |
872 ciKlass* declared_method_holder, | |
873 Bytecodes::Code bc) { | |
874 if (!is_loaded()) { | |
875 // Method lookup failed. | |
876 return false; | |
877 } | |
878 | |
879 // The link checks have been front-loaded into the get_method | |
880 // call. This method (ciMethod::will_link()) will be removed | |
881 // in the future. | |
882 | |
883 return true; | |
884 } | |
885 | |
886 // ------------------------------------------------------------------ | |
887 // ciMethod::should_exclude | |
888 // | |
889 // Should this method be excluded from compilation? | |
890 bool ciMethod::should_exclude() { | |
891 check_is_loaded(); | |
892 VM_ENTRY_MARK; | |
893 methodHandle mh(THREAD, get_methodOop()); | |
894 bool ignore; | |
895 return CompilerOracle::should_exclude(mh, ignore); | |
896 } | |
897 | |
898 // ------------------------------------------------------------------ | |
899 // ciMethod::should_inline | |
900 // | |
901 // Should this method be inlined during compilation? | |
902 bool ciMethod::should_inline() { | |
903 check_is_loaded(); | |
904 VM_ENTRY_MARK; | |
905 methodHandle mh(THREAD, get_methodOop()); | |
906 return CompilerOracle::should_inline(mh); | |
907 } | |
908 | |
909 // ------------------------------------------------------------------ | |
910 // ciMethod::should_not_inline | |
911 // | |
912 // Should this method be disallowed from inlining during compilation? | |
913 bool ciMethod::should_not_inline() { | |
914 check_is_loaded(); | |
915 VM_ENTRY_MARK; | |
916 methodHandle mh(THREAD, get_methodOop()); | |
917 return CompilerOracle::should_not_inline(mh); | |
918 } | |
919 | |
920 // ------------------------------------------------------------------ | |
921 // ciMethod::should_print_assembly | |
922 // | |
923 // Should the compiler print the generated code for this method? | |
924 bool ciMethod::should_print_assembly() { | |
925 check_is_loaded(); | |
926 VM_ENTRY_MARK; | |
927 methodHandle mh(THREAD, get_methodOop()); | |
928 return CompilerOracle::should_print(mh); | |
929 } | |
930 | |
931 // ------------------------------------------------------------------ | |
932 // ciMethod::break_at_execute | |
933 // | |
934 // Should the compiler insert a breakpoint into the generated code | |
935 // method? | |
936 bool ciMethod::break_at_execute() { | |
937 check_is_loaded(); | |
938 VM_ENTRY_MARK; | |
939 methodHandle mh(THREAD, get_methodOop()); | |
940 return CompilerOracle::should_break_at(mh); | |
941 } | |
942 | |
943 // ------------------------------------------------------------------ | |
944 // ciMethod::has_option | |
945 // | |
946 bool ciMethod::has_option(const char* option) { | |
947 check_is_loaded(); | |
948 VM_ENTRY_MARK; | |
949 methodHandle mh(THREAD, get_methodOop()); | |
950 return CompilerOracle::has_option_string(mh, option); | |
951 } | |
952 | |
953 // ------------------------------------------------------------------ | |
954 // ciMethod::can_be_compiled | |
955 // | |
956 // Have previous compilations of this method succeeded? | |
957 bool ciMethod::can_be_compiled() { | |
958 check_is_loaded(); | |
1783 | 959 ciEnv* env = CURRENT_ENV; |
960 if (is_c1_compile(env->comp_level())) { | |
961 return _is_c1_compilable; | |
962 } | |
963 return _is_c2_compilable; | |
0 | 964 } |
965 | |
966 // ------------------------------------------------------------------ | |
967 // ciMethod::set_not_compilable | |
968 // | |
969 // Tell the VM that this method cannot be compiled at all. | |
970 void ciMethod::set_not_compilable() { | |
971 check_is_loaded(); | |
972 VM_ENTRY_MARK; | |
1783 | 973 ciEnv* env = CURRENT_ENV; |
974 if (is_c1_compile(env->comp_level())) { | |
975 _is_c1_compilable = false; | |
976 } else { | |
977 _is_c2_compilable = false; | |
978 } | |
979 get_methodOop()->set_not_compilable(env->comp_level()); | |
0 | 980 } |
981 | |
982 // ------------------------------------------------------------------ | |
983 // ciMethod::can_be_osr_compiled | |
984 // | |
985 // Have previous compilations of this method succeeded? | |
986 // | |
987 // Implementation note: the VM does not currently keep track | |
988 // of failed OSR compilations per bci. The entry_bci parameter | |
989 // is currently unused. | |
990 bool ciMethod::can_be_osr_compiled(int entry_bci) { | |
991 check_is_loaded(); | |
992 VM_ENTRY_MARK; | |
1783 | 993 ciEnv* env = CURRENT_ENV; |
994 return !get_methodOop()->is_not_osr_compilable(env->comp_level()); | |
0 | 995 } |
996 | |
997 // ------------------------------------------------------------------ | |
998 // ciMethod::has_compiled_code | |
999 bool ciMethod::has_compiled_code() { | |
1000 VM_ENTRY_MARK; | |
1001 return get_methodOop()->code() != NULL; | |
1002 } | |
1003 | |
1783 | 1004 int ciMethod::comp_level() { |
1005 check_is_loaded(); | |
1006 VM_ENTRY_MARK; | |
1007 nmethod* nm = get_methodOop()->code(); | |
1008 if (nm != NULL) return nm->comp_level(); | |
1009 return 0; | |
1010 } | |
1011 | |
0 | 1012 // ------------------------------------------------------------------ |
1013 // ciMethod::instructions_size | |
1748 | 1014 // |
1015 // This is a rough metric for "fat" methods, compared before inlining | |
1016 // with InlineSmallCode. The CodeBlob::code_size accessor includes | |
1017 // junk like exception handler, stubs, and constant table, which are | |
1018 // not highly relevant to an inlined method. So we use the more | |
1019 // specific accessor nmethod::insts_size. | |
1783 | 1020 int ciMethod::instructions_size(int comp_level) { |
0 | 1021 GUARDED_VM_ENTRY( |
1022 nmethod* code = get_methodOop()->code(); | |
1783 | 1023 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
|
1024 return code->insts_end() - code->verified_entry_point(); |
0 | 1025 } |
1783 | 1026 return 0; |
0 | 1027 ) |
1028 } | |
1029 | |
1030 // ------------------------------------------------------------------ | |
1031 // ciMethod::log_nmethod_identity | |
1032 void ciMethod::log_nmethod_identity(xmlStream* log) { | |
1033 GUARDED_VM_ENTRY( | |
1034 nmethod* code = get_methodOop()->code(); | |
1035 if (code != NULL) { | |
1036 code->log_identity(log); | |
1037 } | |
1038 ) | |
1039 } | |
1040 | |
1041 // ------------------------------------------------------------------ | |
1042 // ciMethod::is_not_reached | |
1043 bool ciMethod::is_not_reached(int bci) { | |
1044 check_is_loaded(); | |
1045 VM_ENTRY_MARK; | |
1046 return Interpreter::is_not_reached( | |
1047 methodHandle(THREAD, get_methodOop()), bci); | |
1048 } | |
1049 | |
1050 // ------------------------------------------------------------------ | |
1051 // ciMethod::was_never_executed | |
1052 bool ciMethod::was_executed_more_than(int times) { | |
1053 VM_ENTRY_MARK; | |
1054 return get_methodOop()->was_executed_more_than(times); | |
1055 } | |
1056 | |
1057 // ------------------------------------------------------------------ | |
1058 // ciMethod::has_unloaded_classes_in_signature | |
1059 bool ciMethod::has_unloaded_classes_in_signature() { | |
1060 VM_ENTRY_MARK; | |
1061 { | |
1062 EXCEPTION_MARK; | |
1063 methodHandle m(THREAD, get_methodOop()); | |
1064 bool has_unloaded = methodOopDesc::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD); | |
1065 if( HAS_PENDING_EXCEPTION ) { | |
1066 CLEAR_PENDING_EXCEPTION; | |
1067 return true; // Declare that we may have unloaded classes | |
1068 } | |
1069 return has_unloaded; | |
1070 } | |
1071 } | |
1072 | |
1073 // ------------------------------------------------------------------ | |
1074 // ciMethod::is_klass_loaded | |
1075 bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { | |
1076 VM_ENTRY_MARK; | |
1077 return get_methodOop()->is_klass_loaded(refinfo_index, must_be_resolved); | |
1078 } | |
1079 | |
1080 // ------------------------------------------------------------------ | |
1081 // ciMethod::check_call | |
1082 bool ciMethod::check_call(int refinfo_index, bool is_static) const { | |
1083 VM_ENTRY_MARK; | |
1084 { | |
1085 EXCEPTION_MARK; | |
1086 HandleMark hm(THREAD); | |
1087 constantPoolHandle pool (THREAD, get_methodOop()->constants()); | |
1088 methodHandle spec_method; | |
1089 KlassHandle spec_klass; | |
1090 LinkResolver::resolve_method(spec_method, spec_klass, pool, refinfo_index, THREAD); | |
1091 if (HAS_PENDING_EXCEPTION) { | |
1092 CLEAR_PENDING_EXCEPTION; | |
1093 return false; | |
1094 } else { | |
1095 return (spec_method->is_static() == is_static); | |
1096 } | |
1097 } | |
1098 return false; | |
1099 } | |
1100 | |
1101 // ------------------------------------------------------------------ | |
1102 // ciMethod::print_codes | |
1103 // | |
1104 // Print the bytecodes for this method. | |
1105 void ciMethod::print_codes_on(outputStream* st) { | |
1106 check_is_loaded(); | |
1107 GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(st);) | |
1108 } | |
1109 | |
1110 | |
1111 #define FETCH_FLAG_FROM_VM(flag_accessor) { \ | |
1112 check_is_loaded(); \ | |
1113 VM_ENTRY_MARK; \ | |
1114 return get_methodOop()->flag_accessor(); \ | |
1115 } | |
1116 | |
1117 bool ciMethod::is_empty_method() const { FETCH_FLAG_FROM_VM(is_empty_method); } | |
1118 bool ciMethod::is_vanilla_constructor() const { FETCH_FLAG_FROM_VM(is_vanilla_constructor); } | |
1119 bool ciMethod::has_loops () const { FETCH_FLAG_FROM_VM(has_loops); } | |
1120 bool ciMethod::has_jsrs () const { FETCH_FLAG_FROM_VM(has_jsrs); } | |
1121 bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); } | |
1122 bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); } | |
1123 | |
1124 BCEscapeAnalyzer *ciMethod::get_bcea() { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1125 #ifdef COMPILER2 |
0 | 1126 if (_bcea == NULL) { |
1127 _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL); | |
1128 } | |
1129 return _bcea; | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1130 #else // COMPILER2 |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1131 ShouldNotReachHere(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1132 return NULL; |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1579
diff
changeset
|
1133 #endif // COMPILER2 |
0 | 1134 } |
1135 | |
1136 ciMethodBlocks *ciMethod::get_method_blocks() { | |
1137 Arena *arena = CURRENT_ENV->arena(); | |
1138 if (_method_blocks == NULL) { | |
1139 _method_blocks = new (arena) ciMethodBlocks(arena, this); | |
1140 } | |
1141 return _method_blocks; | |
1142 } | |
1143 | |
1144 #undef FETCH_FLAG_FROM_VM | |
1145 | |
1146 | |
1147 // ------------------------------------------------------------------ | |
1148 // ciMethod::print_codes | |
1149 // | |
1150 // Print a range of the bytecodes for this method. | |
1151 void ciMethod::print_codes_on(int from, int to, outputStream* st) { | |
1152 check_is_loaded(); | |
1153 GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(from, to, st);) | |
1154 } | |
1155 | |
1156 // ------------------------------------------------------------------ | |
1157 // ciMethod::print_name | |
1158 // | |
1159 // Print the name of this method, including signature and some flags. | |
1160 void ciMethod::print_name(outputStream* st) { | |
1161 check_is_loaded(); | |
1162 GUARDED_VM_ENTRY(get_methodOop()->print_name(st);) | |
1163 } | |
1164 | |
1165 // ------------------------------------------------------------------ | |
1166 // ciMethod::print_short_name | |
1167 // | |
1168 // Print the name of this method, without signature. | |
1169 void ciMethod::print_short_name(outputStream* st) { | |
1170 check_is_loaded(); | |
1171 GUARDED_VM_ENTRY(get_methodOop()->print_short_name(st);) | |
1172 } | |
1173 | |
1174 // ------------------------------------------------------------------ | |
1175 // ciMethod::print_impl | |
1176 // | |
1177 // Implementation of the print method. | |
1178 void ciMethod::print_impl(outputStream* st) { | |
1179 ciObject::print_impl(st); | |
1180 st->print(" name="); | |
1181 name()->print_symbol_on(st); | |
1182 st->print(" holder="); | |
1183 holder()->print_name_on(st); | |
1184 st->print(" signature="); | |
1185 signature()->as_symbol()->print_symbol_on(st); | |
1186 if (is_loaded()) { | |
1187 st->print(" loaded=true flags="); | |
1188 flags().print_member_flags(st); | |
1189 } else { | |
1190 st->print(" loaded=false"); | |
1191 } | |
1192 } |