Commit fa4f0347 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

Revert of [Compiler] Enable handles created during parsing and scope analysis...

Revert of [Compiler] Enable handles created during parsing and scope analysis to be deferred. (patchset #9 id:180001 of https://codereview.chromium.org/2650883002/ )

Reason for revert:
Issue on arm64:
https://build.chromium.org/p/client.v8.ports/builders/V8%20Linux%20-%20arm64%20-%20sim/builds/5752

Original issue's description:
> [Compiler] Enable handles created during parsing and scope analysis to be deferred.
>
> In order to compile eager inner functions on a background thread we need to
> keep the handles created during parsing and scope analysis alive until the
> background compilation is complete. In order to do that, we allocate the
> handles in a deferred handle scope and keep the deferred handles alive with
> a shared_ptr in the ParseInfo and CompileInfo respectively.
>
> BUG=v8:5203
>
> Review-Url: https://codereview.chromium.org/2650883002
> Cr-Commit-Position: refs/heads/master@{#43091}
> Committed: https://chromium.googlesource.com/v8/v8/+/9346cd9b4c50466aa8d50e98c56b84ba47c2a115

TBR=marja@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:5203

Review-Url: https://codereview.chromium.org/2687973003
Cr-Commit-Position: refs/heads/master@{#43093}
parent fd8ef3b6
...@@ -2418,19 +2418,12 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, ...@@ -2418,19 +2418,12 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
} }
source->info->set_script(script); source->info->set_script(script);
if (source->info->literal() == nullptr) {
source->parser->ReportErrors(isolate, script);
}
source->parser->UpdateStatistics(isolate, script);
i::DeferredHandleScope deferred_handle_scope(isolate); // Do the parsing tasks which need to be done on the main thread. This will
{ // also handle parse errors.
// Internalize AST values on the main thread. source->parser->Internalize(isolate, script,
source->info->ReopenHandlesInNewHandleScope(); source->info->literal() == nullptr);
source->info->ast_value_factory()->Internalize(isolate);
source->parser->HandleSourceURLComments(isolate, script); source->parser->HandleSourceURLComments(isolate, script);
}
source->info->set_deferred_handles(deferred_handle_scope.Detach());
i::Handle<i::SharedFunctionInfo> result; i::Handle<i::SharedFunctionInfo> result;
if (source->info->literal() != nullptr) { if (source->info->literal() != nullptr) {
......
...@@ -349,7 +349,8 @@ OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE) ...@@ -349,7 +349,8 @@ OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
namespace internal { namespace internal {
class V8_EXPORT_PRIVATE DeferredHandles {
class DeferredHandles {
public: public:
~DeferredHandles(); ~DeferredHandles();
......
...@@ -108,6 +108,7 @@ CompilationInfo::~CompilationInfo() { ...@@ -108,6 +108,7 @@ CompilationInfo::~CompilationInfo() {
shared_info()->DisableOptimization(bailout_reason()); shared_info()->DisableOptimization(bailout_reason());
} }
dependencies()->Rollback(); dependencies()->Rollback();
delete deferred_handles_;
} }
int CompilationInfo::num_parameters() const { int CompilationInfo::num_parameters() const {
...@@ -131,21 +132,8 @@ bool CompilationInfo::ShouldSelfOptimize() { ...@@ -131,21 +132,8 @@ bool CompilationInfo::ShouldSelfOptimize() {
!shared_info()->optimization_disabled(); !shared_info()->optimization_disabled();
} }
void CompilationInfo::set_deferred_handles(
std::shared_ptr<DeferredHandles> deferred_handles) {
DCHECK(deferred_handles_.get() == nullptr);
deferred_handles_.swap(deferred_handles);
}
void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
DCHECK(deferred_handles_.get() == nullptr);
deferred_handles_.reset(deferred_handles);
}
void CompilationInfo::ReopenHandlesInNewHandleScope() { void CompilationInfo::ReopenHandlesInNewHandleScope() {
if (!closure_.is_null()) {
closure_ = Handle<JSFunction>(*closure_); closure_ = Handle<JSFunction>(*closure_);
}
} }
bool CompilationInfo::has_simple_parameters() { bool CompilationInfo::has_simple_parameters() {
......
...@@ -232,10 +232,9 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -232,10 +232,9 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
// Determines whether or not to insert a self-optimization header. // Determines whether or not to insert a self-optimization header.
bool ShouldSelfOptimize(); bool ShouldSelfOptimize();
void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles); void set_deferred_handles(DeferredHandles* deferred_handles) {
void set_deferred_handles(DeferredHandles* deferred_handles); DCHECK(deferred_handles_ == NULL);
std::shared_ptr<DeferredHandles> deferred_handles() { deferred_handles_ = deferred_handles;
return deferred_handles_;
} }
void ReopenHandlesInNewHandleScope(); void ReopenHandlesInNewHandleScope();
...@@ -365,7 +364,7 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -365,7 +364,7 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
// CompilationInfo allocates. // CompilationInfo allocates.
Zone* zone_; Zone* zone_;
std::shared_ptr<DeferredHandles> deferred_handles_; DeferredHandles* deferred_handles_;
// Dependencies for this compilation, e.g. stable maps. // Dependencies for this compilation, e.g. stable maps.
CompilationDependencies dependencies_; CompilationDependencies dependencies_;
......
...@@ -84,27 +84,26 @@ CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate, ...@@ -84,27 +84,26 @@ CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
} }
} }
CompilerDispatcherJob::CompilerDispatcherJob( CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
Isolate* isolate, CompilerDispatcherTracer* tracer, CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared, FunctionLiteral* literal, Handle<SharedFunctionInfo> shared,
std::shared_ptr<Zone> parse_zone, FunctionLiteral* literal,
std::shared_ptr<DeferredHandles> parse_handles, size_t max_stack_size)
std::shared_ptr<DeferredHandles> compile_handles, size_t max_stack_size)
: status_(CompileJobStatus::kAnalyzed), : status_(CompileJobStatus::kAnalyzed),
isolate_(isolate), isolate_(isolate),
tracer_(tracer), tracer_(tracer),
shared_(Handle<SharedFunctionInfo>::cast( shared_(Handle<SharedFunctionInfo>::cast(
isolate_->global_handles()->Create(*shared))), isolate_->global_handles()->Create(*shared))),
max_stack_size_(max_stack_size), max_stack_size_(max_stack_size),
parse_info_(new ParseInfo(shared_)), parse_info_(
parse_zone_(parse_zone), new ParseInfo(Handle<Script>(Script::cast(shared->script())))),
compile_info_(new CompilationInfo(parse_info_->zone(), parse_info_.get(), compile_info_(new CompilationInfo(parse_info_->zone(), parse_info_.get(),
Handle<JSFunction>::null())), Handle<JSFunction>::null())),
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) { trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
parse_info_->set_literal(literal); parse_info_->set_literal(literal);
parse_info_->set_deferred_handles(parse_handles); parse_info_->set_shared_info(shared);
compile_info_->set_deferred_handles(compile_handles); parse_info_->set_function_literal_id(shared->function_literal_id());
parse_info_->set_language_mode(literal->scope()->language_mode());
if (trace_compiler_dispatcher_jobs_) { if (trace_compiler_dispatcher_jobs_) {
PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this)); PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
shared_->ShortPrint(); shared_->ShortPrint();
...@@ -277,19 +276,17 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() { ...@@ -277,19 +276,17 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
wrapper_ = Handle<String>::null(); wrapper_ = Handle<String>::null();
} }
Handle<Script> script(Script::cast(shared_->script()), isolate_);
parse_info_->set_script(script);
if (parse_info_->literal() == nullptr) { if (parse_info_->literal() == nullptr) {
parser_->ReportErrors(isolate_, script);
status_ = CompileJobStatus::kFailed; status_ = CompileJobStatus::kFailed;
} else { } else {
status_ = CompileJobStatus::kReadyToAnalyze; status_ = CompileJobStatus::kReadyToAnalyze;
} }
parser_->UpdateStatistics(isolate_, script);
DeferredHandleScope scope(isolate_); DeferredHandleScope scope(isolate_);
{ {
parse_info_->ReopenHandlesInNewHandleScope(); Handle<Script> script(Script::cast(shared_->script()), isolate_);
parse_info_->set_script(script);
Handle<ScopeInfo> outer_scope_info( Handle<ScopeInfo> outer_scope_info(
handle(ScopeInfo::cast(shared_->outer_scope_info()))); handle(ScopeInfo::cast(shared_->outer_scope_info())));
if (outer_scope_info->length() > 0) { if (outer_scope_info->length() > 0) {
...@@ -297,8 +294,9 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() { ...@@ -297,8 +294,9 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
} }
parse_info_->set_shared_info(shared_); parse_info_->set_shared_info(shared_);
// Internalize ast values on the main thread. // Do the parsing tasks which need to be done on the main thread. This
parse_info_->ast_value_factory()->Internalize(isolate_); // will also handle parse errors.
parser_->Internalize(isolate_, script, parse_info_->literal() == nullptr);
parser_->HandleSourceURLComments(isolate_, script); parser_->HandleSourceURLComments(isolate_, script);
parse_info_->set_character_stream(nullptr); parse_info_->set_character_stream(nullptr);
...@@ -307,7 +305,7 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() { ...@@ -307,7 +305,7 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
unicode_cache_.reset(); unicode_cache_.reset();
character_stream_.reset(); character_stream_.reset();
} }
parse_info_->set_deferred_handles(scope.Detach()); handles_from_parsing_.reset(scope.Detach());
return status_ != CompileJobStatus::kFailed; return status_ != CompileJobStatus::kFailed;
} }
...@@ -395,7 +393,7 @@ bool CompilerDispatcherJob::FinalizeCompilingOnMainThread() { ...@@ -395,7 +393,7 @@ bool CompilerDispatcherJob::FinalizeCompilingOnMainThread() {
compile_job_.reset(); compile_job_.reset();
compile_info_.reset(); compile_info_.reset();
parse_zone_.reset(); handles_from_parsing_.reset();
parse_info_.reset(); parse_info_.reset();
status_ = CompileJobStatus::kDone; status_ = CompileJobStatus::kDone;
...@@ -411,10 +409,10 @@ void CompilerDispatcherJob::ResetOnMainThread() { ...@@ -411,10 +409,10 @@ void CompilerDispatcherJob::ResetOnMainThread() {
compile_job_.reset(); compile_job_.reset();
compile_info_.reset(); compile_info_.reset();
parse_zone_.reset();
parser_.reset(); parser_.reset();
unicode_cache_.reset(); unicode_cache_.reset();
character_stream_.reset(); character_stream_.reset();
handles_from_parsing_.reset();
parse_info_.reset(); parse_info_.reset();
if (!source_.is_null()) { if (!source_.is_null()) {
......
...@@ -20,7 +20,6 @@ class AstValueFactory; ...@@ -20,7 +20,6 @@ class AstValueFactory;
class CompilerDispatcherTracer; class CompilerDispatcherTracer;
class CompilationInfo; class CompilationInfo;
class CompilationJob; class CompilationJob;
class DeferredHandles;
class FunctionLiteral; class FunctionLiteral;
class Isolate; class Isolate;
class ParseInfo; class ParseInfo;
...@@ -51,11 +50,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob { ...@@ -51,11 +50,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
// Creates a CompilerDispatcherJob in the analyzed state. // Creates a CompilerDispatcherJob in the analyzed state.
CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer, CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared, Handle<SharedFunctionInfo> shared,
FunctionLiteral* literal, FunctionLiteral* literal, size_t max_stack_size);
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
std::shared_ptr<DeferredHandles> compile_handles,
size_t max_stack_size);
~CompilerDispatcherJob(); ~CompilerDispatcherJob();
CompileJobStatus status() const { return status_; } CompileJobStatus status() const { return status_; }
...@@ -116,9 +111,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob { ...@@ -116,9 +111,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
std::unique_ptr<Utf16CharacterStream> character_stream_; std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ParseInfo> parse_info_; std::unique_ptr<ParseInfo> parse_info_;
std::unique_ptr<Parser> parser_; std::unique_ptr<Parser> parser_;
std::unique_ptr<DeferredHandles> handles_from_parsing_;
// Members required for compiling a parsed function.
std::shared_ptr<Zone> parse_zone_;
// Members required for compiling. // Members required for compiling.
std::unique_ptr<CompilationInfo> compile_info_; std::unique_ptr<CompilationInfo> compile_info_;
......
...@@ -287,11 +287,8 @@ bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> function) { ...@@ -287,11 +287,8 @@ bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> function) {
return true; return true;
} }
bool CompilerDispatcher::Enqueue( bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function,
Handle<SharedFunctionInfo> function, FunctionLiteral* literal, FunctionLiteral* literal) {
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
std::shared_ptr<DeferredHandles> compile_handles) {
if (!CanEnqueue(function)) return false; if (!CanEnqueue(function)) return false;
if (IsEnqueued(function)) return true; if (IsEnqueued(function)) return true;
...@@ -302,8 +299,7 @@ bool CompilerDispatcher::Enqueue( ...@@ -302,8 +299,7 @@ bool CompilerDispatcher::Enqueue(
} }
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
isolate_, tracer_.get(), function, literal, parse_zone, parse_handles, isolate_, tracer_.get(), function, literal, max_stack_size_));
compile_handles, max_stack_size_));
std::pair<int, int> key(Script::cast(function->script())->id(), std::pair<int, int> key(Script::cast(function->script())->id(),
function->function_literal_id()); function->function_literal_id());
jobs_.insert(std::make_pair(key, std::move(job))); jobs_.insert(std::make_pair(key, std::move(job)));
...@@ -311,14 +307,9 @@ bool CompilerDispatcher::Enqueue( ...@@ -311,14 +307,9 @@ bool CompilerDispatcher::Enqueue(
return true; return true;
} }
bool CompilerDispatcher::EnqueueAndStep( bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> function,
Handle<SharedFunctionInfo> function, FunctionLiteral* literal, FunctionLiteral* literal) {
std::shared_ptr<Zone> parse_zone, if (!Enqueue(function, literal)) return false;
std::shared_ptr<DeferredHandles> parse_handles,
std::shared_ptr<DeferredHandles> compile_handles) {
if (!Enqueue(function, literal, parse_zone, parse_handles, compile_handles)) {
return false;
}
if (trace_compiler_dispatcher_) { if (trace_compiler_dispatcher_) {
PrintF("CompilerDispatcher: stepping "); PrintF("CompilerDispatcher: stepping ");
......
...@@ -28,11 +28,9 @@ namespace internal { ...@@ -28,11 +28,9 @@ namespace internal {
class CancelableTaskManager; class CancelableTaskManager;
class CompilerDispatcherJob; class CompilerDispatcherJob;
class CompilerDispatcherTracer; class CompilerDispatcherTracer;
class DeferredHandles;
class FunctionLiteral; class FunctionLiteral;
class Isolate; class Isolate;
class SharedFunctionInfo; class SharedFunctionInfo;
class Zone;
template <typename T> template <typename T>
class Handle; class Handle;
...@@ -84,19 +82,13 @@ class V8_EXPORT_PRIVATE CompilerDispatcher { ...@@ -84,19 +82,13 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Enqueue a job for compilation. Function must have already been parsed and // Enqueue a job for compilation. Function must have already been parsed and
// analyzed and be ready for compilation. Returns true if a job was enqueued. // analyzed and be ready for compilation. Returns true if a job was enqueued.
bool Enqueue(Handle<SharedFunctionInfo> function, FunctionLiteral* literal, bool Enqueue(Handle<SharedFunctionInfo> function, FunctionLiteral* literal);
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
std::shared_ptr<DeferredHandles> compile_handles);
// Like Enqueue, but also advances the job so that it can potentially // Like Enqueue, but also advances the job so that it can potentially
// continue running on a background thread (if at all possible). Returns // continue running on a background thread (if at all possible). Returns
// true if the job was enqueued. // true if the job was enqueued.
bool EnqueueAndStep(Handle<SharedFunctionInfo> function, bool EnqueueAndStep(Handle<SharedFunctionInfo> function,
FunctionLiteral* literal, FunctionLiteral* literal);
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
std::shared_ptr<DeferredHandles> compile_handles);
// Returns true if there is a pending job for the given function. // Returns true if there is a pending job for the given function.
bool IsEnqueued(Handle<SharedFunctionInfo> function) const; bool IsEnqueued(Handle<SharedFunctionInfo> function) const;
......
...@@ -39,19 +39,6 @@ ...@@ -39,19 +39,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// A wrapper around a ParseInfo that detaches the parser handles from the
// underlying DeferredHandleScope and stores them in info_ on destruction.
class ParseHandleScope final {
public:
explicit ParseHandleScope(ParseInfo* info)
: deferred_(info->isolate()), info_(info) {}
~ParseHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
private:
DeferredHandleScope deferred_;
ParseInfo* info_;
};
// A wrapper around a CompilationInfo that detaches the Handles from // A wrapper around a CompilationInfo that detaches the Handles from
// the underlying DeferredHandleScope and stores them in info_ on // the underlying DeferredHandleScope and stores them in info_ on
// destruction. // destruction.
...@@ -525,7 +512,7 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) { ...@@ -525,7 +512,7 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) {
bool CompileUnoptimizedInnerFunctions( bool CompileUnoptimizedInnerFunctions(
Compiler::EagerInnerFunctionLiterals* literals, Compiler::EagerInnerFunctionLiterals* literals,
Compiler::ConcurrencyMode inner_function_mode, Compiler::ConcurrencyMode inner_function_mode,
std::shared_ptr<Zone> parse_zone, CompilationInfo* outer_info) { CompilationInfo* outer_info) {
Isolate* isolate = outer_info->isolate(); Isolate* isolate = outer_info->isolate();
Handle<Script> script = outer_info->script(); Handle<Script> script = outer_info->script();
bool is_debug = outer_info->is_debug(); bool is_debug = outer_info->is_debug();
...@@ -547,9 +534,7 @@ bool CompileUnoptimizedInnerFunctions( ...@@ -547,9 +534,7 @@ bool CompileUnoptimizedInnerFunctions(
CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(),
shared, is_debug, will_serialize) && shared, is_debug, will_serialize) &&
dispatcher->EnqueueAndStep(shared, literal, parse_zone, dispatcher->EnqueueAndStep(shared, literal)) {
outer_info->parse_info()->deferred_handles(),
outer_info->deferred_handles())) {
// If we have successfully queued up the function for compilation on the // If we have successfully queued up the function for compilation on the
// compiler dispatcher then we are done. // compiler dispatcher then we are done.
continue; continue;
...@@ -594,16 +579,10 @@ bool CompileUnoptimizedCode(CompilationInfo* info, ...@@ -594,16 +579,10 @@ bool CompileUnoptimizedCode(CompilationInfo* info,
DCHECK(AllowCompilation::IsAllowed(isolate)); DCHECK(AllowCompilation::IsAllowed(isolate));
Compiler::EagerInnerFunctionLiterals inner_literals; Compiler::EagerInnerFunctionLiterals inner_literals;
{
std::unique_ptr<CompilationHandleScope> compilation_handle_scope;
if (inner_function_mode == Compiler::CONCURRENT) {
compilation_handle_scope.reset(new CompilationHandleScope(info));
}
if (!Compiler::Analyze(info->parse_info(), &inner_literals)) { if (!Compiler::Analyze(info->parse_info(), &inner_literals)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false; return false;
} }
}
// Disable concurrent inner compilation for asm-wasm code. // Disable concurrent inner compilation for asm-wasm code.
// TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm // TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm
...@@ -613,17 +592,15 @@ bool CompileUnoptimizedCode(CompilationInfo* info, ...@@ -613,17 +592,15 @@ bool CompileUnoptimizedCode(CompilationInfo* info,
inner_function_mode = Compiler::NOT_CONCURRENT; inner_function_mode = Compiler::NOT_CONCURRENT;
} }
std::shared_ptr<Zone> parse_zone;
if (inner_function_mode == Compiler::CONCURRENT) { if (inner_function_mode == Compiler::CONCURRENT) {
// Seal the parse zone so that it can be shared by parallel inner function // Seal the parse zone so that it can be shared by parallel inner function
// compilation jobs. // compilation jobs.
DCHECK_NE(info->parse_info()->zone(), info->zone()); DCHECK_NE(info->parse_info()->zone(), info->zone());
parse_zone = info->parse_info()->zone_shared(); info->parse_info()->zone()->Seal();
parse_zone->Seal();
} }
if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode,
parse_zone, info) || info) ||
!GenerateUnoptimizedCode(info)) { !GenerateUnoptimizedCode(info)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false; return false;
...@@ -664,20 +641,8 @@ MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode( ...@@ -664,20 +641,8 @@ MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(
VMState<COMPILER> state(info->isolate()); VMState<COMPILER> state(info->isolate());
PostponeInterruptsScope postpone(info->isolate()); PostponeInterruptsScope postpone(info->isolate());
// Parse and update ParseInfo with the results. // Parse and update CompilationInfo with the results.
{ if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>();
if (!parsing::ParseAny(info->parse_info(),
inner_function_mode != Compiler::CONCURRENT)) {
return MaybeHandle<Code>();
}
if (inner_function_mode == Compiler::CONCURRENT) {
ParseHandleScope parse_handles(info->parse_info());
info->parse_info()->ReopenHandlesInNewHandleScope();
info->parse_info()->ast_value_factory()->Internalize(info->isolate());
}
}
if (info->parse_info()->is_toplevel()) { if (info->parse_info()->is_toplevel()) {
EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); EnsureSharedFunctionInfosArrayOnScript(info->parse_info());
} }
...@@ -1169,18 +1134,11 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { ...@@ -1169,18 +1134,11 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
Handle<SharedFunctionInfo> result; Handle<SharedFunctionInfo> result;
{ VMState<COMPILER> state(info->isolate()); { VMState<COMPILER> state(info->isolate());
if (parse_info->literal() == nullptr) { if (parse_info->literal() == nullptr &&
if (!parsing::ParseProgram(parse_info, false)) { !parsing::ParseProgram(parse_info)) {
return Handle<SharedFunctionInfo>::null(); return Handle<SharedFunctionInfo>::null();
} }
{
ParseHandleScope parse_handles(parse_info);
parse_info->ReopenHandlesInNewHandleScope();
parse_info->ast_value_factory()->Internalize(info->isolate());
}
}
EnsureSharedFunctionInfosArrayOnScript(parse_info); EnsureSharedFunctionInfosArrayOnScript(parse_info);
// Measure how long it takes to do the compilation; only take the // Measure how long it takes to do the compilation; only take the
......
...@@ -361,7 +361,8 @@ class V8_EXPORT_PRIVATE CanonicalHandleScope final { ...@@ -361,7 +361,8 @@ class V8_EXPORT_PRIVATE CanonicalHandleScope final {
friend class HandleScope; friend class HandleScope;
}; };
class V8_EXPORT_PRIVATE DeferredHandleScope final {
class DeferredHandleScope final {
public: public:
explicit DeferredHandleScope(Isolate* isolate); explicit DeferredHandleScope(Isolate* isolate);
// The DeferredHandles object returned stores the Handles created // The DeferredHandles object returned stores the Handles created
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include "src/parsing/parse-info.h" #include "src/parsing/parse-info.h"
#include "src/api.h"
#include "src/ast/ast-value-factory.h" #include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h" #include "src/ast/ast.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
...@@ -37,8 +36,7 @@ ParseInfo::ParseInfo(AccountingAllocator* zone_allocator) ...@@ -37,8 +36,7 @@ ParseInfo::ParseInfo(AccountingAllocator* zone_allocator)
cached_data_(nullptr), cached_data_(nullptr),
ast_value_factory_(nullptr), ast_value_factory_(nullptr),
function_name_(nullptr), function_name_(nullptr),
literal_(nullptr), literal_(nullptr) {}
deferred_handles_(nullptr) {}
ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared) ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
: ParseInfo(shared->GetIsolate()->allocator()) { : ParseInfo(shared->GetIsolate()->allocator()) {
...@@ -110,17 +108,6 @@ FunctionKind ParseInfo::function_kind() const { ...@@ -110,17 +108,6 @@ FunctionKind ParseInfo::function_kind() const {
return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_); return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_);
} }
void ParseInfo::set_deferred_handles(
std::shared_ptr<DeferredHandles> deferred_handles) {
DCHECK(deferred_handles_.get() == nullptr);
deferred_handles_.swap(deferred_handles);
}
void ParseInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
DCHECK(deferred_handles_.get() == nullptr);
deferred_handles_.reset(deferred_handles);
}
#ifdef DEBUG #ifdef DEBUG
bool ParseInfo::script_is_native() const { bool ParseInfo::script_is_native() const {
return script_->type() == Script::TYPE_NATIVE; return script_->type() == Script::TYPE_NATIVE;
......
...@@ -22,7 +22,6 @@ class AccountingAllocator; ...@@ -22,7 +22,6 @@ class AccountingAllocator;
class AstRawString; class AstRawString;
class AstValueFactory; class AstValueFactory;
class DeclarationScope; class DeclarationScope;
class DeferredHandles;
class FunctionLiteral; class FunctionLiteral;
class ScriptData; class ScriptData;
class SharedFunctionInfo; class SharedFunctionInfo;
...@@ -46,12 +45,6 @@ class V8_EXPORT_PRIVATE ParseInfo { ...@@ -46,12 +45,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
std::shared_ptr<Zone> zone_shared() const { return zone_; } std::shared_ptr<Zone> zone_shared() const { return zone_; }
void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles);
void set_deferred_handles(DeferredHandles* deferred_handles);
std::shared_ptr<DeferredHandles> deferred_handles() const {
return deferred_handles_;
}
// Convenience accessor methods for flags. // Convenience accessor methods for flags.
#define FLAG_ACCESSOR(flag, getter, setter) \ #define FLAG_ACCESSOR(flag, getter, setter) \
bool getter() const { return GetFlag(flag); } \ bool getter() const { return GetFlag(flag); } \
...@@ -208,12 +201,8 @@ class V8_EXPORT_PRIVATE ParseInfo { ...@@ -208,12 +201,8 @@ class V8_EXPORT_PRIVATE ParseInfo {
} }
void ReopenHandlesInNewHandleScope() { void ReopenHandlesInNewHandleScope() {
if (!script_.is_null()) {
script_ = Handle<Script>(*script_);
}
if (!shared_.is_null()) {
shared_ = Handle<SharedFunctionInfo>(*shared_); shared_ = Handle<SharedFunctionInfo>(*shared_);
} script_ = Handle<Script>(*script_);
Handle<ScopeInfo> outer_scope_info; Handle<ScopeInfo> outer_scope_info;
if (maybe_outer_scope_info_.ToHandle(&outer_scope_info)) { if (maybe_outer_scope_info_.ToHandle(&outer_scope_info)) {
maybe_outer_scope_info_ = Handle<ScopeInfo>(*outer_scope_info); maybe_outer_scope_info_ = Handle<ScopeInfo>(*outer_scope_info);
...@@ -277,7 +266,6 @@ class V8_EXPORT_PRIVATE ParseInfo { ...@@ -277,7 +266,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
//----------- Output of parsing and scope analysis ------------------------ //----------- Output of parsing and scope analysis ------------------------
FunctionLiteral* literal_; FunctionLiteral* literal_;
std::shared_ptr<DeferredHandles> deferred_handles_;
void SetFlag(Flag f) { flags_ |= f; } void SetFlag(Flag f) { flags_ |= f; }
void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; } void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
......
...@@ -3361,18 +3361,21 @@ void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) { ...@@ -3361,18 +3361,21 @@ void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
} }
} }
void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) {
void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
// Internalize strings and values.
ast_value_factory()->Internalize(isolate);
// Error processing.
if (error) {
if (stack_overflow()) { if (stack_overflow()) {
isolate->StackOverflow(); isolate->StackOverflow();
} else { } else {
DCHECK(pending_error_handler_.has_pending_error()); DCHECK(pending_error_handler_.has_pending_error());
// Internalize ast values for throwing the pending error.
ast_value_factory()->Internalize(isolate);
pending_error_handler_.ThrowPendingError(isolate, script); pending_error_handler_.ThrowPendingError(isolate, script);
} }
} }
void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
// Move statistics to Isolate. // Move statistics to Isolate.
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) { ++feature) {
......
...@@ -222,17 +222,16 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -222,17 +222,16 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void DeserializeScopeChain(ParseInfo* info, void DeserializeScopeChain(ParseInfo* info,
MaybeHandle<ScopeInfo> maybe_outer_scope_info); MaybeHandle<ScopeInfo> maybe_outer_scope_info);
// Handle errors detected during parsing // Handle errors detected during parsing, move statistics to Isolate,
void ReportErrors(Isolate* isolate, Handle<Script> script); // internalize strings (move them to the heap).
// Move statistics to Isolate void Internalize(Isolate* isolate, Handle<Script> script, bool error);
void UpdateStatistics(Isolate* isolate, Handle<Script> script);
void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
private: private:
friend class ParserBase<Parser>; friend class ParserBase<Parser>;
friend class v8::internal::ExpressionClassifier<ParserTypes<Parser>>; friend class v8::internal::ExpressionClassifier<ParserTypes<Parser>>;
friend bool v8::internal::parsing::ParseProgram(ParseInfo*, bool); friend bool v8::internal::parsing::ParseProgram(ParseInfo*);
friend bool v8::internal::parsing::ParseFunction(ParseInfo*, bool); friend bool v8::internal::parsing::ParseFunction(ParseInfo*);
bool AllowsLazyParsingWithoutUnresolvedVariables() const { bool AllowsLazyParsingWithoutUnresolvedVariables() const {
return scope()->AllowsLazyParsingWithoutUnresolvedVariables( return scope()->AllowsLazyParsingWithoutUnresolvedVariables(
......
...@@ -15,7 +15,7 @@ namespace v8 { ...@@ -15,7 +15,7 @@ namespace v8 {
namespace internal { namespace internal {
namespace parsing { namespace parsing {
bool ParseProgram(ParseInfo* info, bool internalize) { bool ParseProgram(ParseInfo* info) {
DCHECK(info->is_toplevel()); DCHECK(info->is_toplevel());
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
...@@ -29,19 +29,14 @@ bool ParseProgram(ParseInfo* info, bool internalize) { ...@@ -29,19 +29,14 @@ bool ParseProgram(ParseInfo* info, bool internalize) {
parser.SetCachedData(info); parser.SetCachedData(info);
result = parser.ParseProgram(isolate, info); result = parser.ParseProgram(isolate, info);
info->set_literal(result); info->set_literal(result);
if (result == nullptr) { parser.Internalize(isolate, info->script(), result == nullptr);
parser.ReportErrors(isolate, info->script()); if (result != nullptr) {
} else {
info->set_language_mode(info->literal()->language_mode()); info->set_language_mode(info->literal()->language_mode());
} }
parser.UpdateStatistics(isolate, info->script());
if (internalize) {
info->ast_value_factory()->Internalize(isolate);
}
return (result != nullptr); return (result != nullptr);
} }
bool ParseFunction(ParseInfo* info, bool internalize) { bool ParseFunction(ParseInfo* info) {
DCHECK(!info->is_toplevel()); DCHECK(!info->is_toplevel());
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
...@@ -54,19 +49,12 @@ bool ParseFunction(ParseInfo* info, bool internalize) { ...@@ -54,19 +49,12 @@ bool ParseFunction(ParseInfo* info, bool internalize) {
result = parser.ParseFunction(isolate, info); result = parser.ParseFunction(isolate, info);
info->set_literal(result); info->set_literal(result);
if (result == nullptr) { parser.Internalize(isolate, info->script(), result == nullptr);
parser.ReportErrors(isolate, info->script());
}
parser.UpdateStatistics(isolate, info->script());
if (internalize) {
info->ast_value_factory()->Internalize(isolate);
}
return (result != nullptr); return (result != nullptr);
} }
bool ParseAny(ParseInfo* info, bool internalize) { bool ParseAny(ParseInfo* info) {
return info->is_toplevel() ? ParseProgram(info, internalize) return info->is_toplevel() ? ParseProgram(info) : ParseFunction(info);
: ParseFunction(info, internalize);
} }
} // namespace parsing } // namespace parsing
......
...@@ -16,18 +16,16 @@ namespace parsing { ...@@ -16,18 +16,16 @@ namespace parsing {
// Parses the top-level source code represented by the parse info and sets its // Parses the top-level source code represented by the parse info and sets its
// function literal. Returns false (and deallocates any allocated AST // function literal. Returns false (and deallocates any allocated AST
// nodes) if parsing failed. Internalizes AST nodes on the heap if // nodes) if parsing failed.
// |internalize|. V8_EXPORT_PRIVATE bool ParseProgram(ParseInfo* info);
V8_EXPORT_PRIVATE bool ParseProgram(ParseInfo* info, bool internalize = true);
// Like ParseProgram but for an individual function. Internalizes AST nodes on // Like ParseProgram but for an individual function.
// the heap if |internalize|. V8_EXPORT_PRIVATE bool ParseFunction(ParseInfo* info);
V8_EXPORT_PRIVATE bool ParseFunction(ParseInfo* info, bool internalize = true);
// If you don't know whether info->is_toplevel() is true or not, use this method // If you don't know whether info->is_toplevel() is true or not, use this method
// to dispatch to either of the above functions. Prefer to use the above methods // to dispatch to either of the above functions. Prefer to use the above methods
// whenever possible. Internalizes AST nodes on the heap if |internalize|. // whenever possible.
V8_EXPORT_PRIVATE bool ParseAny(ParseInfo* info, bool internalize = true); V8_EXPORT_PRIVATE bool ParseAny(ParseInfo* info);
} // namespace parsing } // namespace parsing
} // namespace internal } // namespace internal
......
...@@ -22,6 +22,7 @@ Handle<String> PendingCompilationErrorHandler::ArgumentString( ...@@ -22,6 +22,7 @@ Handle<String> PendingCompilationErrorHandler::ArgumentString(
->NewStringFromUtf8(CStrVector(char_arg_)) ->NewStringFromUtf8(CStrVector(char_arg_))
.ToHandleChecked(); .ToHandleChecked();
} }
if (!handle_arg_.is_null()) return handle_arg_;
return isolate->factory()->undefined_string(); return isolate->factory()->undefined_string();
} }
......
...@@ -58,6 +58,20 @@ class PendingCompilationErrorHandler { ...@@ -58,6 +58,20 @@ class PendingCompilationErrorHandler {
error_type_ = error_type; error_type_ = error_type;
} }
void ReportMessageAt(int start_position, int end_position,
MessageTemplate::Template message, Handle<String> arg,
ParseErrorType error_type = kSyntaxError) {
if (has_pending_error_) return;
has_pending_error_ = true;
start_position_ = start_position;
end_position_ = end_position;
message_ = message;
char_arg_ = nullptr;
arg_ = nullptr;
handle_arg_ = arg;
error_type_ = error_type;
}
bool has_pending_error() const { return has_pending_error_; } bool has_pending_error() const { return has_pending_error_; }
void ThrowPendingError(Isolate* isolate, Handle<Script> script); void ThrowPendingError(Isolate* isolate, Handle<Script> script);
...@@ -72,6 +86,7 @@ class PendingCompilationErrorHandler { ...@@ -72,6 +86,7 @@ class PendingCompilationErrorHandler {
MessageTemplate::Template message_; MessageTemplate::Template message_;
const AstRawString* arg_; const AstRawString* arg_;
const char* char_arg_; const char* char_arg_;
Handle<String> handle_arg_;
ParseErrorType error_type_; ParseErrorType error_type_;
DISALLOW_COPY_AND_ASSIGN(PendingCompilationErrorHandler); DISALLOW_COPY_AND_ASSIGN(PendingCompilationErrorHandler);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "src/handles.h" #include "src/handles.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/parsing/parse-info.h" #include "src/parsing/parse-info.h"
#include "src/parsing/parsing.h"
#include "src/v8.h" #include "src/v8.h"
#include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h" #include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h"
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
...@@ -817,11 +816,9 @@ TEST_F(CompilerDispatcherTest, EnqueueParsed) { ...@@ -817,11 +816,9 @@ TEST_F(CompilerDispatcherTest, EnqueueParsed) {
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info)); ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info));
std::shared_ptr<DeferredHandles> handles;
ASSERT_FALSE(dispatcher.IsEnqueued(shared)); ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.Enqueue(shared, parse_info.literal(), ASSERT_TRUE(dispatcher.Enqueue(shared, parse_info.literal()));
parse_info.zone_shared(), handles, handles));
ASSERT_TRUE(dispatcher.IsEnqueued(shared)); ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.jobs_.begin()->second->status() == ASSERT_TRUE(dispatcher.jobs_.begin()->second->status() ==
...@@ -844,12 +841,9 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepParsed) { ...@@ -844,12 +841,9 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepParsed) {
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info)); ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info));
std::shared_ptr<DeferredHandles> handles;
ASSERT_FALSE(dispatcher.IsEnqueued(shared)); ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.EnqueueAndStep(shared, parse_info.literal(), ASSERT_TRUE(dispatcher.EnqueueAndStep(shared, parse_info.literal()));
parse_info.zone_shared(), handles,
handles));
ASSERT_TRUE(dispatcher.IsEnqueued(shared)); ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.jobs_.begin()->second->status() == ASSERT_TRUE(dispatcher.jobs_.begin()->second->status() ==
...@@ -883,9 +877,7 @@ TEST_F(CompilerDispatcherTest, FinishAllNow) { ...@@ -883,9 +877,7 @@ TEST_F(CompilerDispatcherTest, FinishAllNow) {
// Enqueue shared1 as already parsed. // Enqueue shared1 as already parsed.
ParseInfo parse_info(shared1); ParseInfo parse_info(shared1);
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info)); ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info));
std::shared_ptr<DeferredHandles> handles; ASSERT_TRUE(dispatcher.Enqueue(shared1, parse_info.literal()));
ASSERT_TRUE(dispatcher.Enqueue(shared1, parse_info.literal(),
parse_info.zone_shared(), handles, handles));
// Enqueue shared2 for parsing and compiling // Enqueue shared2 for parsing and compiling
ASSERT_TRUE(dispatcher.Enqueue(shared2)); ASSERT_TRUE(dispatcher.Enqueue(shared2));
...@@ -901,43 +893,5 @@ TEST_F(CompilerDispatcherTest, FinishAllNow) { ...@@ -901,43 +893,5 @@ TEST_F(CompilerDispatcherTest, FinishAllNow) {
platform.ClearIdleTask(); platform.ClearIdleTask();
} }
TEST_F(CompilerDispatcherTest, CompileParsedOutOfScope) {
MockPlatform platform;
CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
const char script[] =
"function g() { var y = 1; function f20(x) { return x + y }; return f20; "
"} g();";
Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
{
HandleScope scope(i_isolate()); // Create handles scope for parsing.
ASSERT_FALSE(shared->is_compiled());
ParseInfo parse_info(shared);
ASSERT_TRUE(parsing::ParseAny(&parse_info));
DeferredHandleScope handles_scope(i_isolate());
{ ASSERT_TRUE(Compiler::Analyze(&parse_info)); }
std::shared_ptr<DeferredHandles> compilation_handles(
handles_scope.Detach());
ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(dispatcher.Enqueue(
shared, parse_info.literal(), parse_info.zone_shared(),
parse_info.deferred_handles(), compilation_handles));
ASSERT_TRUE(platform.IdleTaskPending());
}
// Exit the handles scope and destroy ParseInfo before running the idle task.
// Since time doesn't progress on the MockPlatform, this is enough idle time
// to finish compiling the function.
platform.RunIdleTask(1000.0, 0.0);
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(shared->is_compiled());
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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