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 |