OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/compiler.h" | 5 #include "vm/compiler.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 | 8 |
9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 | 481 |
482 // Perform register allocation on the SSA graph. | 482 // Perform register allocation on the SSA graph. |
483 FlowGraphAllocator allocator(*flow_graph); | 483 FlowGraphAllocator allocator(*flow_graph); |
484 allocator.AllocateRegisters(); | 484 allocator.AllocateRegisters(); |
485 | 485 |
486 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { | 486 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { |
487 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); | 487 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); |
488 } | 488 } |
489 } | 489 } |
490 | 490 |
491 Assembler assembler; | 491 // First, try to assemble the function using only near branches. If that |
492 FlowGraphCompiler graph_compiler(&assembler, | 492 // fails, we'll longjmp back here, set the needs_far_branches bit in the |
493 *flow_graph, | 493 // function and try again. |
494 optimized); | 494 bool assembled = false; |
495 { | 495 while (!assembled) { |
496 TimerScope timer(FLAG_compiler_stats, | 496 const intptr_t prev_deopt_id = isolate->deopt_id(); |
497 &CompilerStats::graphcompiler_timer, | 497 isolate->set_deopt_id(0); |
498 isolate); | 498 LongJump* assembler_old_base = isolate->long_jump_base(); |
499 graph_compiler.CompileGraph(); | 499 LongJump assembler_jump; |
500 } | 500 isolate->set_long_jump_base(&assembler_jump); |
501 { | 501 if (setjmp(*assembler_jump.Set()) == 0) { |
502 TimerScope timer(FLAG_compiler_stats, | 502 Assembler assembler(flow_graph->use_far_branches()); |
503 &CompilerStats::codefinalizer_timer, | 503 FlowGraphCompiler graph_compiler(&assembler, |
504 isolate); | 504 *flow_graph, |
505 const Code& code = Code::Handle( | 505 optimized); |
506 Code::FinalizeCode(function, &assembler, optimized)); | 506 { |
507 code.set_is_optimized(optimized); | 507 TimerScope timer(FLAG_compiler_stats, |
508 graph_compiler.FinalizePcDescriptors(code); | 508 &CompilerStats::graphcompiler_timer, |
509 graph_compiler.FinalizeDeoptInfo(code); | 509 isolate); |
510 graph_compiler.FinalizeStackmaps(code); | 510 graph_compiler.CompileGraph(); |
511 graph_compiler.FinalizeVarDescriptors(code); | 511 assembled = true; |
512 graph_compiler.FinalizeExceptionHandlers(code); | 512 } |
513 graph_compiler.FinalizeComments(code); | 513 { |
514 graph_compiler.FinalizeStaticCallTargetsTable(code); | 514 TimerScope timer(FLAG_compiler_stats, |
| 515 &CompilerStats::codefinalizer_timer, |
| 516 isolate); |
| 517 const Code& code = Code::Handle( |
| 518 Code::FinalizeCode(function, &assembler, optimized)); |
| 519 code.set_is_optimized(optimized); |
| 520 graph_compiler.FinalizePcDescriptors(code); |
| 521 graph_compiler.FinalizeDeoptInfo(code); |
| 522 graph_compiler.FinalizeStackmaps(code); |
| 523 graph_compiler.FinalizeVarDescriptors(code); |
| 524 graph_compiler.FinalizeExceptionHandlers(code); |
| 525 graph_compiler.FinalizeComments(code); |
| 526 graph_compiler.FinalizeStaticCallTargetsTable(code); |
515 | 527 |
516 if (optimized) { | 528 if (optimized) { |
517 if (osr_id == Isolate::kNoDeoptId) { | 529 if (osr_id == Isolate::kNoDeoptId) { |
518 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 530 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
519 if (FLAG_trace_compiler) { | 531 if (FLAG_trace_compiler) { |
520 OS::Print("--> patching entry %#"Px"\n", | 532 OS::Print("--> patching entry %#"Px"\n", |
521 Code::Handle(function.unoptimized_code()).EntryPoint()); | 533 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 534 } |
| 535 } |
| 536 function.SetCode(code); |
| 537 |
| 538 for (intptr_t i = 0; i < guarded_fields.length(); i++) { |
| 539 const Field& field = *guarded_fields[i]; |
| 540 field.RegisterDependentCode(code); |
| 541 } |
| 542 } else { |
| 543 function.set_unoptimized_code(code); |
| 544 function.SetCode(code); |
| 545 ASSERT(CodePatcher::CodeIsPatchable(code)); |
522 } | 546 } |
523 } | 547 } |
524 function.SetCode(code); | 548 is_compiled = true; |
| 549 } else { |
| 550 isolate->object_store()->clear_sticky_error(); |
525 | 551 |
526 for (intptr_t i = 0; i < guarded_fields.length(); i++) { | 552 // If far branches were enabled, assembly should not fail again. |
527 const Field& field = *guarded_fields[i]; | 553 ASSERT(!flow_graph->use_far_branches()); |
528 field.RegisterDependentCode(code); | 554 flow_graph->set_use_far_branches(true); |
529 } | 555 is_compiled = false; |
530 } else { | |
531 function.set_unoptimized_code(code); | |
532 function.SetCode(code); | |
533 ASSERT(CodePatcher::CodeIsPatchable(code)); | |
534 } | 556 } |
| 557 isolate->set_long_jump_base(assembler_old_base); |
| 558 isolate->set_deopt_id(prev_deopt_id); |
535 } | 559 } |
536 is_compiled = true; | |
537 } else { | 560 } else { |
538 // We bailed out. | 561 // We bailed out. |
539 Error& bailout_error = Error::Handle( | 562 Error& bailout_error = Error::Handle( |
540 isolate->object_store()->sticky_error()); | 563 isolate->object_store()->sticky_error()); |
541 isolate->object_store()->clear_sticky_error(); | 564 isolate->object_store()->clear_sticky_error(); |
542 if (FLAG_trace_bailout) { | 565 if (FLAG_trace_bailout) { |
543 OS::Print("%s\n", bailout_error.ToErrorCString()); | 566 OS::Print("%s\n", bailout_error.ToErrorCString()); |
544 } | 567 } |
545 // We only bail out from generating ssa code. | 568 // We only bail out from generating ssa code. |
546 ASSERT(optimized); | 569 ASSERT(optimized); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 Object::Handle(isolate->object_store()->sticky_error()); | 904 Object::Handle(isolate->object_store()->sticky_error()); |
882 isolate->object_store()->clear_sticky_error(); | 905 isolate->object_store()->clear_sticky_error(); |
883 isolate->set_long_jump_base(base); | 906 isolate->set_long_jump_base(base); |
884 return result.raw(); | 907 return result.raw(); |
885 } | 908 } |
886 UNREACHABLE(); | 909 UNREACHABLE(); |
887 return Object::null(); | 910 return Object::null(); |
888 } | 911 } |
889 | 912 |
890 } // namespace dart | 913 } // namespace dart |
OLD | NEW |