Mercurial > hg > graal-jvmci-8
annotate src/share/vm/c1/c1_Compilation.cpp @ 3249:e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes
author | johnc |
---|---|
date | Thu, 07 Apr 2011 09:53:20 -0700 |
parents | 72d6c57d0658 |
children | c124e2e7463e |
rev | line source |
---|---|
0 | 1 /* |
2252 | 2 * Copyright (c) 1999, 2011, 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 | |
2098
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
248 bool Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) { |
1584 | 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 |
2098
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
256 int stub_size = (call_stub_estimate * LIR_Assembler::call_stub_size) + |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
257 LIR_Assembler::exception_handler_size + |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
258 (2 * LIR_Assembler::deopt_handler_size); |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
259 if (stub_size >= code->insts_capacity()) return false; |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
260 code->initialize_stubs_size(stub_size); |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
261 return true; |
1584 | 262 } |
263 | |
264 | |
0 | 265 int Compilation::emit_code_body() { |
266 // emit code | |
2098
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
267 if (!setup_code_buffer(code(), allocator()->num_calls())) { |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
268 BAILOUT_("size requested greater than avail code buffer size", 0); |
2f9d59b0fa5c
7009268: guarantee(middle - slop > start) failed: need enough space to divide up
bobv
parents:
2007
diff
changeset
|
269 } |
0 | 270 code()->initialize_oop_recorder(env()->oop_recorder()); |
271 | |
272 _masm = new C1_MacroAssembler(code()); | |
273 _masm->set_oop_recorder(env()->oop_recorder()); | |
274 | |
275 LIR_Assembler lir_asm(this); | |
276 | |
277 lir_asm.emit_code(hir()->code()); | |
278 CHECK_BAILOUT_(0); | |
279 | |
280 emit_code_epilog(&lir_asm); | |
281 CHECK_BAILOUT_(0); | |
282 | |
283 generate_exception_handler_table(); | |
284 | |
285 #ifndef PRODUCT | |
286 if (PrintExceptionHandlers && Verbose) { | |
287 exception_handler_table()->print(); | |
288 } | |
289 #endif /* PRODUCT */ | |
290 | |
291 return frame_map()->framesize(); | |
292 } | |
293 | |
294 | |
295 int Compilation::compile_java_method() { | |
296 assert(!method()->is_native(), "should not reach here"); | |
297 | |
298 if (BailoutOnExceptionHandlers) { | |
299 if (method()->has_exception_handlers()) { | |
300 bailout("linear scan can't handle exception handlers"); | |
301 } | |
302 } | |
303 | |
304 CHECK_BAILOUT_(no_frame_size); | |
305 | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
306 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
|
307 BAILOUT_("mdo allocation failed", no_frame_size); |
1783 | 308 } |
309 | |
0 | 310 { |
311 PhaseTraceTime timeit(_t_buildIR); | |
1783 | 312 build_hir(); |
0 | 313 } |
314 if (BailoutAfterHIR) { | |
315 BAILOUT_("Bailing out because of -XX:+BailoutAfterHIR", no_frame_size); | |
316 } | |
317 | |
318 | |
319 { | |
320 PhaseTraceTime timeit(_t_emit_lir); | |
321 | |
322 _frame_map = new FrameMap(method(), hir()->number_of_locks(), MAX2(4, hir()->max_stack())); | |
323 emit_lir(); | |
324 } | |
325 CHECK_BAILOUT_(no_frame_size); | |
326 | |
327 { | |
328 PhaseTraceTime timeit(_t_codeemit); | |
329 return emit_code_body(); | |
330 } | |
331 } | |
332 | |
333 void Compilation::install_code(int frame_size) { | |
334 // frame_size is in 32-bit words so adjust it intptr_t words | |
335 assert(frame_size == frame_map()->framesize(), "must match"); | |
336 assert(in_bytes(frame_map()->framesize_in_bytes()) % sizeof(intptr_t) == 0, "must be at least pointer aligned"); | |
337 _env->register_method( | |
338 method(), | |
339 osr_bci(), | |
340 &_offsets, | |
341 in_bytes(_frame_map->sp_offset_for_orig_pc()), | |
342 code(), | |
343 in_bytes(frame_map()->framesize_in_bytes()) / sizeof(intptr_t), | |
344 debug_info_recorder()->_oopmaps, | |
345 exception_handler_table(), | |
346 implicit_exception_table(), | |
347 compiler(), | |
348 _env->comp_level(), | |
1397
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1378
diff
changeset
|
349 true, |
0 | 350 has_unsafe_access() |
351 ); | |
352 } | |
353 | |
354 | |
355 void Compilation::compile_method() { | |
356 // setup compilation | |
357 initialize(); | |
358 | |
359 if (!method()->can_be_compiled()) { | |
360 // Prevent race condition 6328518. | |
361 // This can happen if the method is obsolete or breakpointed. | |
362 bailout("Bailing out because method is not compilable"); | |
363 return; | |
364 } | |
365 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
0
diff
changeset
|
366 if (_env->jvmti_can_hotswap_or_post_breakpoint()) { |
0 | 367 // We can assert evol_method because method->can_be_compiled is true. |
368 dependency_recorder()->assert_evol_method(method()); | |
369 } | |
370 | |
371 if (method()->break_at_execute()) { | |
372 BREAKPOINT; | |
373 } | |
374 | |
375 #ifndef PRODUCT | |
376 if (PrintCFGToFile) { | |
377 CFGPrinter::print_compilation(this); | |
378 } | |
379 #endif | |
380 | |
381 // compile method | |
382 int frame_size = compile_java_method(); | |
383 | |
384 // bailout if method couldn't be compiled | |
385 // Note: make sure we mark the method as not compilable! | |
386 CHECK_BAILOUT(); | |
387 | |
388 if (InstallMethods) { | |
389 // install code | |
390 PhaseTraceTime timeit(_t_codeinstall); | |
391 install_code(frame_size); | |
392 } | |
393 totalInstructionNodes += Instruction::number_of_instructions(); | |
394 } | |
395 | |
396 | |
397 void Compilation::generate_exception_handler_table() { | |
398 // Generate an ExceptionHandlerTable from the exception handler | |
399 // information accumulated during the compilation. | |
400 ExceptionInfoList* info_list = exception_info_list(); | |
401 | |
402 if (info_list->length() == 0) { | |
403 return; | |
404 } | |
405 | |
406 // allocate some arrays for use by the collection code. | |
407 const int num_handlers = 5; | |
408 GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t>(num_handlers); | |
409 GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t>(num_handlers); | |
410 GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t>(num_handlers); | |
411 | |
412 for (int i = 0; i < info_list->length(); i++) { | |
413 ExceptionInfo* info = info_list->at(i); | |
414 XHandlers* handlers = info->exception_handlers(); | |
415 | |
416 // empty the arrays | |
417 bcis->trunc_to(0); | |
418 scope_depths->trunc_to(0); | |
419 pcos->trunc_to(0); | |
420 | |
421 for (int i = 0; i < handlers->length(); i++) { | |
422 XHandler* handler = handlers->handler_at(i); | |
423 assert(handler->entry_pco() != -1, "must have been generated"); | |
424 | |
425 int e = bcis->find(handler->handler_bci()); | |
426 if (e >= 0 && scope_depths->at(e) == handler->scope_count()) { | |
427 // two different handlers are declared to dispatch to the same | |
428 // catch bci. During parsing we created edges for each | |
429 // handler but we really only need one. The exception handler | |
430 // table will also get unhappy if we try to declare both since | |
431 // it's nonsensical. Just skip this handler. | |
432 continue; | |
433 } | |
434 | |
435 bcis->append(handler->handler_bci()); | |
436 if (handler->handler_bci() == -1) { | |
437 // insert a wildcard handler at scope depth 0 so that the | |
438 // exception lookup logic with find it. | |
439 scope_depths->append(0); | |
440 } else { | |
441 scope_depths->append(handler->scope_count()); | |
442 } | |
443 pcos->append(handler->entry_pco()); | |
444 | |
445 // stop processing once we hit a catch any | |
446 if (handler->is_catch_all()) { | |
447 assert(i == handlers->length() - 1, "catch all must be last handler"); | |
448 } | |
449 } | |
450 exception_handler_table()->add_subtable(info->pco(), bcis, scope_depths, pcos); | |
451 } | |
452 } | |
453 | |
454 | |
1584 | 455 Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method, |
456 int osr_bci, BufferBlob* buffer_blob) | |
0 | 457 : _compiler(compiler) |
458 , _env(env) | |
459 , _method(method) | |
460 , _osr_bci(osr_bci) | |
461 , _hir(NULL) | |
462 , _max_spills(-1) | |
463 , _frame_map(NULL) | |
464 , _masm(NULL) | |
465 , _has_exception_handlers(false) | |
466 , _has_fpu_code(true) // pessimistic assumption | |
1783 | 467 , _would_profile(false) |
0 | 468 , _has_unsafe_access(false) |
1691
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1617
diff
changeset
|
469 , _has_method_handle_invokes(false) |
0 | 470 , _bailout_msg(NULL) |
471 , _exception_info_list(NULL) | |
472 , _allocator(NULL) | |
1584 | 473 , _next_id(0) |
474 , _next_block_id(0) | |
1748 | 475 , _code(buffer_blob) |
0 | 476 , _current_instruction(NULL) |
477 #ifndef PRODUCT | |
478 , _last_instruction_printed(NULL) | |
479 #endif // PRODUCT | |
480 { | |
481 PhaseTraceTime timeit(_t_compile); | |
482 _arena = Thread::current()->resource_area(); | |
1584 | 483 _env->set_compiler_data(this); |
0 | 484 _exception_info_list = new ExceptionInfoList(); |
485 _implicit_exception_table.set_size(0); | |
486 compile_method(); | |
1964
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
487 if (bailed_out()) { |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
488 _env->record_method_not_compilable(bailout_msg(), !TieredCompilation); |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
489 if (is_profiling()) { |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
490 // Compilation failed, create MDO, which would signal the interpreter |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
491 // 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
|
492 _method->ensure_method_data(); |
1964
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
493 } |
2252 | 494 } else if (is_profiling()) { |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
495 ciMethodData *md = method->method_data_or_null(); |
2252 | 496 if (md != NULL) { |
497 md->set_would_profile(_would_profile); | |
498 } | |
1783 | 499 } |
0 | 500 } |
501 | |
502 Compilation::~Compilation() { | |
1584 | 503 _env->set_compiler_data(NULL); |
0 | 504 } |
505 | |
506 | |
507 void Compilation::add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers) { | |
508 #ifndef PRODUCT | |
509 if (PrintExceptionHandlers && Verbose) { | |
510 tty->print_cr(" added exception scope for pco %d", pco); | |
511 } | |
512 #endif | |
513 // Note: we do not have program counters for these exception handlers yet | |
514 exception_info_list()->push(new ExceptionInfo(pco, exception_handlers)); | |
515 } | |
516 | |
517 | |
518 void Compilation::notice_inlined_method(ciMethod* method) { | |
519 _env->notice_inlined_method(method); | |
520 } | |
521 | |
522 | |
523 void Compilation::bailout(const char* msg) { | |
524 assert(msg != NULL, "bailout message must exist"); | |
525 if (!bailed_out()) { | |
526 // keep first bailout message | |
527 if (PrintBailouts) tty->print_cr("compilation bailout: %s", msg); | |
528 _bailout_msg = msg; | |
529 } | |
530 } | |
531 | |
532 | |
533 void Compilation::print_timers() { | |
534 // 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); | |
535 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(); | |
536 | |
537 | |
538 tty->print_cr(" Detailed C1 Timings"); | |
539 tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); | |
540 tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); | |
541 tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(), (timers[_t_optimizeIR].seconds() / total) * 100.0); | |
542 tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); | |
543 tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); | |
544 tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); | |
545 NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); | |
546 tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0); | |
547 tty->print_cr(" Code Emission: %6.3f s (%4.1f%%)", timers[_t_codeemit].seconds(), (timers[_t_codeemit].seconds() / total) * 100.0); | |
548 tty->print_cr(" Code Installation: %6.3f s (%4.1f%%)", timers[_t_codeinstall].seconds(), (timers[_t_codeinstall].seconds() / total) * 100.0); | |
549 tty->print_cr(" Instruction Nodes: %6d nodes", totalInstructionNodes); | |
550 | |
551 NOT_PRODUCT(LinearScan::print_statistics()); | |
552 } | |
553 | |
554 | |
555 #ifndef PRODUCT | |
556 void Compilation::compile_only_this_method() { | |
557 ResourceMark rm; | |
558 fileStream stream(fopen("c1_compile_only", "wt")); | |
559 stream.print_cr("# c1 compile only directives"); | |
560 compile_only_this_scope(&stream, hir()->top_scope()); | |
561 } | |
562 | |
563 | |
564 void Compilation::compile_only_this_scope(outputStream* st, IRScope* scope) { | |
565 st->print("CompileOnly="); | |
566 scope->method()->holder()->name()->print_symbol_on(st); | |
567 st->print("."); | |
568 scope->method()->name()->print_symbol_on(st); | |
569 st->cr(); | |
570 } | |
571 | |
572 | |
573 void Compilation::exclude_this_method() { | |
574 fileStream stream(fopen(".hotspot_compiler", "at")); | |
575 stream.print("exclude "); | |
576 method()->holder()->name()->print_symbol_on(&stream); | |
577 stream.print(" "); | |
578 method()->name()->print_symbol_on(&stream); | |
579 stream.cr(); | |
580 stream.cr(); | |
581 } | |
582 #endif |