Index: runtime/vm/compiler.cc |
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc |
index 3972b3300fb0c256f9441fb07169b424d855b186..dccb8c12623e62930e8f9fbff95e278be2150228 100644 |
--- a/runtime/vm/compiler.cc |
+++ b/runtime/vm/compiler.cc |
@@ -16,6 +16,8 @@ |
#include "vm/dart_entry.h" |
#include "vm/debugger.h" |
#include "vm/deopt_instructions.h" |
+#include "vm/kernel.h" |
+#include "vm/kernel_to_il.h" |
#include "vm/disassembler.h" |
#include "vm/exceptions.h" |
#include "vm/flags.h" |
@@ -84,9 +86,20 @@ DECLARE_FLAG(bool, trace_irregexp); |
#ifndef DART_PRECOMPILED_RUNTIME |
+ |
+bool UseKernelFrontEndFor(ParsedFunction* parsed_function) { |
+ const Function& function = parsed_function->function(); |
+ return (function.kernel_function() != NULL) || |
+ (function.kind() == RawFunction::kNoSuchMethodDispatcher) || |
+ (function.kind() == RawFunction::kInvokeFieldDispatcher); |
+} |
+ |
+ |
void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) { |
- Parser::ParseFunction(parsed_function); |
- parsed_function->AllocateVariables(); |
+ if (!UseKernelFrontEndFor(parsed_function)) { |
+ Parser::ParseFunction(parsed_function); |
+ parsed_function->AllocateVariables(); |
+ } |
} |
@@ -95,7 +108,15 @@ FlowGraph* DartCompilationPipeline::BuildFlowGraph( |
ParsedFunction* parsed_function, |
const ZoneGrowableArray<const ICData*>& ic_data_array, |
intptr_t osr_id) { |
- // Build the flow graph. |
+ if (UseKernelFrontEndFor(parsed_function)) { |
+ kernel::TreeNode* node = static_cast<kernel::TreeNode*>( |
+ parsed_function->function().kernel_function()); |
+ kernel::FlowGraphBuilder builder( |
+ node, parsed_function, ic_data_array, NULL, osr_id); |
+ FlowGraph* graph = builder.BuildGraph(); |
+ ASSERT(graph != NULL); |
+ return graph; |
+ } |
FlowGraphBuilder builder(*parsed_function, |
ic_data_array, |
NULL, // NULL = not inlining. |
@@ -1028,7 +1049,7 @@ bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { |
// the deoptimization path. |
AllocationSinking* sinking = NULL; |
if (FLAG_allocation_sinking && |
- (flow_graph->graph_entry()->SuccessorCount() == 1)) { |
+ (flow_graph->graph_entry()->SuccessorCount() == 1)) { |
NOT_IN_PRODUCT(TimelineDurationScope tds2( |
thread(), compiler_timeline, "AllocationSinking::Optimize")); |
// TODO(fschneider): Support allocation sinking with try-catch. |
@@ -1704,11 +1725,43 @@ RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
} |
) |
- StackZone zone(thread); |
- ParsedFunction* parsed_function = |
- Parser::ParseStaticFieldInitializer(field); |
+ StackZone stack_zone(thread); |
+ Zone* zone = stack_zone.GetZone(); |
+ ParsedFunction* parsed_function; |
+ |
+ // Create a one-time-use function to evaluate the initializer and invoke |
+ // it immediately. |
+ if (field.kernel_field() != NULL) { |
+ // kImplicitStaticFinalGetter is used for both implicit static getters |
+ // and static initializers. The Kernel graph builder will tell the |
+ // difference by pattern matching on the name. |
+ const String& name = String::Handle(zone, |
+ Symbols::FromConcat(thread, |
+ Symbols::InitPrefix(), String::Handle(zone, field.name()))); |
+ const Script& script = Script::Handle(zone, field.Script()); |
+ Object& owner = Object::Handle(zone, field.Owner()); |
+ owner = PatchClass::New(Class::Cast(owner), script); |
+ const Function& function = Function::ZoneHandle(zone, |
+ Function::New(name, |
+ RawFunction::kImplicitStaticFinalGetter, |
+ true, // is_static |
+ false, // is_const |
+ false, // is_abstract |
+ false, // is_external |
+ false, // is_native |
+ owner, |
+ TokenPosition::kNoSource)); |
+ function.set_kernel_function(field.kernel_field()); |
+ function.set_result_type(AbstractType::Handle(zone, field.type())); |
+ function.set_is_reflectable(false); |
+ function.set_is_debuggable(false); |
+ function.set_is_inlinable(false); |
+ parsed_function = new(zone) ParsedFunction(thread, function); |
+ } else { |
+ parsed_function = Parser::ParseStaticFieldInitializer(field); |
+ parsed_function->AllocateVariables(); |
+ } |
- parsed_function->AllocateVariables(); |
// Non-optimized code generator. |
DartCompilationPipeline pipeline; |
CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); |
@@ -2165,6 +2218,12 @@ void BackgroundCompiler::EnsureInit(Thread* thread) { |
#else // DART_PRECOMPILED_RUNTIME |
+bool UseKernelFrontEndFor(ParsedFunction* parsed_function) { |
+ UNREACHABLE(); |
+ return false; |
+} |
+ |
+ |
CompilationPipeline* CompilationPipeline::New(Zone* zone, |
const Function& function) { |
UNREACHABLE(); |