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() { |