Chromium Code Reviews| Index: src/interpreter/interpreter.cc |
| diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc |
| index f513f0045ea5cee81d7e9fce807eaa30ea8cf4d5..d1dcea021d9c68217ea604ed18cbdcfaa7be3835 100644 |
| --- a/src/interpreter/interpreter.cc |
| +++ b/src/interpreter/interpreter.cc |
| @@ -6,7 +6,9 @@ |
| #include <fstream> |
| #include <memory> |
| +#include <set> |
| +#include "src/ast/ast-traversal-visitor.h" |
| #include "src/ast/prettyprinter.h" |
| #include "src/code-factory.h" |
| #include "src/compilation-info.h" |
| @@ -18,6 +20,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 +36,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 +53,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 +164,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 +218,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 +235,81 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() { |
| return SUCCEEDED; |
| } |
| -CompilationJob* Interpreter::NewCompilationJob(CompilationInfo* info) { |
| - return new InterpreterCompilationJob(info); |
| +class CollectEagerFunctionLiterals final |
| + : public AstTraversalVisitor<CollectEagerFunctionLiterals> { |
| + public: |
| + explicit CollectEagerFunctionLiterals(CompilationInfo* info) |
| + : AstTraversalVisitor(info->isolate(), info->parse_info()->literal()), |
| + parse_info_(info->parse_info()) {} |
| + |
| + const std::set<FunctionLiteral*>& eager_literals() const { |
| + return eager_literals_; |
| + } |
| + |
| + private: |
| + friend class AstTraversalVisitor<CollectEagerFunctionLiterals>; |
| + |
| + void VisitFunctionDeclaration(FunctionDeclaration* decl) { |
| + i::Variable* variable = decl->proxy()->var(); |
| + DCHECK(variable->mode() == LET || variable->mode() == VAR); |
| + if (variable->location() == VariableLocation::UNALLOCATED) { |
| + if (decl->fun()->ShouldEagerCompile()) { |
| + eager_literals_.insert(decl->fun()); |
| + } else { |
| + return; |
| + } |
| + } |
| + AstTraversalVisitor::VisitFunctionDeclaration(decl); |
| + } |
| + |
| + void VisitFunctionLiteral(FunctionLiteral* fun) { |
| + if (fun->ShouldEagerCompile()) { |
| + if (fun != parse_info_->literal()) { |
| + eager_literals_.insert(fun); |
| + } |
| + AstTraversalVisitor::VisitFunctionLiteral(fun); |
| + } |
| + } |
| + |
| + std::set<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()); |
| + Compiler::Renumber(parse_info.get()); |
|
jochen (gone - plz use gerrit)
2016/10/07 15:40:48
^^^ like this
|
| + 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() { |