| 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/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "vm/flow_graph_compiler.h" | 22 #include "vm/flow_graph_compiler.h" |
| 23 #include "vm/flow_graph_inliner.h" | 23 #include "vm/flow_graph_inliner.h" |
| 24 #include "vm/flow_graph_optimizer.h" | 24 #include "vm/flow_graph_optimizer.h" |
| 25 #include "vm/flow_graph_type_propagator.h" | 25 #include "vm/flow_graph_type_propagator.h" |
| 26 #include "vm/il_printer.h" | 26 #include "vm/il_printer.h" |
| 27 #include "vm/longjump.h" | 27 #include "vm/longjump.h" |
| 28 #include "vm/object.h" | 28 #include "vm/object.h" |
| 29 #include "vm/object_store.h" | 29 #include "vm/object_store.h" |
| 30 #include "vm/os.h" | 30 #include "vm/os.h" |
| 31 #include "vm/parser.h" | 31 #include "vm/parser.h" |
| 32 #include "vm/regexp_parser.h" |
| 33 #include "vm/regexp_assembler.h" |
| 32 #include "vm/scanner.h" | 34 #include "vm/scanner.h" |
| 33 #include "vm/symbols.h" | 35 #include "vm/symbols.h" |
| 34 #include "vm/tags.h" | 36 #include "vm/tags.h" |
| 35 #include "vm/timer.h" | 37 #include "vm/timer.h" |
| 36 | 38 |
| 37 namespace dart { | 39 namespace dart { |
| 38 | 40 |
| 39 DEFINE_FLAG(bool, allocation_sinking, true, | 41 DEFINE_FLAG(bool, allocation_sinking, true, |
| 40 "Attempt to sink temporary allocations to side exits"); | 42 "Attempt to sink temporary allocations to side exits"); |
| 41 DEFINE_FLAG(bool, common_subexpression_elimination, true, | 43 DEFINE_FLAG(bool, common_subexpression_elimination, true, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 56 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); | 58 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); |
| 57 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); | 59 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); |
| 58 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); | 60 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); |
| 59 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); | 61 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); |
| 60 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); | 62 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); |
| 61 DEFINE_FLAG(bool, verify_compiler, false, | 63 DEFINE_FLAG(bool, verify_compiler, false, |
| 62 "Enable compiler verification assertions"); | 64 "Enable compiler verification assertions"); |
| 63 | 65 |
| 64 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 66 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| 65 DECLARE_FLAG(bool, trace_patching); | 67 DECLARE_FLAG(bool, trace_patching); |
| 68 DECLARE_FLAG(bool, trace_irregexp); |
| 66 | 69 |
| 67 // Compile a function. Should call only if the function has not been compiled. | 70 // Compile a function. Should call only if the function has not been compiled. |
| 68 // Arg0: function object. | 71 // Arg0: function object. |
| 69 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { | 72 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { |
| 70 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 73 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 71 ASSERT(!function.HasCode()); | 74 ASSERT(!function.HasCode()); |
| 72 const Error& error = Error::Handle(Compiler::CompileFunction(isolate, | 75 const Error& error = Error::Handle(Compiler::CompileFunction(isolate, |
| 73 function)); | 76 function)); |
| 74 if (!error.IsNull()) { | 77 if (!error.IsNull()) { |
| 75 Exceptions::PropagateError(error); | 78 Exceptions::PropagateError(error); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 const intptr_t prev_deopt_id = isolate->deopt_id(); | 292 const intptr_t prev_deopt_id = isolate->deopt_id(); |
| 290 isolate->set_deopt_id(0); | 293 isolate->set_deopt_id(0); |
| 291 LongJumpScope jump; | 294 LongJumpScope jump; |
| 292 if (setjmp(*jump.Set()) == 0) { | 295 if (setjmp(*jump.Set()) == 0) { |
| 293 FlowGraph* flow_graph = NULL; | 296 FlowGraph* flow_graph = NULL; |
| 294 | 297 |
| 295 // Class hierarchy analysis is registered with the isolate in the | 298 // Class hierarchy analysis is registered with the isolate in the |
| 296 // constructor and unregisters itself upon destruction. | 299 // constructor and unregisters itself upon destruction. |
| 297 CHA cha(isolate); | 300 CHA cha(isolate); |
| 298 | 301 |
| 302 IRRegExpMacroAssembler* macro_assembler = NULL; |
| 303 |
| 299 // TimerScope needs an isolate to be properly terminated in case of a | 304 // TimerScope needs an isolate to be properly terminated in case of a |
| 300 // LongJump. | 305 // LongJump. |
| 301 { | 306 { |
| 302 TimerScope timer(FLAG_compiler_stats, | 307 TimerScope timer(FLAG_compiler_stats, |
| 303 &CompilerStats::graphbuilder_timer, | 308 &CompilerStats::graphbuilder_timer, |
| 304 isolate); | 309 isolate); |
| 305 ZoneGrowableArray<const ICData*>* ic_data_array = | 310 ZoneGrowableArray<const ICData*>* ic_data_array = |
| 306 new(isolate) ZoneGrowableArray<const ICData*>(); | 311 new(isolate) ZoneGrowableArray<const ICData*>(); |
| 307 if (optimized) { | 312 if (optimized) { |
| 308 ASSERT(function.HasCode()); | 313 ASSERT(function.HasCode()); |
| 309 // Extract type feedback before the graph is built, as the graph | 314 // Extract type feedback before the graph is built, as the graph |
| 310 // builder uses it to attach it to nodes. | 315 // builder uses it to attach it to nodes. |
| 311 ASSERT(function.deoptimization_counter() < | 316 ASSERT(function.deoptimization_counter() < |
| 312 FLAG_deoptimization_counter_threshold); | 317 FLAG_deoptimization_counter_threshold); |
| 313 function.RestoreICDataMap(ic_data_array); | 318 function.RestoreICDataMap(ic_data_array); |
| 314 if (FLAG_print_ic_data_map) { | 319 if (FLAG_print_ic_data_map) { |
| 315 for (intptr_t i = 0; i < ic_data_array->length(); i++) { | 320 for (intptr_t i = 0; i < ic_data_array->length(); i++) { |
| 316 if ((*ic_data_array)[i] != NULL) { | 321 if ((*ic_data_array)[i] != NULL) { |
| 317 OS::Print("%" Pd " ", i); | 322 OS::Print("%" Pd " ", i); |
| 318 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); | 323 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); |
| 319 } | 324 } |
| 320 } | 325 } |
| 321 } | 326 } |
| 322 } | 327 } |
| 323 | 328 |
| 324 // Build the flow graph. | 329 if (function.IsIrregexpFunction()) { |
| 325 FlowGraphBuilder builder(parsed_function, | 330 // Compile to the dart IR. |
| 326 *ic_data_array, | 331 RegExpEngine::CompilationResult result = |
| 327 NULL, // NULL = not inlining. | 332 RegExpEngine::Compile(parsed_function->regexp_compile_data(), |
| 328 osr_id); | 333 parsed_function, |
| 329 flow_graph = builder.BuildGraph(); | 334 ic_data_array); |
| 335 macro_assembler = result.macro_assembler; |
| 336 |
| 337 // Allocate variables now that we know the number of locals. |
| 338 parsed_function->AllocateIrregexpVariables(result.num_stack_locals); |
| 339 |
| 340 // Build the flow graph. |
| 341 FlowGraphBuilder builder(parsed_function, |
| 342 *ic_data_array, |
| 343 NULL, // NULL = not inlining. |
| 344 osr_id); |
| 345 |
| 346 flow_graph = new(isolate) FlowGraph(builder, |
| 347 result.graph_entry, |
| 348 result.num_blocks); |
| 349 } else { |
| 350 // Build the flow graph. |
| 351 FlowGraphBuilder builder(parsed_function, |
| 352 *ic_data_array, |
| 353 NULL, // NULL = not inlining. |
| 354 osr_id); |
| 355 |
| 356 flow_graph = builder.BuildGraph(); |
| 357 } |
| 330 } | 358 } |
| 331 | 359 |
| 332 if (FLAG_print_flow_graph || | 360 if (FLAG_print_flow_graph || |
| 333 (optimized && FLAG_print_flow_graph_optimized)) { | 361 (optimized && FLAG_print_flow_graph_optimized)) { |
| 334 if (osr_id == Isolate::kNoDeoptId) { | 362 if (osr_id == Isolate::kNoDeoptId) { |
| 335 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); | 363 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); |
| 336 } else { | 364 } else { |
| 337 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); | 365 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); |
| 338 } | 366 } |
| 339 } | 367 } |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 } | 604 } |
| 577 } | 605 } |
| 578 | 606 |
| 579 Assembler assembler(use_far_branches); | 607 Assembler assembler(use_far_branches); |
| 580 FlowGraphCompiler graph_compiler(&assembler, flow_graph, optimized); | 608 FlowGraphCompiler graph_compiler(&assembler, flow_graph, optimized); |
| 581 { | 609 { |
| 582 TimerScope timer(FLAG_compiler_stats, | 610 TimerScope timer(FLAG_compiler_stats, |
| 583 &CompilerStats::graphcompiler_timer, | 611 &CompilerStats::graphcompiler_timer, |
| 584 isolate); | 612 isolate); |
| 585 graph_compiler.CompileGraph(); | 613 graph_compiler.CompileGraph(); |
| 614 if (function.IsIrregexpFunction()) { |
| 615 macro_assembler->FinalizeBlockOffsetTable(); |
| 616 } |
| 586 } | 617 } |
| 587 { | 618 { |
| 588 TimerScope timer(FLAG_compiler_stats, | 619 TimerScope timer(FLAG_compiler_stats, |
| 589 &CompilerStats::codefinalizer_timer, | 620 &CompilerStats::codefinalizer_timer, |
| 590 isolate); | 621 isolate); |
| 591 const Code& code = Code::Handle( | 622 const Code& code = Code::Handle( |
| 592 Code::FinalizeCode(function, &assembler, optimized)); | 623 Code::FinalizeCode(function, &assembler, optimized)); |
| 593 code.set_is_optimized(optimized); | 624 code.set_is_optimized(optimized); |
| 594 graph_compiler.FinalizePcDescriptors(code); | 625 graph_compiler.FinalizePcDescriptors(code); |
| 595 graph_compiler.FinalizeDeoptInfo(code); | 626 graph_compiler.FinalizeDeoptInfo(code); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 if (FLAG_trace_compiler) { | 853 if (FLAG_trace_compiler) { |
| 823 OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 854 OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
| 824 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), | 855 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), |
| 825 (optimized ? "optimized " : ""), | 856 (optimized ? "optimized " : ""), |
| 826 function.ToFullyQualifiedCString(), | 857 function.ToFullyQualifiedCString(), |
| 827 function.token_pos(), | 858 function.token_pos(), |
| 828 (function.end_token_pos() - function.token_pos())); | 859 (function.end_token_pos() - function.token_pos())); |
| 829 } | 860 } |
| 830 { | 861 { |
| 831 HANDLESCOPE(isolate); | 862 HANDLESCOPE(isolate); |
| 832 Parser::ParseFunction(parsed_function); | 863 |
| 833 parsed_function->AllocateVariables(); | 864 if (function.IsIrregexpFunction()) { |
| 865 RegExpParser::ParseFunction(parsed_function); |
| 866 // Variables are allocated after compilation. |
| 867 } else { |
| 868 Parser::ParseFunction(parsed_function); |
| 869 parsed_function->AllocateVariables(); |
| 870 } |
| 834 } | 871 } |
| 835 | 872 |
| 836 const bool success = | 873 const bool success = |
| 837 CompileParsedFunctionHelper(parsed_function, optimized, osr_id); | 874 CompileParsedFunctionHelper(parsed_function, optimized, osr_id); |
| 838 if (!success) { | 875 if (!success) { |
| 839 if (optimized) { | 876 if (optimized) { |
| 840 // Optimizer bailed out. Disable optimizations and to never try again. | 877 // Optimizer bailed out. Disable optimizations and to never try again. |
| 841 if (FLAG_trace_compiler) { | 878 if (FLAG_trace_compiler) { |
| 842 OS::Print("--> disabling optimizations for '%s'\n", | 879 OS::Print("--> disabling optimizations for '%s'\n", |
| 843 function.ToFullyQualifiedCString()); | 880 function.ToFullyQualifiedCString()); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 const Object& result = | 1090 const Object& result = |
| 1054 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1091 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
| 1055 isolate->object_store()->clear_sticky_error(); | 1092 isolate->object_store()->clear_sticky_error(); |
| 1056 return result.raw(); | 1093 return result.raw(); |
| 1057 } | 1094 } |
| 1058 UNREACHABLE(); | 1095 UNREACHABLE(); |
| 1059 return Object::null(); | 1096 return Object::null(); |
| 1060 } | 1097 } |
| 1061 | 1098 |
| 1062 } // namespace dart | 1099 } // namespace dart |
| OLD | NEW |