Chromium Code Reviews| Index: runtime/vm/compiler.cc |
| diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc |
| index 4fee7933623f1f656c2cdf918910455eb3569739..2a34e00ea93058e66b7a671ce474367d02dcb633 100644 |
| --- a/runtime/vm/compiler.cc |
| +++ b/runtime/vm/compiler.cc |
| @@ -1373,6 +1373,66 @@ 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); |
| + const bool trace_compiler = |
| + FLAG_trace_compiler || |
| + (FLAG_trace_optimizing_compiler && optimized); |
| + Timer per_compile_timer(trace_compiler, "Compilation time"); |
| + per_compile_timer.Start(); |
| + |
| + if (trace_compiler) { |
| + const intptr_t token_size = function.end_token_pos().Pos() - |
| + function.token_pos().Pos(); |
| + THR_Print("Compiling %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); |
| + } |
| + INC_STAT(thread, num_functions_compiled, 1); |
|
hausner
2016/09/09 16:31:07
I know this is just a temporary thing, but it migh
siva
2016/09/23 00:04:03
Done.
|
| + if (optimized) { |
| + INC_STAT(thread, num_functions_optimized, 1); |
| + } |
| + 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(); |
| + if (error.raw() == Object::background_compilation_error().raw()) { |
| + // Exit compilation, retry it later. |
| + if (FLAG_trace_bailout) { |
| + THR_Print("Aborted background compilation: %s\n", |
| + function.ToFullyQualifiedCString()); |
| + } |
| + return Error::null(); |
| + } |
| + // Unoptimized compilation or precompilation may encounter compile-time |
| + // errors, but regular optimized compilation should not. |
| + ASSERT(!optimized); |
| + // Do not attempt to optimize functions that can cause errors. |
| + function.set_is_optimizable(false); |
| + return error.raw(); |
| + } |
| + UNREACHABLE(); |
| + return Error::null(); |
| +} |
| + |
| + |
| RawError* Compiler::CompileFunction(Thread* thread, |
| const Function& function) { |
| #ifdef DART_PRECOMPILER |
| @@ -1403,6 +1463,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, "CompileFunction", 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()) { |
| @@ -1554,6 +1639,42 @@ 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.HasCode() && |
| + !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) { |