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