Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Unified Diff: src/compiler.cc

Issue 2399463008: Create multiple compilation jobs for ignition if compiling multiple literals (Closed)
Patch Set: updates Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index cf556f237babe4642cd2d837aa75a99ce73b0e78..31e0fc5110dc054d91089821e7ff7e212177956a 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -10,6 +10,7 @@
#include "src/asmjs/asm-js.h"
#include "src/asmjs/asm-typer.h"
#include "src/ast/ast-numbering.h"
+#include "src/ast/collect-eager-literals.h"
#include "src/ast/prettyprinter.h"
#include "src/ast/scopes.h"
#include "src/bootstrapper.h"
@@ -71,6 +72,15 @@ struct ScopedTimer {
// ----------------------------------------------------------------------------
// Implementation of CompilationJob
+CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info,
+ const char* compiler_name, State initial_state)
+ : info_(info),
+ compiler_name_(compiler_name),
+ state_(initial_state),
+ stack_limit_(isolate->stack_guard()->real_climit()) {}
+
+CompilationJob::~CompilationJob() {}
+
CompilationJob::Status CompilationJob::PrepareJob() {
DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id()));
DisallowJavascriptExecution no_js(isolate());
@@ -188,6 +198,13 @@ void CompilationJob::RecordOptimizedCompilationStats() const {
Isolate* CompilationJob::isolate() const { return info()->isolate(); }
+void CompilationJob::TakeOwnershipOfCompilationInfo() {
+ DCHECK_NULL(compilation_info_.get());
+ compilation_info_.reset(info_);
+ parse_info_.reset(info_->parse_info());
+ zone_.reset(info_->parse_info()->zone());
+}
+
namespace {
void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
@@ -346,17 +363,99 @@ bool ShouldUseIgnition(CompilationInfo* info) {
return info->shared_info()->PassesFilter(FLAG_ignition_filter);
}
-CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
+bool Renumber(ParseInfo* parse_info) {
+ // Create a canonical handle scope if compiling ignition bytecode. This is
+ // required by the constant array builder to de-duplicate objects without
+ // dereferencing handles.
+ std::unique_ptr<CanonicalHandleScope> canonical;
+ if (FLAG_ignition) {
+ canonical.reset(new CanonicalHandleScope(parse_info->isolate()));
+ }
+
+ if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(),
+ parse_info->literal())) {
+ return false;
+ }
+ Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
+ if (!shared_info.is_null()) {
+ FunctionLiteral* lit = parse_info->literal();
+ shared_info->set_ast_node_count(lit->ast_node_count());
+ if (lit->dont_optimize_reason() != kNoReason) {
+ shared_info->DisableOptimization(lit->dont_optimize_reason());
+ }
+ if (lit->flags() & AstProperties::kDontCrankshaft) {
+ shared_info->set_dont_crankshaft(true);
+ }
+ }
+ return true;
+}
+
+std::vector<std::unique_ptr<CompilationJob>> GetUnoptimizedCompilationJobs(
+ CompilationInfo* info) {
// Function should have been parsed and analyzed before creating a compilation
// job.
DCHECK_NOT_NULL(info->literal());
DCHECK_NOT_NULL(info->scope());
EnsureFeedbackMetadata(info);
+
+ std::vector<std::unique_ptr<CompilationJob>> result;
+
if (ShouldUseIgnition(info)) {
- return interpreter::Interpreter::NewCompilationJob(info);
+ // When compiling eagerly, the majority of work might happen in the
+ // finalization phase, when we get the SharedFunctionInfos for all the
+ // functions referenced from the function we actually want to compile.
+ //
+ // This is undesirable when we want to schedule the compilation work (which
+ // is only the case for ignition at this point). To avoid this compilation
+ // during finalization, walk the AST and create separate compilation jobs
+ // for each eager function literal we encounter.
+ //
+ // This doesn't work for debug code, as GetSharedFunctionInfo only caches
+ // the SharedFunctionInfos with non-debug code.
+ ShouldCompile should_compile =
+ (FLAG_ignition_split_jobs && !info->is_debug())
+ ? ShouldCompile::kNever
+ : ShouldCompile::kIfNecessary;
+ result.push_back(std::unique_ptr<CompilationJob>(
+ interpreter::Interpreter::NewCompilationJob(info, should_compile)));
+
+ if (should_compile == ShouldCompile::kNever) {
+ CollectEagerLiterals collector(info);
+ collector.Run();
+
+ for (auto fun : collector.eager_literals()) {
+ Handle<SharedFunctionInfo> sfi = Compiler::GetSharedFunctionInfo(
+ fun, info->script(), info, ShouldCompile::kNever);
+
+ std::unique_ptr<ParseInfo> parse_info(new ParseInfo(
+ new Zone(info->isolate()->allocator()), info->script()));
+ parse_info->set_literal(fun);
+ parse_info->set_shared_info(sfi);
+ parse_info->set_language_mode(fun->scope()->language_mode());
+
+ std::unique_ptr<CompilationInfo> compilation_info(new CompilationInfo(
+ parse_info.release(), Handle<JSFunction>::null()));
+ if (info->will_serialize()) compilation_info->PrepareForSerializing();
+ DCHECK(!info->is_debug());
+
+ Renumber(compilation_info->parse_info());
+ EnsureFeedbackMetadata(compilation_info.get());
+ DCHECK(ShouldUseIgnition(compilation_info.get()));
+ std::unique_ptr<CompilationJob> job(
+ interpreter::Interpreter::NewCompilationJob(
+ compilation_info.release(), ShouldCompile::kNever));
+ job->TakeOwnershipOfCompilationInfo();
+ result.push_back(std::move(job));
+ }
+ }
+
+ return result;
} else {
- return FullCodeGenerator::NewCompilationJob(info);
+ std::unique_ptr<CompilationJob> job(
+ FullCodeGenerator::NewCompilationJob(info));
+ result.push_back(std::move(job));
+ return result;
}
}
@@ -419,12 +518,16 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) {
}
}
- std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
- if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
- if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false;
- if (FinalizeUnoptimizedCompilationJob(job.get()) !=
- CompilationJob::SUCCEEDED) {
- return false;
+ std::vector<std::unique_ptr<CompilationJob>> jobs(
+ GetUnoptimizedCompilationJobs(info));
+ for (auto& job : jobs) {
+ if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
+ if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false;
+ if (FinalizeUnoptimizedCompilationJob(job.get()) !=
+ CompilationJob::SUCCEEDED) {
+ return false;
+ }
+ job.reset();
}
return true;
}
@@ -497,33 +600,6 @@ void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
literals, info->osr_ast_id());
}
-bool Renumber(ParseInfo* parse_info) {
- // Create a canonical handle scope if compiling ignition bytecode. This is
- // required by the constant array builder to de-duplicate objects without
- // dereferencing handles.
- std::unique_ptr<CanonicalHandleScope> canonical;
- if (FLAG_ignition) {
- canonical.reset(new CanonicalHandleScope(parse_info->isolate()));
- }
-
- if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(),
- parse_info->literal())) {
- return false;
- }
- Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
- if (!shared_info.is_null()) {
- FunctionLiteral* lit = parse_info->literal();
- shared_info->set_ast_node_count(lit->ast_node_count());
- if (lit->dont_optimize_reason() != kNoReason) {
- shared_info->DisableOptimization(lit->dont_optimize_reason());
- }
- if (lit->flags() & AstProperties::kDontCrankshaft) {
- shared_info->set_dont_crankshaft(true);
- }
- }
- return true;
-}
-
bool UseTurboFan(Handle<SharedFunctionInfo> shared) {
bool optimization_disabled = shared->optimization_disabled();
bool dont_crankshaft = shared->dont_crankshaft();
@@ -1694,16 +1770,16 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript(
return result;
}
-
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
FunctionLiteral* literal, Handle<Script> script,
- CompilationInfo* outer_info) {
+ CompilationInfo* outer_info, ShouldCompile should_compile) {
// Precondition: code has been parsed and scopes have been analyzed.
Isolate* isolate = outer_info->isolate();
MaybeHandle<SharedFunctionInfo> maybe_existing;
// Find any previously allocated shared function info for the given literal.
- if (outer_info->shared_info()->never_compiled()) {
+ if (outer_info->shared_info()->never_compiled() &&
+ should_compile == ShouldCompile::kIfNecessary) {
// On the first compile, there are no existing shared function info for
// inner functions yet, so do not try to find them. All bets are off for
// live edit though.
@@ -1725,6 +1801,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
if (!outer_info->is_debug() || existing->HasDebugCode()) {
return existing;
}
+ } else if (should_compile == ShouldCompile::kNever) {
+ return existing;
Michael Starzinger 2016/10/17 13:16:03 nit: Please add a DCHECK(!outer_info->is_debug())
}
}
@@ -1754,7 +1832,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
- if (!literal->ShouldEagerCompile()) {
+ if (!literal->ShouldEagerCompile() ||
+ should_compile == ShouldCompile::kNever) {
info.SetCode(isolate->builtins()->CompileLazy());
Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
if (outer_scope) {
@@ -1818,14 +1897,18 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame);
}
-CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
- CompilationInfo* info) {
+std::vector<std::unique_ptr<CompilationJob>>
+Compiler::PrepareUnoptimizedCompilationJobs(CompilationInfo* info) {
VMState<COMPILER> state(info->isolate());
- std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
- if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
- return nullptr;
+ std::vector<std::unique_ptr<CompilationJob>> jobs(
+ GetUnoptimizedCompilationJobs(info));
+ for (auto& job : jobs) {
+ if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
+ std::vector<std::unique_ptr<CompilationJob>> result;
+ return result;
+ }
}
- return job.release();
+ return jobs;
}
bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {

Powered by Google App Engine
This is Rietveld 408576698