Chromium Code Reviews| Index: runtime/vm/compiler.cc |
| diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc |
| index 959dd0fd85b466dc575e7ee546f8e7145f1d403c..97530c9d8c8a70d9759d86c3bdb6138b4fadee59 100644 |
| --- a/runtime/vm/compiler.cc |
| +++ b/runtime/vm/compiler.cc |
| @@ -29,6 +29,8 @@ |
| #include "vm/object_store.h" |
| #include "vm/os.h" |
| #include "vm/parser.h" |
| +#include "vm/regexp_parser.h" |
| +#include "vm/regexp_assembler.h" |
| #include "vm/scanner.h" |
| #include "vm/symbols.h" |
| #include "vm/tags.h" |
| @@ -63,6 +65,94 @@ DEFINE_FLAG(bool, verify_compiler, false, |
| DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| DECLARE_FLAG(bool, trace_patching); |
| +DECLARE_FLAG(bool, trace_irregexp); |
| + |
| +// TODO(jgruber): Factor out unoptimizing/optimizing pipelines and remove |
| +// separate helpers functions & `optimizing` args. |
| +class CompilationPipeline : public ValueObject { |
| + public: |
| + virtual void ParseFunction(ParsedFunction* parsed_function) = 0; |
| + virtual FlowGraph* BuildFlowGraph( |
| + ParsedFunction* parsed_function, |
| + ZoneGrowableArray<const ICData*>* ic_data_array, |
| + intptr_t osr_id) = 0; |
| + virtual void CompileGraph(FlowGraphCompiler* graph_compiler) = 0; |
| + virtual ~CompilationPipeline() { } |
| +}; |
| + |
| + |
| +class StandardCompilationPipeline : public CompilationPipeline { |
|
Vyacheslav Egorov (Google)
2014/10/07 15:48:30
I would call it 'Default' or 'Dart' CompilationPip
jgruber1
2014/10/07 17:16:51
Done.
|
| + public: |
| + virtual void ParseFunction(ParsedFunction* parsed_function) { |
| + Parser::ParseFunction(parsed_function); |
| + parsed_function->AllocateVariables(); |
| + } |
| + |
| + virtual FlowGraph* BuildFlowGraph( |
| + ParsedFunction* parsed_function, |
| + ZoneGrowableArray<const ICData*>* ic_data_array, |
| + intptr_t osr_id) { |
| + // Build the flow graph. |
| + FlowGraphBuilder builder(parsed_function, |
| + *ic_data_array, |
| + NULL, // NULL = not inlining. |
| + osr_id); |
| + |
| + return builder.BuildGraph(); |
| + } |
| + |
| + virtual void CompileGraph(FlowGraphCompiler* graph_compiler) { |
|
Vyacheslav Egorov (Google)
2014/10/07 15:48:30
Given that CompileGraph is the same in both pipeli
jgruber1
2014/10/07 17:16:51
Done.
|
| + graph_compiler->CompileGraph(); |
| + } |
| +}; |
| + |
| + |
| +class IrregexpCompilationPipeline : public StandardCompilationPipeline { |
| + public: |
| + explicit IrregexpCompilationPipeline(Isolate* isolate) |
| + : macro_assembler_(NULL), |
| + isolate_(isolate) { } |
| + |
| + virtual void ParseFunction(ParsedFunction* parsed_function) { |
| + RegExpParser::ParseFunction(parsed_function); |
| + // Variables are allocated after compilation. |
| + } |
| + |
| + virtual FlowGraph* BuildFlowGraph( |
| + ParsedFunction* parsed_function, |
| + ZoneGrowableArray<const ICData*>* ic_data_array, |
| + intptr_t osr_id) { |
| + // Compile to the dart IR. |
| + RegExpEngine::CompilationResult result = |
| + RegExpEngine::Compile(parsed_function->regexp_compile_data(), |
| + parsed_function, |
| + ic_data_array); |
| + macro_assembler_ = result.macro_assembler; |
| + |
| + // Allocate variables now that we know the number of locals. |
| + parsed_function->AllocateIrregexpVariables(result.num_stack_locals); |
| + |
| + // Build the flow graph. |
| + FlowGraphBuilder builder(parsed_function, |
| + *ic_data_array, |
| + NULL, // NULL = not inlining. |
| + osr_id); |
| + |
| + return new(isolate_) FlowGraph(builder, |
| + result.graph_entry, |
| + result.num_blocks); |
| + } |
| + |
| + virtual void CompileGraph(FlowGraphCompiler* graph_compiler) { |
| + graph_compiler->CompileGraph(); |
| + macro_assembler_->FinalizeBlockOffsetTable(); |
| + } |
| + |
| + private: |
| + IRRegExpMacroAssembler* macro_assembler_; |
| + Isolate* isolate_; |
| +}; |
| + |
| // Compile a function. Should call only if the function has not been compiled. |
| // Arg0: function object. |
| @@ -264,7 +354,8 @@ RawError* Compiler::CompileClass(const Class& cls) { |
| // Return false if bailed out. |
| -static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| +static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline, |
| + ParsedFunction* parsed_function, |
| bool optimized, |
| intptr_t osr_id) { |
| const Function& function = parsed_function->function(); |
| @@ -321,12 +412,9 @@ static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| } |
| } |
| - // Build the flow graph. |
| - FlowGraphBuilder builder(parsed_function, |
| - *ic_data_array, |
| - NULL, // NULL = not inlining. |
| - osr_id); |
| - flow_graph = builder.BuildGraph(); |
| + flow_graph = pipeline->BuildFlowGraph(parsed_function, |
| + ic_data_array, |
| + osr_id); |
| } |
| if (FLAG_print_flow_graph || |
| @@ -582,7 +670,7 @@ static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| TimerScope timer(FLAG_compiler_stats, |
| &CompilerStats::graphcompiler_timer, |
| isolate); |
| - graph_compiler.CompileGraph(); |
| + pipeline->CompileGraph(&graph_compiler); |
| } |
| { |
| TimerScope timer(FLAG_compiler_stats, |
| @@ -816,7 +904,8 @@ static void DisassembleCode(const Function& function, bool optimized) { |
| } |
| -static RawError* CompileFunctionHelper(const Function& function, |
| +static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
| + const Function& function, |
| bool optimized, |
| intptr_t osr_id) { |
| Isolate* isolate = Isolate::Current(); |
| @@ -838,12 +927,13 @@ static RawError* CompileFunctionHelper(const Function& function, |
| } |
| { |
| HANDLESCOPE(isolate); |
| - Parser::ParseFunction(parsed_function); |
| - parsed_function->AllocateVariables(); |
| + pipeline->ParseFunction(parsed_function); |
| } |
| - const bool success = |
| - CompileParsedFunctionHelper(parsed_function, optimized, osr_id); |
| + const bool success = CompileParsedFunctionHelper(pipeline, |
| + parsed_function, |
| + optimized, |
| + osr_id); |
| if (!success) { |
| if (optimized) { |
| // Optimizer bailed out. Disable optimizations and to never try again. |
| @@ -897,7 +987,15 @@ static RawError* CompileFunctionHelper(const Function& function, |
| RawError* Compiler::CompileFunction(Isolate* isolate, |
| const Function& function) { |
| VMTagScope tagScope(isolate, VMTag::kCompileUnoptimizedTagId); |
| - return CompileFunctionHelper(function, false, Isolate::kNoDeoptId); |
| + if (function.IsIrregexpFunction()) { |
| + IrregexpCompilationPipeline pipeline(isolate); |
| + return CompileFunctionHelper( |
| + &pipeline, function, false, Isolate::kNoDeoptId); |
| + } else { |
| + StandardCompilationPipeline pipeline; |
| + return CompileFunctionHelper( |
| + &pipeline, function, false, Isolate::kNoDeoptId); |
| + } |
| } |
| @@ -905,7 +1003,13 @@ RawError* Compiler::CompileOptimizedFunction(Isolate* isolate, |
| const Function& function, |
| intptr_t osr_id) { |
| VMTagScope tagScope(isolate, VMTag::kCompileOptimizedTagId); |
| - return CompileFunctionHelper(function, true, osr_id); |
| + if (function.IsIrregexpFunction()) { |
| + IrregexpCompilationPipeline pipeline(isolate); |
| + return CompileFunctionHelper(&pipeline, function, true, osr_id); |
| + } else { |
| + StandardCompilationPipeline pipeline; |
| + return CompileFunctionHelper(&pipeline, function, true, osr_id); |
| + } |
| } |
| @@ -916,7 +1020,11 @@ RawError* Compiler::CompileParsedFunction( |
| LongJumpScope jump; |
| if (setjmp(*jump.Set()) == 0) { |
| // Non-optimized code generator. |
| - CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |
| + StandardCompilationPipeline pipeline; |
| + CompileParsedFunctionHelper(&pipeline, |
| + parsed_function, |
| + false, |
| + Isolate::kNoDeoptId); |
| if (FLAG_disassemble) { |
| DisassembleCode(parsed_function->function(), false); |
| } |
| @@ -993,7 +1101,11 @@ RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| parsed_function->AllocateVariables(); |
| // Non-optimized code generator. |
| - CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |
| + StandardCompilationPipeline pipeline; |
| + CompileParsedFunctionHelper(&pipeline, |
| + parsed_function, |
| + false, |
| + Isolate::kNoDeoptId); |
| // Invoke the function to evaluate the expression. |
| const Function& initializer = parsed_function->function(); |
| @@ -1053,7 +1165,11 @@ RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| parsed_function->AllocateVariables(); |
| // Non-optimized code generator. |
| - CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |
| + StandardCompilationPipeline pipeline; |
| + CompileParsedFunctionHelper(&pipeline, |
| + parsed_function, |
| + false, |
| + Isolate::kNoDeoptId); |
| const Object& result = PassiveObject::Handle( |
| DartEntry::InvokeFunction(func, Object::empty_array())); |