Chromium Code Reviews| Index: runtime/vm/compiler.cc |
| diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc |
| index 93898adc5c69c5b7c51ea6b17078374d2fa7096a..730a26ab3e2234df18aaa745b3acdfe3181e7028 100644 |
| --- a/runtime/vm/compiler.cc |
| +++ b/runtime/vm/compiler.cc |
| @@ -1374,6 +1374,63 @@ static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
| } |
| +static RawError* ParseFunctionHelper(CompilationPipeline* pipeline, |
| + const Function& function, |
| + bool optimized, |
| + intptr_t osr_id) { |
| + ASSERT(!FLAG_precompiled_mode); |
| + ASSERT(!optimized || function.was_compiled()); |
| + LongJumpScope jump; |
| + if (setjmp(*jump.Set()) == 0) { |
| + Thread* const thread = Thread::Current(); |
| + StackZone stack_zone(thread); |
| + Zone* const zone = stack_zone.GetZone(); |
| + const bool trace_compiler = |
| + FLAG_trace_compiler || |
| + (FLAG_trace_optimizing_compiler && optimized); |
| + |
| + if (trace_compiler) { |
| + const intptr_t token_size = function.end_token_pos().Pos() - |
| + function.token_pos().Pos(); |
| + THR_Print("Parsing %s%sfunction %s: '%s' @ token %s, size %" Pd "\n", |
| + (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "), |
| + (optimized ? "optimized " : ""), |
| + (Compiler::IsBackgroundCompilation() ? "(background)" : ""), |
| + function.ToFullyQualifiedCString(), |
| + function.token_pos().ToCString(), |
| + token_size); |
| + } |
| + ParsedFunction* parsed_function = new(zone) ParsedFunction( |
| + thread, Function::ZoneHandle(zone, function.raw())); |
| + pipeline->ParseFunction(parsed_function); |
| + // For now we just walk thru the AST nodes and in DEBUG mode we print |
| + // them otherwise just skip through them, this will be need to be |
| + // wired to generate the IR format. |
| +#if defined(DEBUG) |
| + AstPrinter ast_printer(true); |
| +#else |
| + AstPrinter ast_printer(false); |
|
hausner
2016/09/23 21:57:20
What's the purpose of invoking the ast printer vis
siva
2016/09/23 22:05:36
I wanted to keep it to measure if traversing the A
|
| +#endif // defined(DEBUG). |
| + ast_printer.PrintFunctionNodes(*parsed_function); |
| + return Error::null(); |
| + } else { |
| + Thread* const thread = Thread::Current(); |
| + StackZone stack_zone(thread); |
| + Error& error = Error::Handle(); |
| + // We got an error during compilation or it is a bailout from background |
| + // compilation (e.g., during parsing with EnsureIsFinalized). |
| + error = thread->sticky_error(); |
| + thread->clear_sticky_error(); |
| + // Unoptimized compilation or precompilation may encounter compile-time |
| + // errors, but regular optimized compilation should not. |
| + ASSERT(!optimized); |
| + return error.raw(); |
| + } |
| + UNREACHABLE(); |
| + return Error::null(); |
| +} |
| + |
| + |
| RawError* Compiler::CompileFunction(Thread* thread, |
| const Function& function) { |
| #ifdef DART_PRECOMPILER |
| @@ -1404,6 +1461,31 @@ NOT_IN_PRODUCT( |
| } |
| +RawError* Compiler::ParseFunction(Thread* thread, |
| + const Function& function) { |
| + Isolate* isolate = thread->isolate(); |
| +NOT_IN_PRODUCT( |
| + VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); |
| + TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "ParseFunction", function); |
| +) // !PRODUCT |
| + |
| + if (!isolate->compilation_allowed()) { |
| + FATAL3("Precompilation missed function %s (%s, %s)\n", |
| + function.ToLibNamePrefixedQualifiedCString(), |
| + function.token_pos().ToCString(), |
| + Function::KindToCString(function.kind())); |
| + } |
| + |
| + CompilationPipeline* pipeline = |
| + CompilationPipeline::New(thread->zone(), function); |
| + |
| + return ParseFunctionHelper(pipeline, |
| + function, |
| + /* optimized = */ false, |
| + kNoOSRDeoptId); |
| +} |
| + |
| + |
| RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, |
| const Function& function) { |
| if (function.unoptimized_code() != Object::null()) { |
| @@ -1555,6 +1637,40 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) { |
| } |
| +RawError* Compiler::ParseAllFunctions(const Class& cls) { |
| + Thread* thread = Thread::Current(); |
| + Zone* zone = thread->zone(); |
| + Error& error = Error::Handle(zone); |
| + Array& functions = Array::Handle(zone, cls.functions()); |
| + Function& func = Function::Handle(zone); |
| + // Class dynamic lives in the vm isolate. Its array fields cannot be set to |
| + // an empty array. |
| + if (functions.IsNull()) { |
| + ASSERT(cls.IsDynamicClass()); |
| + return error.raw(); |
| + } |
| + // Compile all the regular functions. |
| + for (int i = 0; i < functions.Length(); i++) { |
| + func ^= functions.At(i); |
| + ASSERT(!func.IsNull()); |
| + if (!func.is_abstract() && !func.IsRedirectingFactory()) { |
| + if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) && |
| + func.HasOptionalParameters()) { |
| + // Skipping optional parameters in mixin application. |
| + continue; |
| + } |
| + error = ParseFunction(thread, func); |
| + if (!error.IsNull()) { |
| + return error.raw(); |
| + } |
| + func.ClearICDataArray(); |
| + func.ClearCode(); |
| + } |
| + } |
| + return error.raw(); |
| +} |
| + |
| + |
| RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| #ifdef DART_PRECOMPILER |
| if (FLAG_precompiled_mode) { |
| @@ -1633,7 +1749,8 @@ RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| if (FLAG_trace_compiler) { |
| THR_Print("compiling expression: "); |
| if (FLAG_support_ast_printer) { |
| - AstPrinter::PrintNode(fragment); |
| + AstPrinter ast_printer; |
| + ast_printer.PrintNode(fragment); |
| } |
| } |
| @@ -2091,6 +2208,13 @@ RawError* Compiler::CompileFunction(Thread* thread, |
| } |
| +RawError* Compiler::ParseFunction(Thread* thread, |
| + const Function& function) { |
| + UNREACHABLE(); |
| + return Error::null(); |
| +} |
| + |
| + |
| RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, |
| const Function& function) { |
| UNREACHABLE(); |
| @@ -2124,6 +2248,12 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) { |
| } |
| +RawError* Compiler::ParseAllFunctions(const Class& cls) { |
| + UNREACHABLE(); |
| + return Error::null(); |
| +} |
| + |
| + |
| RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| ASSERT(field.HasPrecompiledInitializer()); |
| const Function& initializer = |