Commit a7a166e3 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Compiler] Move CompilationInfo into CompilationJob for unoptimized jobs.

Moves creation of the CompilationInfo for unoptimized compilation into the
respective CompilationJobs for Igntition, Fullcode and asm.js. This unifies
the behaviour with respect to the optimized compilation jobs, and enables the
CompileInfo to be owned by the CompilationJob.

As part of this change, we no longer build new dummy ParseInfos for eager inner
functions, instead using just the single outer ParseInfo created during the
actual parsing.

BUG=v8:5203

Change-Id: I6813758dfc5eeff44f5a40bf621184e330593bf9
Reviewed-on: https://chromium-review.googlesource.com/601990
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47198}
parent 88931804
......@@ -184,8 +184,12 @@ void ReportInstantiationFailure(Handle<Script> script, int position,
// code.
class AsmJsCompilationJob final : public CompilationJob {
public:
explicit AsmJsCompilationJob(ParseInfo* parse_info, CompilationInfo* info)
: CompilationJob(info->isolate(), parse_info, info, "AsmJs"),
explicit AsmJsCompilationJob(ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate)
: CompilationJob(isolate, parse_info, &compilation_info_, "AsmJs"),
zone_(isolate->allocator(), ZONE_NAME),
compilation_info_(&zone_, isolate, parse_info, literal, shared_info),
module_(nullptr),
asm_offsets_(nullptr),
translate_time_(0),
......@@ -197,6 +201,8 @@ class AsmJsCompilationJob final : public CompilationJob {
Status FinalizeJobImpl() final;
private:
Zone zone_;
CompilationInfo compilation_info_;
wasm::ZoneBuffer* module_;
wasm::ZoneBuffer* asm_offsets_;
wasm::AsmJsParser::StdlibSet stdlib_uses_;
......@@ -299,8 +305,10 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl() {
}
CompilationJob* AsmJs::NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info) {
return new AsmJsCompilationJob(parse_info, compilation_info);
FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate) {
return new AsmJsCompilationJob(parse_info, literal, shared_info, isolate);
}
MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
......
......@@ -14,6 +14,7 @@ namespace internal {
class CompilationInfo;
class CompilationJob;
class FunctionLiteral;
class JSArrayBuffer;
class ParseInfo;
class SharedFunctionInfo;
......@@ -21,8 +22,9 @@ class SharedFunctionInfo;
// Interface to compile and instantiate for asm.js modules.
class AsmJs {
public:
static CompilationJob* NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info);
static CompilationJob* NewCompilationJob(
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate);
static MaybeHandle<Object> InstantiateAsmWasm(Isolate* isolate,
Handle<SharedFunctionInfo>,
Handle<FixedArray> wasm_data,
......
......@@ -18,13 +18,19 @@ namespace internal {
CompilationInfo::CompilationInfo(Zone* zone, Isolate* isolate,
ParseInfo* parse_info,
FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared)
: CompilationInfo(parse_info->script(), {},
Code::ComputeFlags(Code::FUNCTION), BASE, isolate, zone) {
DCHECK_NOT_NULL(parse_info->literal());
literal_ = parse_info->literal();
source_range_map_ = parse_info->source_range_map();
// NOTE: The parse_info passed here represents the global information gathered
// during parsing, but does not represent specific details of the actual
// function literal being compiled for this CompilationInfo. As such,
// parse_info->literal() might be different from literal, and only global
// details of the script being parsed are relevant to this CompilationInfo.
DCHECK_NOT_NULL(literal);
literal_ = literal;
shared_info_ = shared;
source_range_map_ = parse_info->source_range_map();
// Collect source positions for optimized code when profiling or if debugger
// is active, to be able to get more precise source positions at the price of
......
......@@ -57,7 +57,7 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
// Construct a compilation info for unoptimized compilation.
CompilationInfo(Zone* zone, Isolate* isolate, ParseInfo* parse_info,
Handle<SharedFunctionInfo> shared);
FunctionLiteral* literal, Handle<SharedFunctionInfo> shared);
// Construct a compilation info for optimized compilation.
CompilationInfo(Zone* zone, Isolate* isolate, Handle<Script> script,
Handle<SharedFunctionInfo> shared,
......
......@@ -399,21 +399,12 @@ void UnoptimizedCompileJob::AnalyzeOnMainThread(Isolate* isolate) {
PrintF("UnoptimizedCompileJob[%p]: Analyzing\n", static_cast<void*>(this));
}
compile_zone_.reset(new Zone(isolate->allocator(), ZONE_NAME));
compilation_info_.reset(
new CompilationInfo(compile_zone_.get(), isolate, parse_info_.get(),
Handle<SharedFunctionInfo>::null()));
DeferredHandleScope scope(isolate);
{
if (Compiler::Analyze(parse_info_.get(), isolate)) {
status_ = Status::kAnalyzed;
} else {
status_ = Status::kFailed;
if (!isolate->has_pending_exception()) isolate->StackOverflow();
}
if (Compiler::Analyze(parse_info_.get(), isolate)) {
status_ = Status::kAnalyzed;
} else {
status_ = Status::kFailed;
if (!isolate->has_pending_exception()) isolate->StackOverflow();
}
compilation_info_->set_deferred_handles(scope.Detach());
}
void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) {
......@@ -423,7 +414,7 @@ void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) {
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile);
compilation_job_.reset(Compiler::PrepareUnoptimizedCompilationJob(
parse_info_.get(), compilation_info_.get()));
parse_info_.get(), shared_, isolate));
if (!compilation_job_.get()) {
if (!isolate->has_pending_exception()) isolate->StackOverflow();
status_ = Status::kFailed;
......@@ -467,7 +458,6 @@ void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) {
{
HandleScope scope(isolate);
compilation_info_->set_shared_info(shared_);
if (compilation_job_->state() == CompilationJob::State::kFailed ||
!Compiler::FinalizeCompilationJob(compilation_job_.release())) {
if (!isolate->has_pending_exception()) isolate->StackOverflow();
......@@ -477,8 +467,6 @@ void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) {
}
compilation_job_.reset();
compilation_info_.reset();
compile_zone_.reset();
parse_info_.reset();
status_ = Status::kDone;
......@@ -490,8 +478,6 @@ void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) {
}
compilation_job_.reset();
compilation_info_.reset();
compile_zone_.reset();
parser_.reset();
unicode_cache_.reset();
character_stream_.reset();
......
......@@ -131,8 +131,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
std::unique_ptr<Parser> parser_;
// Members required for compiling.
std::shared_ptr<Zone> compile_zone_;
std::unique_ptr<CompilationInfo> compilation_info_;
std::unique_ptr<CompilationJob> compilation_job_;
bool trace_compiler_dispatcher_jobs_;
......
......@@ -272,8 +272,8 @@ bool ShouldUseFullCodegen(FunctionLiteral* literal) {
return FLAG_stress_fullcodegen;
}
bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info,
bool is_debug) {
bool UseAsmWasm(FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, bool is_debug) {
// Check whether asm.js validation is enabled.
if (!FLAG_validate_asm) return false;
......@@ -288,21 +288,23 @@ bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info,
if (FLAG_stress_validate_asm) return true;
// In general, we respect the "use asm" directive.
return scope->asm_module();
return literal->scope()->asm_module();
}
CompilationJob* GetUnoptimizedCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info) {
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
// Function should have been parsed and analyzed before creating a compilation
// job.
DCHECK_NOT_NULL(compilation_info->literal());
DCHECK_NOT_NULL(compilation_info->scope());
DCHECK_NOT_NULL(literal);
DCHECK_NOT_NULL(parse_info->scope());
if (ShouldUseFullCodegen(compilation_info->literal())) {
return FullCodeGenerator::NewCompilationJob(parse_info, compilation_info);
if (ShouldUseFullCodegen(literal)) {
return FullCodeGenerator::NewCompilationJob(parse_info, literal,
shared_info, isolate);
} else {
return interpreter::Interpreter::NewCompilationJob(parse_info,
compilation_info);
return interpreter::Interpreter::NewCompilationJob(parse_info, literal,
shared_info, isolate);
}
}
......@@ -444,26 +446,20 @@ bool RunUnoptimizedCompilationJob(CompilationJob* job) {
}
Handle<SharedFunctionInfo> GenerateUnoptimizedCode(
ParseInfo* parse_info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate) {
// TODO(rmcilroy): Move the compilation info to be owned by the compilation
// job.
Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo compilation_info(&compile_zone, isolate, parse_info,
shared_info);
if (UseAsmWasm(parse_info->scope(), shared_info, parse_info->is_debug())) {
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
if (UseAsmWasm(literal, shared_info, parse_info->is_debug())) {
std::unique_ptr<CompilationJob> job(
AsmJs::NewCompilationJob(parse_info, &compilation_info));
AsmJs::NewCompilationJob(parse_info, literal, shared_info, isolate));
if (RunUnoptimizedCompilationJob(job.get())) {
return compilation_info.shared_info();
return job->compilation_info()->shared_info();
}
// asm.js validation failed, fall through to standard unoptimized compile.
}
std::unique_ptr<CompilationJob> job(
GetUnoptimizedCompilationJob(parse_info, &compilation_info));
GetUnoptimizedCompilationJob(parse_info, literal, shared_info, isolate));
if (RunUnoptimizedCompilationJob(job.get())) {
return compilation_info.shared_info();
return job->compilation_info()->shared_info();
}
return Handle<SharedFunctionInfo>::null(); // Compilation failed.
}
......@@ -473,11 +469,8 @@ bool CompileUnoptimizedInnerFunctions(
ParseInfo* outer_parse_info, Isolate* isolate) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompileUnoptimizedInnerFunctions");
bool is_debug = outer_parse_info->is_debug();
bool will_serialize = outer_parse_info->will_serialize();
RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileInnerFunction);
for (auto it : *literals) {
FunctionLiteral* literal = it->value();
Handle<SharedFunctionInfo> shared =
......@@ -485,18 +478,8 @@ bool CompileUnoptimizedInnerFunctions(
if (shared->is_compiled()) continue;
// Generate unoptimized code now.
ParseInfo parse_info(script);
parse_info.set_toplevel(false);
parse_info.set_literal(literal);
parse_info.set_function_literal_id(shared->function_literal_id());
parse_info.set_language_mode(literal->scope()->language_mode());
parse_info.ShareAstValueFactory(outer_parse_info);
parse_info.set_source_range_map(outer_parse_info->source_range_map());
if (will_serialize) parse_info.set_will_serialize();
if (is_debug) parse_info.set_is_debug();
if (GenerateUnoptimizedCode(&parse_info, shared, isolate).is_null()) {
if (GenerateUnoptimizedCode(outer_parse_info, literal, shared, isolate)
.is_null()) {
if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false;
}
......@@ -541,8 +524,12 @@ Handle<SharedFunctionInfo> CompileUnoptimizedCode(
}
}
Handle<SharedFunctionInfo> result =
GenerateUnoptimizedCode(parse_info, shared_info, isolate);
Handle<SharedFunctionInfo> result = GenerateUnoptimizedCode(
parse_info, parse_info->literal(), shared_info, isolate);
// Set toplevel to false for inner functions.
// TODO(rmcilroy): Remove this once we no longer rely on
// parse_info->toplevel() in FinalizeUnoptimizedCompilationJob.
parse_info->set_toplevel(false);
if (result.is_null() ||
!CompileUnoptimizedInnerFunctions(&inner_literals, parse_info->script(),
parse_info, isolate)) {
......@@ -1611,10 +1598,11 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
}
CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info) {
VMState<COMPILER> state(compilation_info->isolate());
std::unique_ptr<CompilationJob> job(
GetUnoptimizedCompilationJob(parse_info, compilation_info));
ParseInfo* parse_info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate) {
VMState<COMPILER> state(isolate);
std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(
parse_info, parse_info->literal(), shared_info, isolate));
if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
return nullptr;
}
......
......@@ -54,7 +54,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
// Prepare a compilation job for unoptimized code. Requires ParseAndAnalyse.
static CompilationJob* PrepareUnoptimizedCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info);
ParseInfo* parse_info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate);
// Generate and install code from previously queued compilation job.
static bool FinalizeCompilationJob(CompilationJob* job);
......
......@@ -30,8 +30,12 @@ namespace internal {
class FullCodegenCompilationJob final : public CompilationJob {
public:
explicit FullCodegenCompilationJob(ParseInfo* parse_info,
CompilationInfo* info)
: CompilationJob(info->isolate(), parse_info, info, "Full-Codegen") {}
FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate)
: CompilationJob(isolate, parse_info, &compilation_info_, "Full-Codegen"),
zone_(isolate->allocator(), ZONE_NAME),
compilation_info_(&zone_, isolate, parse_info, literal, shared_info) {}
bool can_execute_on_background_thread() const override { return false; }
......@@ -48,6 +52,9 @@ class FullCodegenCompilationJob final : public CompilationJob {
CompilationJob::Status FinalizeJobImpl() final { return SUCCEEDED; }
private:
Zone zone_;
CompilationInfo compilation_info_;
DISALLOW_COPY_AND_ASSIGN(FullCodegenCompilationJob);
};
......@@ -74,8 +81,10 @@ FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm,
// static
CompilationJob* FullCodeGenerator::NewCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info) {
return new FullCodegenCompilationJob(parse_info, compilation_info);
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
return new FullCodegenCompilationJob(parse_info, literal, shared_info,
isolate);
}
// static
......
......@@ -24,6 +24,7 @@ namespace internal {
// Forward declarations.
class CompilationInfo;
class CompilationJob;
class FunctionLiteral;
class JumpPatchSite;
class ParseInfo;
class Scope;
......@@ -38,8 +39,9 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
void Initialize(uintptr_t stack_limit);
static CompilationJob* NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info);
static CompilationJob* NewCompilationJob(
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate);
static bool MakeCode(ParseInfo* parse_info, CompilationInfo* info,
uintptr_t stack_limit);
......
......@@ -24,8 +24,9 @@ namespace interpreter {
class InterpreterCompilationJob final : public CompilationJob {
public:
InterpreterCompilationJob(ParseInfo* pare_info,
CompilationInfo* compilation_info);
InterpreterCompilationJob(ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate);
protected:
Status PrepareJobImpl() final;
......@@ -65,6 +66,8 @@ class InterpreterCompilationJob final : public CompilationJob {
BytecodeGenerator* generator() { return &generator_; }
Zone zone_;
CompilationInfo compilation_info_;
BytecodeGenerator generator_;
RuntimeCallStats* runtime_call_stats_;
RuntimeCallCounter background_execute_counter_;
......@@ -145,12 +148,13 @@ bool ShouldPrintBytecode(Handle<SharedFunctionInfo> shared) {
} // namespace
InterpreterCompilationJob::InterpreterCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info)
: CompilationJob(compilation_info->isolate(), parse_info, compilation_info,
"Ignition"),
generator_(compilation_info),
runtime_call_stats_(
compilation_info->isolate()->counters()->runtime_call_stats()),
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate)
: CompilationJob(isolate, parse_info, &compilation_info_, "Ignition"),
zone_(isolate->allocator(), ZONE_NAME),
compilation_info_(&zone_, isolate, parse_info, literal, shared_info),
generator_(&compilation_info_),
runtime_call_stats_(isolate->counters()->runtime_call_stats()),
background_execute_counter_("CompileBackgroundIgnition") {}
InterpreterCompilationJob::Status InterpreterCompilationJob::PrepareJobImpl() {
......@@ -207,8 +211,10 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() {
}
CompilationJob* Interpreter::NewCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info) {
return new InterpreterCompilationJob(parse_info, compilation_info);
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
return new InterpreterCompilationJob(parse_info, literal, shared_info,
isolate);
}
bool Interpreter::IsDispatchTableInitialized() {
......
......@@ -23,8 +23,10 @@ class Isolate;
class Callable;
class CompilationInfo;
class CompilationJob;
class FunctionLiteral;
class ParseInfo;
class SetupIsolateDelegate;
class SharedFunctionInfo;
class RootVisitor;
namespace interpreter {
......@@ -39,10 +41,10 @@ class Interpreter {
// Returns the interrupt budget which should be used for the profiler counter.
static int InterruptBudget();
// Creates a compilation job which will generate bytecode for |parse_info| and
// |compilation_info|.
static CompilationJob* NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info);
// Creates a compilation job which will generate bytecode for |literal|.
static CompilationJob* NewCompilationJob(
ParseInfo* parse_info, FunctionLiteral* literal,
Handle<SharedFunctionInfo> shared_info, Isolate* isolate);
// Return bytecode handler for |bytecode|.
Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment