Mercurial > hg > truffle
annotate src/share/vm/c1/c1_Compilation.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 | 2f9d59b0fa5c |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
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:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
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:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_CFGPrinter.hpp" | |
27 #include "c1/c1_Compilation.hpp" | |
28 #include "c1/c1_IR.hpp" | |
29 #include "c1/c1_LIRAssembler.hpp" | |
30 #include "c1/c1_LinearScan.hpp" | |
31 #include "c1/c1_MacroAssembler.hpp" | |
32 #include "c1/c1_ValueMap.hpp" | |
33 #include "c1/c1_ValueStack.hpp" | |
34 #include "code/debugInfoRec.hpp" | |
0 | 35 |
36 | |
37 typedef enum { | |
38 _t_compile, | |
39 _t_setup, | |
40 _t_optimizeIR, | |
41 _t_buildIR, | |
42 _t_emit_lir, | |
43 _t_linearScan, | |
44 _t_lirGeneration, | |
45 _t_lir_schedule, | |
46 _t_codeemit, | |
47 _t_codeinstall, | |
48 max_phase_timers | |
49 } TimerName; | |
50 | |
51 static const char * timer_name[] = { | |
52 "compile", | |
53 "setup", | |
54 "optimizeIR", | |
55 "buildIR", | |
56 "emit_lir", | |
57 "linearScan", | |
58 "lirGeneration", | |
59 "lir_schedule", | |
60 "codeemit", | |
61 "codeinstall" | |
62 }; | |
63 | |
64 static elapsedTimer timers[max_phase_timers]; | |
65 static int totalInstructionNodes = 0; | |
66 | |
67 class PhaseTraceTime: public TraceTime { | |
68 private: | |
69 JavaThread* _thread; | |
70 | |
71 public: | |
72 PhaseTraceTime(TimerName timer): | |
73 TraceTime("", &timers[timer], CITime || CITimeEach, Verbose) { | |
74 } | |
75 }; | |
76 | |
77 // Implementation of Compilation | |
78 | |
79 | |
80 #ifndef PRODUCT | |
81 | |
82 void Compilation::maybe_print_current_instruction() { | |
83 if (_current_instruction != NULL && _last_instruction_printed != _current_instruction) { | |
84 _last_instruction_printed = _current_instruction; | |
85 _current_instruction->print_line(); | |
86 } | |
87 } | |
88 #endif // PRODUCT | |
89 | |
90 | |
91 DebugInformationRecorder* Compilation::debug_info_recorder() const { | |
92 return _env->debug_info(); | |
93 } | |
94 | |
95 | |
96 Dependencies* Compilation::dependency_recorder() const { | |
97 return _env->dependencies(); | |
98 } | |
99 | |
100 | |
101 void Compilation::initialize() { | |
102 // Use an oop recorder bound to the CI environment. | |
103 // (The default oop recorder is ignorant of the CI.) | |
104 OopRecorder* ooprec = new OopRecorder(_env->arena()); | |
105 _env->set_oop_recorder(ooprec); | |
106 _env->set_debug_info(new DebugInformationRecorder(ooprec)); | |
107 debug_info_recorder()->set_oopmaps(new OopMapSet()); | |
108 _env->set_dependencies(new Dependencies(_env)); | |
109 } | |
110 | |
111 | |
112 void Compilation::build_hir() { | |
113 CHECK_BAILOUT(); | |
114 | |
115 // setup ir | |
116 _hir = new IR(this, method(), osr_bci()); | |
117 if (!_hir->is_valid()) { | |
118 bailout("invalid parsing"); | |
119 return; | |
120 } | |
121 | |
122 #ifndef PRODUCT | |
123 if (PrintCFGToFile) { | |
124 CFGPrinter::print_cfg(_hir, "After Generation of HIR", true, false); | |
125 } | |
126 #endif | |
127 | |
128 #ifndef PRODUCT | |
129 if (PrintCFG || PrintCFG0) { tty->print_cr("CFG after parsing"); _hir->print(true); } | |
130 if (PrintIR || PrintIR0 ) { tty->print_cr("IR after parsing"); _hir->print(false); } | |
131 #endif | |
132 | |
133 _hir->verify(); | |
134 | |
135 if (UseC1Optimizations) { | |
136 NEEDS_CLEANUP | |
137 // optimization | |
138 PhaseTraceTime timeit(_t_optimizeIR); | |
139 | |
140 _hir->optimize(); | |
141 } | |
142 | |
143 _hir->verify(); | |
144 | |
145 _hir->split_critical_edges(); | |
146 | |
147 #ifndef PRODUCT | |
148 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after optimizations"); _hir->print(true); } | |
149 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after optimizations"); _hir->print(false); } | |
150 #endif | |
151 | |
152 _hir->verify(); | |
153 | |
154 // compute block ordering for code generation | |
155 // the control flow must not be changed from here on | |
156 _hir->compute_code(); | |
157 | |
158 if (UseGlobalValueNumbering) { | |
159 ResourceMark rm; | |
160 int instructions = Instruction::number_of_instructions(); | |
161 GlobalValueNumbering gvn(_hir); | |
162 assert(instructions == Instruction::number_of_instructions(), | |
163 "shouldn't have created an instructions"); | |
164 } | |
165 | |
166 // compute use counts after global value numbering | |
167 _hir->compute_use_counts(); | |
168 | |
169 #ifndef PRODUCT | |
170 if (PrintCFG || PrintCFG2) { tty->print_cr("CFG before code generation"); _hir->code()->print(true); } | |
171 if (PrintIR || PrintIR2 ) { tty->print_cr("IR before code generation"); _hir->code()->print(false, true); } | |
172 #endif | |
173 | |
174 _hir->verify(); | |
175 } | |
176 | |
177 | |
178 void Compilation::emit_lir() { | |
179 CHECK_BAILOUT(); | |
180 | |
181 LIRGenerator gen(this, method()); | |
182 { | |
183 PhaseTraceTime timeit(_t_lirGeneration); | |
184 hir()->iterate_linear_scan_order(&gen); | |
185 } | |
186 | |
187 CHECK_BAILOUT(); | |
188 | |
189 { | |
190 PhaseTraceTime timeit(_t_linearScan); | |
191 | |
192 LinearScan* allocator = new LinearScan(hir(), &gen, frame_map()); | |
193 set_allocator(allocator); | |
194 // Assign physical registers to LIR operands using a linear scan algorithm. | |
195 allocator->do_linear_scan(); | |
196 CHECK_BAILOUT(); | |
197 | |
198 _max_spills = allocator->max_spills(); | |
199 } | |
200 | |
201 if (BailoutAfterLIR) { | |
202 if (PrintLIR && !bailed_out()) { | |
203 print_LIR(hir()->code()); | |
204 } | |
205 bailout("Bailing out because of -XX:+BailoutAfterLIR"); | |
206 } | |
207 } | |
208 | |
209 | |
210 void Compilation::emit_code_epilog(LIR_Assembler* assembler) { | |
211 CHECK_BAILOUT(); | |
212 | |
1204 | 213 CodeOffsets* code_offsets = assembler->offsets(); |
214 | |
0 | 215 // generate code or slow cases |
216 assembler->emit_slow_case_stubs(); | |
217 CHECK_BAILOUT(); | |
218 | |
219 // generate exception adapters | |
220 assembler->emit_exception_entries(exception_info_list()); | |
221 CHECK_BAILOUT(); | |
222 | |
1204 | 223 // Generate code for exception handler. |
224 code_offsets->set_value(CodeOffsets::Exceptions, assembler->emit_exception_handler()); | |
0 | 225 CHECK_BAILOUT(); |
1204 | 226 |
227 // Generate code for deopt handler. | |
228 code_offsets->set_value(CodeOffsets::Deopt, assembler->emit_deopt_handler()); | |
229 CHECK_BAILOUT(); | |
230 | |
1691
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
231 // Emit the MethodHandle deopt handler code (if required). |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
232 if (has_method_handle_invokes()) { |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
233 // We can use the same code as for the normal deopt handler, we |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
234 // just need a different entry point address. |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
235 code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler()); |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
236 CHECK_BAILOUT(); |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
237 } |
0 | 238 |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
239 // Emit the handler to remove the activation from the stack and |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
240 // dispatch to the caller. |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
241 offsets()->set_value(CodeOffsets::UnwindHandler, assembler->emit_unwind_handler()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
242 |
0 | 243 // done |
244 masm()->flush(); | |
245 } | |
246 | |
247 | |
1584 | 248 void Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) { |
249 // Preinitialize the consts section to some large size: | |
250 int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo)); | |
251 char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size); | |
252 code->insts()->initialize_shared_locs((relocInfo*)locs_buffer, | |
253 locs_buffer_size / sizeof(relocInfo)); | |
254 code->initialize_consts_size(Compilation::desired_max_constant_size()); | |
1617
9887b5e57f9e
6962980: C1: stub area should take into account method handle deopt stub
iveresov
parents:
1584
diff
changeset
|
255 // Call stubs + two deopt handlers (regular and MH) + exception handler |
1584 | 256 code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) + |
257 LIR_Assembler::exception_handler_size + | |
1617
9887b5e57f9e
6962980: C1: stub area should take into account method handle deopt stub
iveresov
parents:
1584
diff
changeset
|
258 2 * LIR_Assembler::deopt_handler_size); |
1584 | 259 } |
260 | |
261 | |
0 | 262 int Compilation::emit_code_body() { |
263 // emit code | |
1584 | 264 setup_code_buffer(code(), allocator()->num_calls()); |
0 | 265 code()->initialize_oop_recorder(env()->oop_recorder()); |
266 | |
267 _masm = new C1_MacroAssembler(code()); | |
268 _masm->set_oop_recorder(env()->oop_recorder()); | |
269 | |
270 LIR_Assembler lir_asm(this); | |
271 | |
272 lir_asm.emit_code(hir()->code()); | |
273 CHECK_BAILOUT_(0); | |
274 | |
275 emit_code_epilog(&lir_asm); | |
276 CHECK_BAILOUT_(0); | |
277 | |
278 generate_exception_handler_table(); | |
279 | |
280 #ifndef PRODUCT | |
281 if (PrintExceptionHandlers && Verbose) { | |
282 exception_handler_table()->print(); | |
283 } | |
284 #endif /* PRODUCT */ | |
285 | |
286 return frame_map()->framesize(); | |
287 } | |
288 | |
289 | |
290 int Compilation::compile_java_method() { | |
291 assert(!method()->is_native(), "should not reach here"); | |
292 | |
293 if (BailoutOnExceptionHandlers) { | |
294 if (method()->has_exception_handlers()) { | |
295 bailout("linear scan can't handle exception handlers"); | |
296 } | |
297 } | |
298 | |
299 CHECK_BAILOUT_(no_frame_size); | |
300 | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
301 if (is_profiling() && !method()->ensure_method_data()) { |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
302 BAILOUT_("mdo allocation failed", no_frame_size); |
1783 | 303 } |
304 | |
0 | 305 { |
306 PhaseTraceTime timeit(_t_buildIR); | |
1783 | 307 build_hir(); |
0 | 308 } |
309 if (BailoutAfterHIR) { | |
310 BAILOUT_("Bailing out because of -XX:+BailoutAfterHIR", no_frame_size); | |
311 } | |
312 | |
313 | |
314 { | |
315 PhaseTraceTime timeit(_t_emit_lir); | |
316 | |
317 _frame_map = new FrameMap(method(), hir()->number_of_locks(), MAX2(4, hir()->max_stack())); | |
318 emit_lir(); | |
319 } | |
320 CHECK_BAILOUT_(no_frame_size); | |
321 | |
322 { | |
323 PhaseTraceTime timeit(_t_codeemit); | |
324 return emit_code_body(); | |
325 } | |
326 } | |
327 | |
328 void Compilation::install_code(int frame_size) { | |
329 // frame_size is in 32-bit words so adjust it intptr_t words | |
330 assert(frame_size == frame_map()->framesize(), "must match"); | |
331 assert(in_bytes(frame_map()->framesize_in_bytes()) % sizeof(intptr_t) == 0, "must be at least pointer aligned"); | |
332 _env->register_method( | |
333 method(), | |
334 osr_bci(), | |
335 &_offsets, | |
336 in_bytes(_frame_map->sp_offset_for_orig_pc()), | |
337 code(), | |
338 in_bytes(frame_map()->framesize_in_bytes()) / sizeof(intptr_t), | |
339 debug_info_recorder()->_oopmaps, | |
340 exception_handler_table(), | |
341 implicit_exception_table(), | |
342 compiler(), | |
343 _env->comp_level(), | |
1397
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1378
diff
changeset
|
344 true, |
0 | 345 has_unsafe_access() |
346 ); | |
347 } | |
348 | |
349 | |
350 void Compilation::compile_method() { | |
351 // setup compilation | |
352 initialize(); | |
353 | |
354 if (!method()->can_be_compiled()) { | |
355 // Prevent race condition 6328518. | |
356 // This can happen if the method is obsolete or breakpointed. | |
357 bailout("Bailing out because method is not compilable"); | |
358 return; | |
359 } | |
360 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
0
diff
changeset
|
361 if (_env->jvmti_can_hotswap_or_post_breakpoint()) { |
0 | 362 // We can assert evol_method because method->can_be_compiled is true. |
363 dependency_recorder()->assert_evol_method(method()); | |
364 } | |
365 | |
366 if (method()->break_at_execute()) { | |
367 BREAKPOINT; | |
368 } | |
369 | |
370 #ifndef PRODUCT | |
371 if (PrintCFGToFile) { | |
372 CFGPrinter::print_compilation(this); | |
373 } | |
374 #endif | |
375 | |
376 // compile method | |
377 int frame_size = compile_java_method(); | |
378 | |
379 // bailout if method couldn't be compiled | |
380 // Note: make sure we mark the method as not compilable! | |
381 CHECK_BAILOUT(); | |
382 | |
383 if (InstallMethods) { | |
384 // install code | |
385 PhaseTraceTime timeit(_t_codeinstall); | |
386 install_code(frame_size); | |
387 } | |
388 totalInstructionNodes += Instruction::number_of_instructions(); | |
389 } | |
390 | |
391 | |
392 void Compilation::generate_exception_handler_table() { | |
393 // Generate an ExceptionHandlerTable from the exception handler | |
394 // information accumulated during the compilation. | |
395 ExceptionInfoList* info_list = exception_info_list(); | |
396 | |
397 if (info_list->length() == 0) { | |
398 return; | |
399 } | |
400 | |
401 // allocate some arrays for use by the collection code. | |
402 const int num_handlers = 5; | |
403 GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t>(num_handlers); | |
404 GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t>(num_handlers); | |
405 GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t>(num_handlers); | |
406 | |
407 for (int i = 0; i < info_list->length(); i++) { | |
408 ExceptionInfo* info = info_list->at(i); | |
409 XHandlers* handlers = info->exception_handlers(); | |
410 | |
411 // empty the arrays | |
412 bcis->trunc_to(0); | |
413 scope_depths->trunc_to(0); | |
414 pcos->trunc_to(0); | |
415 | |
416 for (int i = 0; i < handlers->length(); i++) { | |
417 XHandler* handler = handlers->handler_at(i); | |
418 assert(handler->entry_pco() != -1, "must have been generated"); | |
419 | |
420 int e = bcis->find(handler->handler_bci()); | |
421 if (e >= 0 && scope_depths->at(e) == handler->scope_count()) { | |
422 // two different handlers are declared to dispatch to the same | |
423 // catch bci. During parsing we created edges for each | |
424 // handler but we really only need one. The exception handler | |
425 // table will also get unhappy if we try to declare both since | |
426 // it's nonsensical. Just skip this handler. | |
427 continue; | |
428 } | |
429 | |
430 bcis->append(handler->handler_bci()); | |
431 if (handler->handler_bci() == -1) { | |
432 // insert a wildcard handler at scope depth 0 so that the | |
433 // exception lookup logic with find it. | |
434 scope_depths->append(0); | |
435 } else { | |
436 scope_depths->append(handler->scope_count()); | |
437 } | |
438 pcos->append(handler->entry_pco()); | |
439 | |
440 // stop processing once we hit a catch any | |
441 if (handler->is_catch_all()) { | |
442 assert(i == handlers->length() - 1, "catch all must be last handler"); | |
443 } | |
444 } | |
445 exception_handler_table()->add_subtable(info->pco(), bcis, scope_depths, pcos); | |
446 } | |
447 } | |
448 | |
449 | |
1584 | 450 Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method, |
451 int osr_bci, BufferBlob* buffer_blob) | |
0 | 452 : _compiler(compiler) |
453 , _env(env) | |
454 , _method(method) | |
455 , _osr_bci(osr_bci) | |
456 , _hir(NULL) | |
457 , _max_spills(-1) | |
458 , _frame_map(NULL) | |
459 , _masm(NULL) | |
460 , _has_exception_handlers(false) | |
461 , _has_fpu_code(true) // pessimistic assumption | |
1783 | 462 , _would_profile(false) |
0 | 463 , _has_unsafe_access(false) |
1691
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
464 , _has_method_handle_invokes(false) |
0 | 465 , _bailout_msg(NULL) |
466 , _exception_info_list(NULL) | |
467 , _allocator(NULL) | |
1584 | 468 , _next_id(0) |
469 , _next_block_id(0) | |
1748 | 470 , _code(buffer_blob) |
0 | 471 , _current_instruction(NULL) |
472 #ifndef PRODUCT | |
473 , _last_instruction_printed(NULL) | |
474 #endif // PRODUCT | |
475 { | |
476 PhaseTraceTime timeit(_t_compile); | |
477 _arena = Thread::current()->resource_area(); | |
1584 | 478 _env->set_compiler_data(this); |
0 | 479 _exception_info_list = new ExceptionInfoList(); |
480 _implicit_exception_table.set_size(0); | |
481 compile_method(); | |
1964
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
482 if (bailed_out()) { |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
483 _env->record_method_not_compilable(bailout_msg(), !TieredCompilation); |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
484 if (is_profiling()) { |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
485 // Compilation failed, create MDO, which would signal the interpreter |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
486 // to start profiling on its own. |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
487 _method->ensure_method_data(); |
1964
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
488 } |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
489 } else if (is_profiling() && _would_profile) { |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
490 ciMethodData *md = method->method_data_or_null(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
491 assert(md != NULL, "Sanity"); |
1783 | 492 md->set_would_profile(_would_profile); |
493 } | |
0 | 494 } |
495 | |
496 Compilation::~Compilation() { | |
1584 | 497 _env->set_compiler_data(NULL); |
0 | 498 } |
499 | |
500 | |
501 void Compilation::add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers) { | |
502 #ifndef PRODUCT | |
503 if (PrintExceptionHandlers && Verbose) { | |
504 tty->print_cr(" added exception scope for pco %d", pco); | |
505 } | |
506 #endif | |
507 // Note: we do not have program counters for these exception handlers yet | |
508 exception_info_list()->push(new ExceptionInfo(pco, exception_handlers)); | |
509 } | |
510 | |
511 | |
512 void Compilation::notice_inlined_method(ciMethod* method) { | |
513 _env->notice_inlined_method(method); | |
514 } | |
515 | |
516 | |
517 void Compilation::bailout(const char* msg) { | |
518 assert(msg != NULL, "bailout message must exist"); | |
519 if (!bailed_out()) { | |
520 // keep first bailout message | |
521 if (PrintBailouts) tty->print_cr("compilation bailout: %s", msg); | |
522 _bailout_msg = msg; | |
523 } | |
524 } | |
525 | |
526 | |
527 void Compilation::print_timers() { | |
528 // tty->print_cr(" Native methods : %6.3f s, Average : %2.3f", CompileBroker::_t_native_compilation.seconds(), CompileBroker::_t_native_compilation.seconds() / CompileBroker::_total_native_compile_count); | |
529 float total = timers[_t_setup].seconds() + timers[_t_buildIR].seconds() + timers[_t_emit_lir].seconds() + timers[_t_lir_schedule].seconds() + timers[_t_codeemit].seconds() + timers[_t_codeinstall].seconds(); | |
530 | |
531 | |
532 tty->print_cr(" Detailed C1 Timings"); | |
533 tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); | |
534 tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); | |
535 tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(), (timers[_t_optimizeIR].seconds() / total) * 100.0); | |
536 tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); | |
537 tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); | |
538 tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); | |
539 NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); | |
540 tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0); | |
541 tty->print_cr(" Code Emission: %6.3f s (%4.1f%%)", timers[_t_codeemit].seconds(), (timers[_t_codeemit].seconds() / total) * 100.0); | |
542 tty->print_cr(" Code Installation: %6.3f s (%4.1f%%)", timers[_t_codeinstall].seconds(), (timers[_t_codeinstall].seconds() / total) * 100.0); | |
543 tty->print_cr(" Instruction Nodes: %6d nodes", totalInstructionNodes); | |
544 | |
545 NOT_PRODUCT(LinearScan::print_statistics()); | |
546 } | |
547 | |
548 | |
549 #ifndef PRODUCT | |
550 void Compilation::compile_only_this_method() { | |
551 ResourceMark rm; | |
552 fileStream stream(fopen("c1_compile_only", "wt")); | |
553 stream.print_cr("# c1 compile only directives"); | |
554 compile_only_this_scope(&stream, hir()->top_scope()); | |
555 } | |
556 | |
557 | |
558 void Compilation::compile_only_this_scope(outputStream* st, IRScope* scope) { | |
559 st->print("CompileOnly="); | |
560 scope->method()->holder()->name()->print_symbol_on(st); | |
561 st->print("."); | |
562 scope->method()->name()->print_symbol_on(st); | |
563 st->cr(); | |
564 } | |
565 | |
566 | |
567 void Compilation::exclude_this_method() { | |
568 fileStream stream(fopen(".hotspot_compiler", "at")); | |
569 stream.print("exclude "); | |
570 method()->holder()->name()->print_symbol_on(&stream); | |
571 stream.print(" "); | |
572 method()->name()->print_symbol_on(&stream); | |
573 stream.cr(); | |
574 stream.cr(); | |
575 } | |
576 #endif |