Chromium Code Reviews| Index: src/interpreter/interpreter.cc |
| diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc |
| index 64d093fbb6e19096baa4f8579728239c07edd4ca..2b0d86f750d5acfde29b4e0f7ee4504412b21a09 100644 |
| --- a/src/interpreter/interpreter.cc |
| +++ b/src/interpreter/interpreter.cc |
| @@ -7,6 +7,7 @@ |
| #include <fstream> |
| #include <memory> |
| +#include "src/ast/ast-traversal-visitor.h" |
| #include "src/ast/prettyprinter.h" |
| #include "src/code-factory.h" |
| #include "src/compilation-info.h" |
| @@ -18,6 +19,7 @@ |
| #include "src/interpreter/interpreter-assembler.h" |
| #include "src/interpreter/interpreter-intrinsics.h" |
| #include "src/log.h" |
| +#include "src/parsing/parse-info.h" |
| #include "src/zone/zone.h" |
| namespace v8 { |
| @@ -33,7 +35,12 @@ typedef InterpreterAssembler::Arg Arg; |
| class InterpreterCompilationJob final : public CompilationJob { |
| public: |
| - explicit InterpreterCompilationJob(CompilationInfo* info); |
| + InterpreterCompilationJob(CompilationInfo* info, |
| + ShouldCompile should_compile); |
| + |
| + InterpreterCompilationJob(std::unique_ptr<Zone> zone, |
| + std::unique_ptr<ParseInfo> parse_info, |
| + std::unique_ptr<CompilationInfo> info); |
| protected: |
| Status PrepareJobImpl() final; |
| @@ -45,6 +52,12 @@ class InterpreterCompilationJob final : public CompilationJob { |
| BytecodeGenerator generator_; |
| + ShouldCompile should_compile_; |
| + |
| + std::unique_ptr<Zone> zone_; |
| + std::unique_ptr<ParseInfo> parse_info_; |
| + std::unique_ptr<CompilationInfo> info_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(InterpreterCompilationJob); |
| }; |
| @@ -150,8 +163,20 @@ int Interpreter::InterruptBudget() { |
| return FLAG_interrupt_budget * kCodeSizeMultiplier; |
| } |
| -InterpreterCompilationJob::InterpreterCompilationJob(CompilationInfo* info) |
| - : CompilationJob(info->isolate(), info, "Ignition"), generator_(info) {} |
| +InterpreterCompilationJob::InterpreterCompilationJob( |
| + CompilationInfo* info, ShouldCompile should_compile) |
| + : CompilationJob(info->isolate(), info, "Ignition"), |
| + generator_(info), |
| + should_compile_(should_compile) {} |
| + |
| +InterpreterCompilationJob::InterpreterCompilationJob( |
| + std::unique_ptr<Zone> zone, std::unique_ptr<ParseInfo> parse_info, |
| + std::unique_ptr<CompilationInfo> info) |
| + : InterpreterCompilationJob(info.get(), ShouldCompile::kNever) { |
| + zone_ = std::move(zone); |
| + parse_info_ = std::move(parse_info); |
| + info_ = std::move(info); |
| +} |
| InterpreterCompilationJob::Status InterpreterCompilationJob::PrepareJobImpl() { |
| if (FLAG_print_bytecode || FLAG_print_ast) { |
| @@ -192,7 +217,8 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() { |
| } |
| InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() { |
| - Handle<BytecodeArray> bytecodes = generator()->FinalizeBytecode(isolate()); |
| + Handle<BytecodeArray> bytecodes = |
| + generator()->FinalizeBytecode(isolate(), should_compile_); |
| if (generator()->HasStackOverflow()) { |
| return FAILED; |
| } |
| @@ -208,8 +234,66 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() { |
| return SUCCEEDED; |
| } |
| -CompilationJob* Interpreter::NewCompilationJob(CompilationInfo* info) { |
| - return new InterpreterCompilationJob(info); |
| +class CollectEagerFunctionLiterals final |
| + : public AstTraversalVisitor<CollectEagerFunctionLiterals> { |
|
rmcilroy
2016/10/07 14:26:34
I'd really prefer we do this somewhere else - we a
jochen (gone - plz use gerrit)
2016/10/07 14:55:25
none of the other visitors visit the entire AST (o
|
| + public: |
| + explicit CollectEagerFunctionLiterals(CompilationInfo* info) |
| + : AstTraversalVisitor(info->isolate(), info->parse_info()->literal()), |
| + parse_info_(info->parse_info()) {} |
| + |
| + const std::vector<FunctionLiteral*>& eager_literals() const { |
| + return eager_literals_; |
| + } |
| + |
| + private: |
| + friend class AstTraversalVisitor<CollectEagerFunctionLiterals>; |
| + |
| + void VisitFunctionLiteral(FunctionLiteral* literal) { |
| + if (!literal->ShouldEagerCompile()) return; |
| + if (literal != parse_info_->literal()) { |
| + eager_literals_.push_back(literal); |
| + } |
| + AstTraversalVisitor::VisitFunctionLiteral(literal); |
| + } |
| + |
| + std::vector<FunctionLiteral*> eager_literals_; |
| + ParseInfo* parse_info_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(CollectEagerFunctionLiterals); |
| +}; |
| + |
| +std::vector<std::unique_ptr<CompilationJob>> Interpreter::NewCompilationJob( |
| + CompilationInfo* info) { |
| + ShouldCompile should_compile = |
| + info->is_debug() ? ShouldCompile::kIfNecessary : ShouldCompile::kNever; |
| + |
| + std::vector<std::unique_ptr<CompilationJob>> jobs; |
| + jobs.push_back(std::unique_ptr<InterpreterCompilationJob>( |
| + new InterpreterCompilationJob(info, should_compile))); |
| + |
| + if (should_compile == ShouldCompile::kIfNecessary) return jobs; |
| + |
| + CollectEagerFunctionLiterals collector(info); |
| + collector.Run(); |
| + |
| + for (auto fun : collector.eager_literals()) { |
| + Handle<SharedFunctionInfo> sfi = Compiler::GetSharedFunctionInfo( |
| + fun, info->script(), info, ShouldCompile::kNever); |
| + std::unique_ptr<Zone> zone(new Zone(info->isolate()->allocator())); |
| + std::unique_ptr<ParseInfo> parse_info( |
| + new ParseInfo(zone.get(), info->script())); |
| + std::unique_ptr<CompilationInfo> compilation_info( |
| + new CompilationInfo(parse_info.get(), Handle<JSFunction>::null())); |
| + parse_info->set_literal(fun); |
| + parse_info->set_shared_info(sfi); |
| + parse_info->set_language_mode(fun->scope()->language_mode()); |
| + if (info->will_serialize()) compilation_info->PrepareForSerializing(); |
| + DCHECK(!info->is_debug()); |
| + jobs.push_back(std::unique_ptr<InterpreterCompilationJob>( |
| + new InterpreterCompilationJob(std::move(zone), std::move(parse_info), |
| + std::move(compilation_info)))); |
| + } |
| + return jobs; |
| } |
| bool Interpreter::IsDispatchTableInitialized() { |