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())); |