Don't compile inner functions when compiling via the dispatcher
BUG=v8:5394 R=mstarzinger@chromium.org,rmcilroy@chromium.org Review-Url: https://codereview.chromium.org/2579973002 Cr-Commit-Position: refs/heads/master@{#41754}
This commit is contained in:
parent
01408ea653
commit
87bf033799
@ -183,8 +183,8 @@ bool CompilerDispatcherJob::PrepareToCompileOnMainThread() {
|
||||
|
||||
DeferredHandleScope scope(isolate_);
|
||||
if (Compiler::Analyze(parse_info_.get())) {
|
||||
compile_job_.reset(
|
||||
Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
|
||||
compile_job_.reset(Compiler::PrepareUnoptimizedCompilationJob(
|
||||
compile_info_.get(), LazyCompilationMode::kAlways));
|
||||
}
|
||||
compile_info_->set_deferred_handles(scope.Detach());
|
||||
|
||||
|
@ -366,7 +366,8 @@ bool ShouldUseIgnition(CompilationInfo* info) {
|
||||
return shared->PassesFilter(FLAG_ignition_filter);
|
||||
}
|
||||
|
||||
CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
|
||||
CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info,
|
||||
LazyCompilationMode mode) {
|
||||
// Function should have been parsed and analyzed before creating a compilation
|
||||
// job.
|
||||
DCHECK_NOT_NULL(info->literal());
|
||||
@ -374,9 +375,9 @@ CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
|
||||
|
||||
EnsureFeedbackMetadata(info);
|
||||
if (ShouldUseIgnition(info)) {
|
||||
return interpreter::Interpreter::NewCompilationJob(info);
|
||||
return interpreter::Interpreter::NewCompilationJob(info, mode);
|
||||
} else {
|
||||
return FullCodeGenerator::NewCompilationJob(info);
|
||||
return FullCodeGenerator::NewCompilationJob(info, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +440,8 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) {
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
|
||||
std::unique_ptr<CompilationJob> job(
|
||||
GetUnoptimizedCompilationJob(info, LazyCompilationMode::kIfRequested));
|
||||
if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
|
||||
if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false;
|
||||
if (FinalizeUnoptimizedCompilationJob(job.get()) !=
|
||||
@ -1565,10 +1567,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
FunctionLiteral* literal, Handle<Script> script,
|
||||
CompilationInfo* outer_info) {
|
||||
CompilationInfo* outer_info, LazyCompilationMode mode) {
|
||||
// Precondition: code has been parsed and scopes have been analyzed.
|
||||
Isolate* isolate = outer_info->isolate();
|
||||
MaybeHandle<SharedFunctionInfo> maybe_existing;
|
||||
@ -1620,7 +1621,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
// This is especially important for generators. We must not replace the
|
||||
// code for generators, as there may be suspended generator objects.
|
||||
if (!result->is_compiled()) {
|
||||
if (!literal->ShouldEagerCompile()) {
|
||||
if (mode == LazyCompilationMode::kAlways ||
|
||||
!literal->ShouldEagerCompile()) {
|
||||
info.SetCode(isolate->builtins()->CompileLazy());
|
||||
Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
|
||||
if (outer_scope) {
|
||||
@ -1693,9 +1695,9 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
|
||||
}
|
||||
|
||||
CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
|
||||
CompilationInfo* info) {
|
||||
CompilationInfo* info, LazyCompilationMode mode) {
|
||||
VMState<COMPILER> state(info->isolate());
|
||||
std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
|
||||
std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info, mode));
|
||||
if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ class JavaScriptFrame;
|
||||
class ParseInfo;
|
||||
class ScriptData;
|
||||
|
||||
enum class LazyCompilationMode { kAlways, kIfRequested };
|
||||
|
||||
// The V8 compiler API.
|
||||
//
|
||||
// This is the central hub for dispatching to the various compilers within V8.
|
||||
@ -51,9 +53,11 @@ class Compiler : public AllStatic {
|
||||
static bool CompileDebugCode(Handle<SharedFunctionInfo> shared);
|
||||
static MaybeHandle<JSArray> CompileForLiveEdit(Handle<Script> script);
|
||||
|
||||
// Prepare a compilation job for unoptimized code. Requires ParseAndAnalyse.
|
||||
// Prepare a compilation job for unoptimized code. If |mode| is
|
||||
// LazyCompilationMode::kAlways, the returned job will not compile any inner
|
||||
// functions. Requires ParseAndAnalyse.
|
||||
static CompilationJob* PrepareUnoptimizedCompilationJob(
|
||||
CompilationInfo* info);
|
||||
CompilationInfo* info, LazyCompilationMode mode);
|
||||
|
||||
// Generate and install code from previously queued compilation job.
|
||||
static bool FinalizeCompilationJob(CompilationJob* job);
|
||||
@ -115,7 +119,8 @@ class Compiler : public AllStatic {
|
||||
|
||||
// Create a shared function info object (the code may be lazily compiled).
|
||||
static Handle<SharedFunctionInfo> GetSharedFunctionInfo(
|
||||
FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer);
|
||||
FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer,
|
||||
LazyCompilationMode mode = LazyCompilationMode::kIfRequested);
|
||||
|
||||
// Create a shared function info object for a native function literal.
|
||||
static Handle<SharedFunctionInfo> GetSharedFunctionInfoForNative(
|
||||
|
@ -798,8 +798,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -793,8 +793,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -28,8 +28,8 @@ namespace internal {
|
||||
|
||||
class FullCodegenCompilationJob final : public CompilationJob {
|
||||
public:
|
||||
explicit FullCodegenCompilationJob(CompilationInfo* info)
|
||||
: CompilationJob(info->isolate(), info, "Full-Codegen") {}
|
||||
FullCodegenCompilationJob(CompilationInfo* info, LazyCompilationMode mode)
|
||||
: CompilationJob(info->isolate(), info, "Full-Codegen"), mode_(mode) {}
|
||||
|
||||
bool can_execute_on_background_thread() const override { return false; }
|
||||
|
||||
@ -37,19 +37,26 @@ class FullCodegenCompilationJob final : public CompilationJob {
|
||||
|
||||
CompilationJob::Status ExecuteJobImpl() final {
|
||||
DCHECK(ThreadId::Current().Equals(isolate()->thread_id()));
|
||||
return FullCodeGenerator::MakeCode(info(), stack_limit()) ? SUCCEEDED
|
||||
: FAILED;
|
||||
return FullCodeGenerator::MakeCode(info(), stack_limit(), mode_) ? SUCCEEDED
|
||||
: FAILED;
|
||||
}
|
||||
|
||||
CompilationJob::Status FinalizeJobImpl() final { return SUCCEEDED; }
|
||||
|
||||
private:
|
||||
LazyCompilationMode mode_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FullCodegenCompilationJob);
|
||||
};
|
||||
|
||||
FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm,
|
||||
CompilationInfo* info,
|
||||
uintptr_t stack_limit)
|
||||
uintptr_t stack_limit,
|
||||
LazyCompilationMode mode)
|
||||
: masm_(masm),
|
||||
info_(info),
|
||||
isolate_(info->isolate()),
|
||||
compilation_mode_(mode),
|
||||
zone_(info->zone()),
|
||||
scope_(info->scope()),
|
||||
nesting_stack_(NULL),
|
||||
@ -70,17 +77,20 @@ FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// static
|
||||
CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) {
|
||||
return new FullCodegenCompilationJob(info);
|
||||
CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info,
|
||||
LazyCompilationMode mode) {
|
||||
return new FullCodegenCompilationJob(info, mode);
|
||||
}
|
||||
|
||||
// static
|
||||
bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
|
||||
return MakeCode(info, info->isolate()->stack_guard()->real_climit());
|
||||
return MakeCode(info, info->isolate()->stack_guard()->real_climit(),
|
||||
LazyCompilationMode::kIfRequested);
|
||||
}
|
||||
|
||||
// static
|
||||
bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) {
|
||||
bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit,
|
||||
LazyCompilationMode mode) {
|
||||
Isolate* isolate = info->isolate();
|
||||
|
||||
DCHECK(!info->shared_info()->must_use_ignition_turbo());
|
||||
@ -102,7 +112,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) {
|
||||
CodeObjectRequired::kYes);
|
||||
if (info->will_serialize()) masm.enable_serializer();
|
||||
|
||||
FullCodeGenerator cgen(&masm, info, stack_limit);
|
||||
FullCodeGenerator cgen(&masm, info, stack_limit, mode);
|
||||
cgen.Generate();
|
||||
if (cgen.HasStackOverflow()) {
|
||||
DCHECK(!isolate->has_pending_exception());
|
||||
@ -1285,7 +1295,7 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
|
||||
// Build the function boilerplate and instantiate it.
|
||||
Handle<SharedFunctionInfo> function_info =
|
||||
Compiler::GetSharedFunctionInfo(expr, script(), info_);
|
||||
Compiler::GetSharedFunctionInfo(expr, script(), info_, compilation_mode_);
|
||||
if (function_info.is_null()) {
|
||||
SetStackOverflow();
|
||||
return;
|
||||
|
@ -25,6 +25,7 @@ class CompilationInfo;
|
||||
class CompilationJob;
|
||||
class JumpPatchSite;
|
||||
class Scope;
|
||||
enum class LazyCompilationMode;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Full code generator.
|
||||
@ -32,13 +33,15 @@ class Scope;
|
||||
class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
|
||||
public:
|
||||
FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info,
|
||||
uintptr_t stack_limit);
|
||||
uintptr_t stack_limit, LazyCompilationMode mode);
|
||||
|
||||
void Initialize(uintptr_t stack_limit);
|
||||
|
||||
static CompilationJob* NewCompilationJob(CompilationInfo* info);
|
||||
static CompilationJob* NewCompilationJob(CompilationInfo* info,
|
||||
LazyCompilationMode mode);
|
||||
|
||||
static bool MakeCode(CompilationInfo* info, uintptr_t stack_limit);
|
||||
static bool MakeCode(CompilationInfo* info, uintptr_t stack_limit,
|
||||
LazyCompilationMode mode);
|
||||
static bool MakeCode(CompilationInfo* info);
|
||||
|
||||
// Encode bailout state and pc-offset as a BitField<type, start, size>.
|
||||
@ -804,6 +807,7 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
|
||||
MacroAssembler* masm_;
|
||||
CompilationInfo* info_;
|
||||
Isolate* isolate_;
|
||||
LazyCompilationMode compilation_mode_;
|
||||
Zone* zone_;
|
||||
Scope* scope_;
|
||||
Label return_label_;
|
||||
|
@ -746,8 +746,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -797,8 +797,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -797,8 +797,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -766,8 +766,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -738,8 +738,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -760,8 +760,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -742,8 +742,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
|
||||
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
||||
DCHECK(!slot.IsInvalid());
|
||||
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
|
||||
Handle<SharedFunctionInfo> function =
|
||||
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
|
||||
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
|
||||
declaration->fun(), script(), info_, compilation_mode_);
|
||||
// Check for stack-overflow exception.
|
||||
if (function.is_null()) return SetStackOverflow();
|
||||
globals_->Add(function, zone());
|
||||
|
@ -491,10 +491,11 @@ class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
|
||||
// Used to build a list of global declaration initial value pairs.
|
||||
class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
||||
public:
|
||||
explicit GlobalDeclarationsBuilder(Zone* zone)
|
||||
GlobalDeclarationsBuilder(Zone* zone, LazyCompilationMode mode)
|
||||
: declarations_(0, zone),
|
||||
constant_pool_entry_(0),
|
||||
has_constant_pool_entry_(false) {}
|
||||
has_constant_pool_entry_(false),
|
||||
compilation_mode_(mode) {}
|
||||
|
||||
void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot,
|
||||
FunctionLiteral* func) {
|
||||
@ -518,8 +519,8 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
||||
if (func == nullptr) {
|
||||
initial_value = info->isolate()->factory()->undefined_value();
|
||||
} else {
|
||||
initial_value =
|
||||
Compiler::GetSharedFunctionInfo(func, info->script(), info);
|
||||
initial_value = Compiler::GetSharedFunctionInfo(
|
||||
func, info->script(), info, compilation_mode_);
|
||||
}
|
||||
|
||||
// Return a null handle if any initial values can't be created. Caller
|
||||
@ -561,9 +562,11 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
||||
ZoneVector<Declaration> declarations_;
|
||||
size_t constant_pool_entry_;
|
||||
bool has_constant_pool_entry_;
|
||||
LazyCompilationMode compilation_mode_;
|
||||
};
|
||||
|
||||
BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
|
||||
BytecodeGenerator::BytecodeGenerator(CompilationInfo* info,
|
||||
LazyCompilationMode mode)
|
||||
: zone_(info->zone()),
|
||||
builder_(new (zone()) BytecodeArrayBuilder(
|
||||
info->isolate(), info->zone(), info->num_parameters_including_this(),
|
||||
@ -572,7 +575,9 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
|
||||
info->SourcePositionRecordingMode())),
|
||||
info_(info),
|
||||
scope_(info->scope()),
|
||||
globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
|
||||
compilation_mode_(mode),
|
||||
globals_builder_(new (zone())
|
||||
GlobalDeclarationsBuilder(info->zone(), mode)),
|
||||
global_declarations_(0, info->zone()),
|
||||
function_literals_(0, info->zone()),
|
||||
native_function_literals_(0, info->zone()),
|
||||
@ -611,8 +616,8 @@ void BytecodeGenerator::AllocateDeferredConstants() {
|
||||
// Find or build shared function infos.
|
||||
for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
|
||||
FunctionLiteral* expr = literal.first;
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
|
||||
Handle<SharedFunctionInfo> shared_info = Compiler::GetSharedFunctionInfo(
|
||||
expr, info()->script(), info(), compilation_mode_);
|
||||
if (shared_info.is_null()) return SetStackOverflow();
|
||||
builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
|
||||
}
|
||||
@ -949,7 +954,8 @@ void BytecodeGenerator::VisitDeclarations(Declaration::List* declarations) {
|
||||
|
||||
// Push and reset globals builder.
|
||||
global_declarations_.push_back(globals_builder());
|
||||
globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone());
|
||||
globals_builder_ =
|
||||
new (zone()) GlobalDeclarationsBuilder(zone(), compilation_mode_);
|
||||
}
|
||||
|
||||
void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
|
||||
|
@ -15,6 +15,7 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class CompilationInfo;
|
||||
enum class LazyCompilationMode;
|
||||
|
||||
namespace interpreter {
|
||||
|
||||
@ -22,7 +23,7 @@ class LoopBuilder;
|
||||
|
||||
class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
public:
|
||||
explicit BytecodeGenerator(CompilationInfo* info);
|
||||
BytecodeGenerator(CompilationInfo* info, LazyCompilationMode mode);
|
||||
|
||||
void GenerateBytecode(uintptr_t stack_limit);
|
||||
Handle<BytecodeArray> FinalizeBytecode(Isolate* isolate);
|
||||
@ -206,6 +207,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
BytecodeArrayBuilder* builder_;
|
||||
CompilationInfo* info_;
|
||||
DeclarationScope* scope_;
|
||||
LazyCompilationMode compilation_mode_;
|
||||
|
||||
GlobalDeclarationsBuilder* globals_builder_;
|
||||
ZoneVector<GlobalDeclarationsBuilder*> global_declarations_;
|
||||
|
@ -32,7 +32,7 @@ typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
class InterpreterCompilationJob final : public CompilationJob {
|
||||
public:
|
||||
explicit InterpreterCompilationJob(CompilationInfo* info);
|
||||
InterpreterCompilationJob(CompilationInfo* info, LazyCompilationMode mode);
|
||||
|
||||
protected:
|
||||
Status PrepareJobImpl() final;
|
||||
@ -158,8 +158,10 @@ int Interpreter::InterruptBudget() {
|
||||
return FLAG_interrupt_budget * kCodeSizeMultiplier;
|
||||
}
|
||||
|
||||
InterpreterCompilationJob::InterpreterCompilationJob(CompilationInfo* info)
|
||||
: CompilationJob(info->isolate(), info, "Ignition"), generator_(info) {}
|
||||
InterpreterCompilationJob::InterpreterCompilationJob(CompilationInfo* info,
|
||||
LazyCompilationMode mode)
|
||||
: CompilationJob(info->isolate(), info, "Ignition"),
|
||||
generator_(info, mode) {}
|
||||
|
||||
InterpreterCompilationJob::Status InterpreterCompilationJob::PrepareJobImpl() {
|
||||
CodeGenerator::MakeCodePrologue(info(), "interpreter");
|
||||
@ -207,8 +209,9 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() {
|
||||
return SUCCEEDED;
|
||||
}
|
||||
|
||||
CompilationJob* Interpreter::NewCompilationJob(CompilationInfo* info) {
|
||||
return new InterpreterCompilationJob(info);
|
||||
CompilationJob* Interpreter::NewCompilationJob(CompilationInfo* info,
|
||||
LazyCompilationMode mode) {
|
||||
return new InterpreterCompilationJob(info, mode);
|
||||
}
|
||||
|
||||
bool Interpreter::IsDispatchTableInitialized() {
|
||||
|
@ -23,6 +23,7 @@ class Isolate;
|
||||
class Callable;
|
||||
class CompilationInfo;
|
||||
class CompilationJob;
|
||||
enum class LazyCompilationMode;
|
||||
|
||||
namespace compiler {
|
||||
class Node;
|
||||
@ -44,7 +45,8 @@ class Interpreter {
|
||||
static int InterruptBudget();
|
||||
|
||||
// Creates a compilation job which will generate bytecode for |info|.
|
||||
static CompilationJob* NewCompilationJob(CompilationInfo* info);
|
||||
static CompilationJob* NewCompilationJob(CompilationInfo* info,
|
||||
LazyCompilationMode mode);
|
||||
|
||||
// Return bytecode handler for |bytecode|.
|
||||
Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale);
|
||||
|
@ -323,5 +323,36 @@ TEST_F(IgnitionCompilerDispatcherJobTest, CompileOnBackgroundThread) {
|
||||
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
|
||||
}
|
||||
|
||||
TEST_F(CompilerDispatcherJobTest, LazyInnerFunctions) {
|
||||
const char script[] =
|
||||
"function g() {\n"
|
||||
" f = function() {\n"
|
||||
" e = (function() { return 42; });\n"
|
||||
" return e;\n"
|
||||
" };\n"
|
||||
" return f;\n"
|
||||
"}\n"
|
||||
"g();";
|
||||
Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
|
||||
|
||||
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
||||
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
||||
|
||||
job->PrepareToParseOnMainThread();
|
||||
job->Parse();
|
||||
ASSERT_TRUE(job->FinalizeParsingOnMainThread());
|
||||
ASSERT_TRUE(job->PrepareToCompileOnMainThread());
|
||||
job->Compile();
|
||||
ASSERT_TRUE(job->FinalizeCompilingOnMainThread());
|
||||
ASSERT_TRUE(job->status() == CompileJobStatus::kDone);
|
||||
|
||||
Handle<JSFunction> e = Handle<JSFunction>::cast(RunJS(isolate(), "f();"));
|
||||
|
||||
ASSERT_FALSE(e->shared()->HasBaselineCode());
|
||||
|
||||
job->ResetOnMainThread();
|
||||
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user