1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/c1/c1_Compilation.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,526 @@ 1.4 +/* 1.5 + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "incls/_precompiled.incl" 1.29 +#include "incls/_c1_Compilation.cpp.incl" 1.30 + 1.31 + 1.32 +typedef enum { 1.33 + _t_compile, 1.34 + _t_setup, 1.35 + _t_optimizeIR, 1.36 + _t_buildIR, 1.37 + _t_emit_lir, 1.38 + _t_linearScan, 1.39 + _t_lirGeneration, 1.40 + _t_lir_schedule, 1.41 + _t_codeemit, 1.42 + _t_codeinstall, 1.43 + max_phase_timers 1.44 +} TimerName; 1.45 + 1.46 +static const char * timer_name[] = { 1.47 + "compile", 1.48 + "setup", 1.49 + "optimizeIR", 1.50 + "buildIR", 1.51 + "emit_lir", 1.52 + "linearScan", 1.53 + "lirGeneration", 1.54 + "lir_schedule", 1.55 + "codeemit", 1.56 + "codeinstall" 1.57 +}; 1.58 + 1.59 +static elapsedTimer timers[max_phase_timers]; 1.60 +static int totalInstructionNodes = 0; 1.61 + 1.62 +class PhaseTraceTime: public TraceTime { 1.63 + private: 1.64 + JavaThread* _thread; 1.65 + 1.66 + public: 1.67 + PhaseTraceTime(TimerName timer): 1.68 + TraceTime("", &timers[timer], CITime || CITimeEach, Verbose) { 1.69 + } 1.70 +}; 1.71 + 1.72 +Arena* Compilation::_arena = NULL; 1.73 +Compilation* Compilation::_compilation = NULL; 1.74 + 1.75 +// Implementation of Compilation 1.76 + 1.77 + 1.78 +#ifndef PRODUCT 1.79 + 1.80 +void Compilation::maybe_print_current_instruction() { 1.81 + if (_current_instruction != NULL && _last_instruction_printed != _current_instruction) { 1.82 + _last_instruction_printed = _current_instruction; 1.83 + _current_instruction->print_line(); 1.84 + } 1.85 +} 1.86 +#endif // PRODUCT 1.87 + 1.88 + 1.89 +DebugInformationRecorder* Compilation::debug_info_recorder() const { 1.90 + return _env->debug_info(); 1.91 +} 1.92 + 1.93 + 1.94 +Dependencies* Compilation::dependency_recorder() const { 1.95 + return _env->dependencies(); 1.96 +} 1.97 + 1.98 + 1.99 +void Compilation::initialize() { 1.100 + // Use an oop recorder bound to the CI environment. 1.101 + // (The default oop recorder is ignorant of the CI.) 1.102 + OopRecorder* ooprec = new OopRecorder(_env->arena()); 1.103 + _env->set_oop_recorder(ooprec); 1.104 + _env->set_debug_info(new DebugInformationRecorder(ooprec)); 1.105 + debug_info_recorder()->set_oopmaps(new OopMapSet()); 1.106 + _env->set_dependencies(new Dependencies(_env)); 1.107 +} 1.108 + 1.109 + 1.110 +void Compilation::build_hir() { 1.111 + CHECK_BAILOUT(); 1.112 + 1.113 + // setup ir 1.114 + _hir = new IR(this, method(), osr_bci()); 1.115 + if (!_hir->is_valid()) { 1.116 + bailout("invalid parsing"); 1.117 + return; 1.118 + } 1.119 + 1.120 +#ifndef PRODUCT 1.121 + if (PrintCFGToFile) { 1.122 + CFGPrinter::print_cfg(_hir, "After Generation of HIR", true, false); 1.123 + } 1.124 +#endif 1.125 + 1.126 +#ifndef PRODUCT 1.127 + if (PrintCFG || PrintCFG0) { tty->print_cr("CFG after parsing"); _hir->print(true); } 1.128 + if (PrintIR || PrintIR0 ) { tty->print_cr("IR after parsing"); _hir->print(false); } 1.129 +#endif 1.130 + 1.131 + _hir->verify(); 1.132 + 1.133 + if (UseC1Optimizations) { 1.134 + NEEDS_CLEANUP 1.135 + // optimization 1.136 + PhaseTraceTime timeit(_t_optimizeIR); 1.137 + 1.138 + _hir->optimize(); 1.139 + } 1.140 + 1.141 + _hir->verify(); 1.142 + 1.143 + _hir->split_critical_edges(); 1.144 + 1.145 +#ifndef PRODUCT 1.146 + if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after optimizations"); _hir->print(true); } 1.147 + if (PrintIR || PrintIR1 ) { tty->print_cr("IR after optimizations"); _hir->print(false); } 1.148 +#endif 1.149 + 1.150 + _hir->verify(); 1.151 + 1.152 + // compute block ordering for code generation 1.153 + // the control flow must not be changed from here on 1.154 + _hir->compute_code(); 1.155 + 1.156 + if (UseGlobalValueNumbering) { 1.157 + ResourceMark rm; 1.158 + int instructions = Instruction::number_of_instructions(); 1.159 + GlobalValueNumbering gvn(_hir); 1.160 + assert(instructions == Instruction::number_of_instructions(), 1.161 + "shouldn't have created an instructions"); 1.162 + } 1.163 + 1.164 + // compute use counts after global value numbering 1.165 + _hir->compute_use_counts(); 1.166 + 1.167 +#ifndef PRODUCT 1.168 + if (PrintCFG || PrintCFG2) { tty->print_cr("CFG before code generation"); _hir->code()->print(true); } 1.169 + if (PrintIR || PrintIR2 ) { tty->print_cr("IR before code generation"); _hir->code()->print(false, true); } 1.170 +#endif 1.171 + 1.172 + _hir->verify(); 1.173 +} 1.174 + 1.175 + 1.176 +void Compilation::emit_lir() { 1.177 + CHECK_BAILOUT(); 1.178 + 1.179 + LIRGenerator gen(this, method()); 1.180 + { 1.181 + PhaseTraceTime timeit(_t_lirGeneration); 1.182 + hir()->iterate_linear_scan_order(&gen); 1.183 + } 1.184 + 1.185 + CHECK_BAILOUT(); 1.186 + 1.187 + { 1.188 + PhaseTraceTime timeit(_t_linearScan); 1.189 + 1.190 + LinearScan* allocator = new LinearScan(hir(), &gen, frame_map()); 1.191 + set_allocator(allocator); 1.192 + // Assign physical registers to LIR operands using a linear scan algorithm. 1.193 + allocator->do_linear_scan(); 1.194 + CHECK_BAILOUT(); 1.195 + 1.196 + _max_spills = allocator->max_spills(); 1.197 + } 1.198 + 1.199 + if (BailoutAfterLIR) { 1.200 + if (PrintLIR && !bailed_out()) { 1.201 + print_LIR(hir()->code()); 1.202 + } 1.203 + bailout("Bailing out because of -XX:+BailoutAfterLIR"); 1.204 + } 1.205 +} 1.206 + 1.207 + 1.208 +void Compilation::emit_code_epilog(LIR_Assembler* assembler) { 1.209 + CHECK_BAILOUT(); 1.210 + 1.211 + // generate code or slow cases 1.212 + assembler->emit_slow_case_stubs(); 1.213 + CHECK_BAILOUT(); 1.214 + 1.215 + // generate exception adapters 1.216 + assembler->emit_exception_entries(exception_info_list()); 1.217 + CHECK_BAILOUT(); 1.218 + 1.219 + // generate code for exception handler 1.220 + assembler->emit_exception_handler(); 1.221 + CHECK_BAILOUT(); 1.222 + assembler->emit_deopt_handler(); 1.223 + CHECK_BAILOUT(); 1.224 + 1.225 + // done 1.226 + masm()->flush(); 1.227 +} 1.228 + 1.229 + 1.230 +int Compilation::emit_code_body() { 1.231 + // emit code 1.232 + Runtime1::setup_code_buffer(code(), allocator()->num_calls()); 1.233 + code()->initialize_oop_recorder(env()->oop_recorder()); 1.234 + 1.235 + _masm = new C1_MacroAssembler(code()); 1.236 + _masm->set_oop_recorder(env()->oop_recorder()); 1.237 + 1.238 + LIR_Assembler lir_asm(this); 1.239 + 1.240 + lir_asm.emit_code(hir()->code()); 1.241 + CHECK_BAILOUT_(0); 1.242 + 1.243 + emit_code_epilog(&lir_asm); 1.244 + CHECK_BAILOUT_(0); 1.245 + 1.246 + generate_exception_handler_table(); 1.247 + 1.248 +#ifndef PRODUCT 1.249 + if (PrintExceptionHandlers && Verbose) { 1.250 + exception_handler_table()->print(); 1.251 + } 1.252 +#endif /* PRODUCT */ 1.253 + 1.254 + return frame_map()->framesize(); 1.255 +} 1.256 + 1.257 + 1.258 +int Compilation::compile_java_method() { 1.259 + assert(!method()->is_native(), "should not reach here"); 1.260 + 1.261 + if (BailoutOnExceptionHandlers) { 1.262 + if (method()->has_exception_handlers()) { 1.263 + bailout("linear scan can't handle exception handlers"); 1.264 + } 1.265 + } 1.266 + 1.267 + CHECK_BAILOUT_(no_frame_size); 1.268 + 1.269 + { 1.270 + PhaseTraceTime timeit(_t_buildIR); 1.271 + build_hir(); 1.272 + } 1.273 + if (BailoutAfterHIR) { 1.274 + BAILOUT_("Bailing out because of -XX:+BailoutAfterHIR", no_frame_size); 1.275 + } 1.276 + 1.277 + 1.278 + { 1.279 + PhaseTraceTime timeit(_t_emit_lir); 1.280 + 1.281 + _frame_map = new FrameMap(method(), hir()->number_of_locks(), MAX2(4, hir()->max_stack())); 1.282 + emit_lir(); 1.283 + } 1.284 + CHECK_BAILOUT_(no_frame_size); 1.285 + 1.286 + { 1.287 + PhaseTraceTime timeit(_t_codeemit); 1.288 + return emit_code_body(); 1.289 + } 1.290 +} 1.291 + 1.292 +void Compilation::install_code(int frame_size) { 1.293 + // frame_size is in 32-bit words so adjust it intptr_t words 1.294 + assert(frame_size == frame_map()->framesize(), "must match"); 1.295 + assert(in_bytes(frame_map()->framesize_in_bytes()) % sizeof(intptr_t) == 0, "must be at least pointer aligned"); 1.296 + _env->register_method( 1.297 + method(), 1.298 + osr_bci(), 1.299 + &_offsets, 1.300 + in_bytes(_frame_map->sp_offset_for_orig_pc()), 1.301 + code(), 1.302 + in_bytes(frame_map()->framesize_in_bytes()) / sizeof(intptr_t), 1.303 + debug_info_recorder()->_oopmaps, 1.304 + exception_handler_table(), 1.305 + implicit_exception_table(), 1.306 + compiler(), 1.307 + _env->comp_level(), 1.308 + needs_debug_information(), 1.309 + has_unsafe_access() 1.310 + ); 1.311 +} 1.312 + 1.313 + 1.314 +void Compilation::compile_method() { 1.315 + // setup compilation 1.316 + initialize(); 1.317 + 1.318 + if (!method()->can_be_compiled()) { 1.319 + // Prevent race condition 6328518. 1.320 + // This can happen if the method is obsolete or breakpointed. 1.321 + bailout("Bailing out because method is not compilable"); 1.322 + return; 1.323 + } 1.324 + 1.325 + if (JvmtiExport::can_hotswap_or_post_breakpoint()) { 1.326 + // We can assert evol_method because method->can_be_compiled is true. 1.327 + dependency_recorder()->assert_evol_method(method()); 1.328 + } 1.329 + 1.330 + if (method()->break_at_execute()) { 1.331 + BREAKPOINT; 1.332 + } 1.333 + 1.334 +#ifndef PRODUCT 1.335 + if (PrintCFGToFile) { 1.336 + CFGPrinter::print_compilation(this); 1.337 + } 1.338 +#endif 1.339 + 1.340 + // compile method 1.341 + int frame_size = compile_java_method(); 1.342 + 1.343 + // bailout if method couldn't be compiled 1.344 + // Note: make sure we mark the method as not compilable! 1.345 + CHECK_BAILOUT(); 1.346 + 1.347 + if (InstallMethods) { 1.348 + // install code 1.349 + PhaseTraceTime timeit(_t_codeinstall); 1.350 + install_code(frame_size); 1.351 + } 1.352 + totalInstructionNodes += Instruction::number_of_instructions(); 1.353 +} 1.354 + 1.355 + 1.356 +void Compilation::generate_exception_handler_table() { 1.357 + // Generate an ExceptionHandlerTable from the exception handler 1.358 + // information accumulated during the compilation. 1.359 + ExceptionInfoList* info_list = exception_info_list(); 1.360 + 1.361 + if (info_list->length() == 0) { 1.362 + return; 1.363 + } 1.364 + 1.365 + // allocate some arrays for use by the collection code. 1.366 + const int num_handlers = 5; 1.367 + GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t>(num_handlers); 1.368 + GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t>(num_handlers); 1.369 + GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t>(num_handlers); 1.370 + 1.371 + for (int i = 0; i < info_list->length(); i++) { 1.372 + ExceptionInfo* info = info_list->at(i); 1.373 + XHandlers* handlers = info->exception_handlers(); 1.374 + 1.375 + // empty the arrays 1.376 + bcis->trunc_to(0); 1.377 + scope_depths->trunc_to(0); 1.378 + pcos->trunc_to(0); 1.379 + 1.380 + for (int i = 0; i < handlers->length(); i++) { 1.381 + XHandler* handler = handlers->handler_at(i); 1.382 + assert(handler->entry_pco() != -1, "must have been generated"); 1.383 + 1.384 + int e = bcis->find(handler->handler_bci()); 1.385 + if (e >= 0 && scope_depths->at(e) == handler->scope_count()) { 1.386 + // two different handlers are declared to dispatch to the same 1.387 + // catch bci. During parsing we created edges for each 1.388 + // handler but we really only need one. The exception handler 1.389 + // table will also get unhappy if we try to declare both since 1.390 + // it's nonsensical. Just skip this handler. 1.391 + continue; 1.392 + } 1.393 + 1.394 + bcis->append(handler->handler_bci()); 1.395 + if (handler->handler_bci() == -1) { 1.396 + // insert a wildcard handler at scope depth 0 so that the 1.397 + // exception lookup logic with find it. 1.398 + scope_depths->append(0); 1.399 + } else { 1.400 + scope_depths->append(handler->scope_count()); 1.401 + } 1.402 + pcos->append(handler->entry_pco()); 1.403 + 1.404 + // stop processing once we hit a catch any 1.405 + if (handler->is_catch_all()) { 1.406 + assert(i == handlers->length() - 1, "catch all must be last handler"); 1.407 + } 1.408 + } 1.409 + exception_handler_table()->add_subtable(info->pco(), bcis, scope_depths, pcos); 1.410 + } 1.411 +} 1.412 + 1.413 + 1.414 +Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method, int osr_bci) 1.415 +: _compiler(compiler) 1.416 +, _env(env) 1.417 +, _method(method) 1.418 +, _osr_bci(osr_bci) 1.419 +, _hir(NULL) 1.420 +, _max_spills(-1) 1.421 +, _frame_map(NULL) 1.422 +, _masm(NULL) 1.423 +, _has_exception_handlers(false) 1.424 +, _has_fpu_code(true) // pessimistic assumption 1.425 +, _has_unsafe_access(false) 1.426 +, _bailout_msg(NULL) 1.427 +, _exception_info_list(NULL) 1.428 +, _allocator(NULL) 1.429 +, _code(Runtime1::get_buffer_blob()->instructions_begin(), 1.430 + Runtime1::get_buffer_blob()->instructions_size()) 1.431 +, _current_instruction(NULL) 1.432 +#ifndef PRODUCT 1.433 +, _last_instruction_printed(NULL) 1.434 +#endif // PRODUCT 1.435 +{ 1.436 + PhaseTraceTime timeit(_t_compile); 1.437 + 1.438 + assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time"); 1.439 + _arena = Thread::current()->resource_area(); 1.440 + _compilation = this; 1.441 + _needs_debug_information = JvmtiExport::can_examine_or_deopt_anywhere() || 1.442 + JavaMonitorsInStackTrace || AlwaysEmitDebugInfo || DeoptimizeALot; 1.443 + _exception_info_list = new ExceptionInfoList(); 1.444 + _implicit_exception_table.set_size(0); 1.445 + compile_method(); 1.446 +} 1.447 + 1.448 +Compilation::~Compilation() { 1.449 + _arena = NULL; 1.450 + _compilation = NULL; 1.451 +} 1.452 + 1.453 + 1.454 +void Compilation::add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers) { 1.455 +#ifndef PRODUCT 1.456 + if (PrintExceptionHandlers && Verbose) { 1.457 + tty->print_cr(" added exception scope for pco %d", pco); 1.458 + } 1.459 +#endif 1.460 + // Note: we do not have program counters for these exception handlers yet 1.461 + exception_info_list()->push(new ExceptionInfo(pco, exception_handlers)); 1.462 +} 1.463 + 1.464 + 1.465 +void Compilation::notice_inlined_method(ciMethod* method) { 1.466 + _env->notice_inlined_method(method); 1.467 +} 1.468 + 1.469 + 1.470 +void Compilation::bailout(const char* msg) { 1.471 + assert(msg != NULL, "bailout message must exist"); 1.472 + if (!bailed_out()) { 1.473 + // keep first bailout message 1.474 + if (PrintBailouts) tty->print_cr("compilation bailout: %s", msg); 1.475 + _bailout_msg = msg; 1.476 + } 1.477 +} 1.478 + 1.479 + 1.480 +void Compilation::print_timers() { 1.481 + // 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); 1.482 + 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(); 1.483 + 1.484 + 1.485 + tty->print_cr(" Detailed C1 Timings"); 1.486 + tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); 1.487 + tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); 1.488 + tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(), (timers[_t_optimizeIR].seconds() / total) * 100.0); 1.489 + tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); 1.490 + tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); 1.491 + tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); 1.492 + NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); 1.493 + tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0); 1.494 + tty->print_cr(" Code Emission: %6.3f s (%4.1f%%)", timers[_t_codeemit].seconds(), (timers[_t_codeemit].seconds() / total) * 100.0); 1.495 + tty->print_cr(" Code Installation: %6.3f s (%4.1f%%)", timers[_t_codeinstall].seconds(), (timers[_t_codeinstall].seconds() / total) * 100.0); 1.496 + tty->print_cr(" Instruction Nodes: %6d nodes", totalInstructionNodes); 1.497 + 1.498 + NOT_PRODUCT(LinearScan::print_statistics()); 1.499 +} 1.500 + 1.501 + 1.502 +#ifndef PRODUCT 1.503 +void Compilation::compile_only_this_method() { 1.504 + ResourceMark rm; 1.505 + fileStream stream(fopen("c1_compile_only", "wt")); 1.506 + stream.print_cr("# c1 compile only directives"); 1.507 + compile_only_this_scope(&stream, hir()->top_scope()); 1.508 +} 1.509 + 1.510 + 1.511 +void Compilation::compile_only_this_scope(outputStream* st, IRScope* scope) { 1.512 + st->print("CompileOnly="); 1.513 + scope->method()->holder()->name()->print_symbol_on(st); 1.514 + st->print("."); 1.515 + scope->method()->name()->print_symbol_on(st); 1.516 + st->cr(); 1.517 +} 1.518 + 1.519 + 1.520 +void Compilation::exclude_this_method() { 1.521 + fileStream stream(fopen(".hotspot_compiler", "at")); 1.522 + stream.print("exclude "); 1.523 + method()->holder()->name()->print_symbol_on(&stream); 1.524 + stream.print(" "); 1.525 + method()->name()->print_symbol_on(&stream); 1.526 + stream.cr(); 1.527 + stream.cr(); 1.528 +} 1.529 +#endif