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

[Parsing] Remove parse-task support.

Parse tasks are not currently used, and will need to be changed significantly
for background compilation, so we remove them for now.

BUG=v8:6093,v8:5203

Change-Id: I44559a94ecca85668f0117629d35aaa5f4075745
Reviewed-on: https://chromium-review.googlesource.com/617140
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47446}
parent 56772de7
......@@ -313,23 +313,6 @@ bool FunctionLiteral::NeedsHomeObject(Expression* expr) {
return expr->AsFunctionLiteral()->scope()->NeedsHomeObject();
}
void FunctionLiteral::ReplaceBodyAndScope(FunctionLiteral* other) {
DCHECK_NULL(body_);
DCHECK_NOT_NULL(scope_);
DCHECK_NOT_NULL(other->scope());
Scope* outer_scope = scope_->outer_scope();
body_ = other->body();
scope_ = other->scope();
scope_->ReplaceOuterScope(outer_scope);
#ifdef DEBUG
scope_->set_replaced_from_parse_task(true);
#endif
function_length_ = other->function_length_;
}
ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
Kind kind, bool is_computed_name)
: LiteralProperty(key, value, is_computed_name),
......
......@@ -2623,8 +2623,6 @@ class FunctionLiteral final : public Expression {
return produced_preparsed_scope_data_;
}
void ReplaceBodyAndScope(FunctionLiteral* other);
private:
friend class AstNodeFactory;
......
......@@ -1811,9 +1811,6 @@ void Scope::CheckZones() {
DCHECK_NULL(scope->inner_scope_);
continue;
}
if (!scope->replaced_from_parse_task()) {
CHECK_EQ(scope->zone(), zone());
}
scope->CheckZones();
}
}
......
......@@ -461,11 +461,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// Check that all Scopes in the scope tree use the same Zone.
void CheckZones();
bool replaced_from_parse_task() const { return replaced_from_parse_task_; }
void set_replaced_from_parse_task(bool replaced_from_parse_task) {
replaced_from_parse_task_ = replaced_from_parse_task;
}
#endif
// Retrieve `IsSimpleParameterList` of current or outer function.
......@@ -550,10 +545,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// True if this scope may contain objects from a temp zone that needs to be
// fixed up.
bool needs_migration_;
// True if scope comes from other zone - as a result of being created in a
// parse tasks.
bool replaced_from_parse_task_ = false;
#endif
// Source positions.
......
......@@ -253,33 +253,6 @@ bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
return true;
}
bool CompilerDispatcher::Enqueue(
Handle<String> source, int start_position, int end_position,
LanguageMode language_mode, int function_literal_id, bool native,
bool module, bool is_named_expression, int compiler_hints,
UnoptimizedCompileJobFinishCallback* finish_callback, JobId* job_id) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompilerDispatcherEnqueue");
if (!CanEnqueue()) return false;
if (trace_compiler_dispatcher_) {
PrintF("CompilerDispatcher: enqueuing function at %d for initial parse\n",
start_position);
}
std::unique_ptr<CompilerDispatcherJob> job(new UnoptimizedCompileJob(
isolate_->thread_id().ToInteger(), tracer_.get(), max_stack_size_, source,
start_position, end_position, language_mode, function_literal_id, native,
module, is_named_expression, isolate_->heap()->HashSeed(),
isolate_->allocator(), compiler_hints, isolate_->ast_string_constants(),
finish_callback));
JobId id = Enqueue(std::move(job));
if (job_id != nullptr) {
*job_id = id;
}
return true;
}
bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> function) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompilerDispatcherEnqueueAndStep");
......
......@@ -31,7 +31,6 @@ class AstValueFactory;
class CancelableTaskManager;
class CompilerDispatcherJob;
class UnoptimizedCompileJob;
class UnoptimizedCompileJobFinishCallback;
class CompilerDispatcherTracer;
class DeferredHandles;
class FunctionLiteral;
......@@ -85,13 +84,6 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Enqueue a job for parse and compile. Returns true if a job was enqueued.
bool Enqueue(Handle<SharedFunctionInfo> function);
// Enqueue a job for initial parse. Returns true if a job was enqueued.
bool Enqueue(Handle<String> source, int start_pos, int end_position,
LanguageMode language_mode, int function_literal_id, bool native,
bool module, bool is_named_expression, int compiler_hints,
UnoptimizedCompileJobFinishCallback* finish_callback,
JobId* job_id);
// 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.
......
......@@ -62,54 +62,6 @@ class TwoByteWrapper : public v8::String::ExternalStringResource {
} // namespace
UnoptimizedCompileJob::UnoptimizedCompileJob(
int main_thread_id, CompilerDispatcherTracer* tracer, size_t max_stack_size,
Handle<String> source, int start_position, int end_position,
LanguageMode language_mode, int function_literal_id, bool native,
bool module, bool is_named_expression, uint32_t hash_seed,
AccountingAllocator* zone_allocator, int compiler_hints,
const AstStringConstants* ast_string_constants,
UnoptimizedCompileJobFinishCallback* finish_callback)
: status_(Status::kReadyToParse),
main_thread_id_(main_thread_id),
tracer_(tracer),
max_stack_size_(max_stack_size),
finish_callback_(finish_callback),
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
parse_info_.reset(new ParseInfo(zone_allocator));
DCHECK(source->IsExternalTwoByteString() ||
source->IsExternalOneByteString());
character_stream_.reset(
ScannerStream::For(source, start_position, end_position));
parse_info_->set_character_stream(character_stream_.get());
parse_info_->set_hash_seed(hash_seed);
parse_info_->set_compiler_hints(compiler_hints);
parse_info_->set_start_position(start_position);
parse_info_->set_end_position(end_position);
unicode_cache_.reset(new UnicodeCache());
parse_info_->set_unicode_cache(unicode_cache_.get());
parse_info_->set_language_mode(language_mode);
parse_info_->set_function_literal_id(function_literal_id);
parse_info_->set_ast_string_constants(ast_string_constants);
if (V8_UNLIKELY(FLAG_runtime_stats)) {
parse_info_->set_runtime_call_stats(new (parse_info_->zone())
RuntimeCallStats());
}
parse_info_->set_native(native);
parse_info_->set_module(module);
parse_info_->set_is_named_expression(is_named_expression);
parser_.reset(new Parser(parse_info_.get()));
parser_->DeserializeScopeChain(parse_info_.get(), MaybeHandle<ScopeInfo>());
if (trace_compiler_dispatcher_jobs_) {
PrintF("UnoptimizedCompileJob[%p] created for ", static_cast<void*>(this));
ShortPrintOnMainThread();
PrintF(" in ready to parse state.\n");
}
}
UnoptimizedCompileJob::UnoptimizedCompileJob(Isolate* isolate,
CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared,
......@@ -134,7 +86,6 @@ UnoptimizedCompileJob::UnoptimizedCompileJob(Isolate* isolate,
UnoptimizedCompileJob::~UnoptimizedCompileJob() {
DCHECK(status_ == Status::kInitial ||
(status_ == Status::kReadyToParse && finish_callback_) ||
status_ == Status::kDone);
if (!shared_.is_null()) {
DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_);
......@@ -335,13 +286,7 @@ void UnoptimizedCompileJob::Parse() {
parser_->set_stack_limit(stack_limit);
parser_->ParseOnBackground(parse_info_.get());
if (finish_callback_) {
finish_callback_->ParseFinished(std::move(parse_info_));
status_ = Status::kDone;
} else {
status_ = Status::kParsed;
}
status_ = Status::kParsed;
}
void UnoptimizedCompileJob::FinalizeParsingOnMainThread(Isolate* isolate) {
......@@ -491,7 +436,6 @@ void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) {
unicode_cache_.reset();
character_stream_.reset();
parse_info_.reset();
finish_callback_ = nullptr;
if (!source_.is_null()) {
DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_);
......@@ -543,16 +487,8 @@ double UnoptimizedCompileJob::EstimateRuntimeOfNextStepInMs() const {
void UnoptimizedCompileJob::ShortPrintOnMainThread() {
DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_);
if (!shared_.is_null()) {
shared_->ShortPrint();
} else {
// TODO(wiktorg) more useful info in those cases
if (parse_info_) {
PrintF("function at %d", parse_info_->start_position());
} else {
PrintF("parsed function");
}
}
DCHECK(!shared_.is_null());
shared_->ShortPrint();
}
} // namespace internal
......
......@@ -30,12 +30,6 @@ class String;
class UnicodeCache;
class Utf16CharacterStream;
class V8_EXPORT_PRIVATE UnoptimizedCompileJobFinishCallback {
public:
virtual ~UnoptimizedCompileJobFinishCallback() {}
virtual void ParseFinished(std::unique_ptr<ParseInfo> parse_info) = 0;
};
class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
public:
enum class Status {
......@@ -54,18 +48,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
UnoptimizedCompileJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared,
size_t max_stack_size);
// TODO(wiktorg) document it better once I know how it relates to whole stuff
// Creates a UnoptimizedCompileJob in ready to parse top-level function state.
UnoptimizedCompileJob(int main_thread_id, CompilerDispatcherTracer* tracer,
size_t max_stack_size, Handle<String> source,
int start_position, int end_position,
LanguageMode language_mode, int function_literal_id,
bool native, bool module, bool is_named_expression,
uint32_t hash_seed, AccountingAllocator* zone_allocator,
int compiler_hints,
const AstStringConstants* ast_string_constants,
UnoptimizedCompileJobFinishCallback* finish_callback);
~UnoptimizedCompileJob() override;
Type type() const override { return kUnoptimizedCompile; }
......@@ -122,7 +104,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
Handle<String> wrapper_; // Global handle.
std::unique_ptr<v8::String::ExternalStringResourceBase> source_wrapper_;
size_t max_stack_size_;
UnoptimizedCompileJobFinishCallback* finish_callback_ = nullptr;
// Members required for parsing.
std::unique_ptr<UnicodeCache> unicode_cache_;
......@@ -138,8 +119,7 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
// Transition from kInitial to kReadyToParse.
void PrepareToParseOnMainThread(Isolate* isolate);
// Transition from kReadyToParse to kParsed (or kDone if there is
// finish_callback).
// Transition from kReadyToParse to kParsed.
void Parse();
// Transition from kParsed to kReadyToAnalyze (or kFailed).
......
......@@ -882,11 +882,6 @@ DEFINE_BOOL(trace_for_in_enumerate, false, "Trace for-in enumerate slow-paths")
DEFINE_BOOL(trace_maps, false, "trace map creation")
#endif
// preparser.cc
DEFINE_BOOL(use_parse_tasks, false, "use parse tasks")
DEFINE_BOOL(trace_parse_tasks, false, "trace parse task creation")
DEFINE_NEG_IMPLICATION(use_parse_tasks, preparser_scope_analysis)
// parser.cc
DEFINE_BOOL(allow_natives_syntax, false, "allow natives syntax")
DEFINE_BOOL(trace_parse, false, "trace parsing and preparsing")
......
......@@ -170,24 +170,6 @@ void ParseInfo::UpdateStatisticsAfterBackgroundParse(Isolate* isolate) {
set_runtime_call_stats(main_call_stats);
}
void ParseInfo::ParseFinished(std::unique_ptr<ParseInfo> info) {
if (info->literal()) {
base::LockGuard<base::Mutex> access_child_infos(&child_infos_mutex_);
child_infos_.emplace_back(std::move(info));
}
}
std::map<int, ParseInfo*> ParseInfo::child_infos() const {
base::LockGuard<base::Mutex> access_child_infos(&child_infos_mutex_);
std::map<int, ParseInfo*> rv;
for (const auto& child_info : child_infos_) {
DCHECK_NOT_NULL(child_info->literal());
int start_position = child_info->literal()->start_position();
rv.insert(std::make_pair(start_position, child_info.get()));
}
return rv;
}
void ParseInfo::ShareZone(ParseInfo* other) {
DCHECK_EQ(0, zone_->allocation_size());
zone_ = other->zone_;
......
......@@ -10,7 +10,6 @@
#include <vector>
#include "include/v8.h"
#include "src/compiler-dispatcher/unoptimized-compile-job.h"
#include "src/globals.h"
#include "src/handles.h"
#include "src/parsing/preparsed-scope-data.h"
......@@ -35,7 +34,7 @@ class Utf16CharacterStream;
class Zone;
// A container for the inputs, configuration options, and outputs of parsing.
class V8_EXPORT_PRIVATE ParseInfo : public UnoptimizedCompileJobFinishCallback {
class V8_EXPORT_PRIVATE ParseInfo {
public:
explicit ParseInfo(AccountingAllocator* zone_allocator);
ParseInfo(Handle<Script> script);
......@@ -250,11 +249,6 @@ class V8_EXPORT_PRIVATE ParseInfo : public UnoptimizedCompileJobFinishCallback {
void UpdateStatisticsAfterBackgroundParse(Isolate* isolate);
// The key of the map is the FunctionLiteral's start_position
std::map<int, ParseInfo*> child_infos() const;
void ParseFinished(std::unique_ptr<ParseInfo> info) override;
private:
// Various configuration flags for parsing.
enum Flag {
......@@ -313,9 +307,6 @@ class V8_EXPORT_PRIVATE ParseInfo : public UnoptimizedCompileJobFinishCallback {
FunctionLiteral* literal_;
std::shared_ptr<DeferredHandles> deferred_handles_;
std::vector<std::unique_ptr<ParseInfo>> child_infos_;
mutable base::Mutex child_infos_mutex_;
void SetFlag(Flag f) { flags_ |= f; }
void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
bool GetFlag(Flag f) const { return (flags_ & f) != 0; }
......
......@@ -587,12 +587,6 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
source = String::Flatten(source);
FunctionLiteral* result;
if (FLAG_use_parse_tasks) {
source_ = source;
compiler_dispatcher_ = isolate->compiler_dispatcher();
main_parse_info_ = info;
}
{
std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
scanner_.Initialize(stream.get(), info->is_module());
......@@ -603,14 +597,6 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
}
HandleSourceURLComments(isolate, info->script());
if (FLAG_use_parse_tasks) {
compiler_dispatcher_->FinishAllNow();
StitchAst(info, isolate);
source_ = Handle<String>();
compiler_dispatcher_ = nullptr;
main_parse_info_ = nullptr;
}
if (FLAG_trace_parse && result != nullptr) {
double ms = timer.Elapsed().InMillisecondsF();
if (info->is_eval()) {
......@@ -771,8 +757,7 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
source, shared_info->start_position(), shared_info->end_position()));
Handle<String> name(shared_info->name());
scanner_.Initialize(stream.get(), info->is_module());
info->set_function_name(ast_value_factory()->GetString(name));
result = DoParseFunction(info);
result = DoParseFunction(info, ast_value_factory()->GetString(name));
if (result != nullptr) {
Handle<String> inferred_name(shared_info->inferred_name());
result->set_inferred_name(inferred_name);
......@@ -801,30 +786,8 @@ static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
return FunctionLiteral::kAnonymousExpression;
}
FunctionLiteral* Parser::DoParseFunction(ParseInfo* info) {
const AstRawString* raw_name = info->function_name();
FunctionNameValidity function_name_validity = kSkipFunctionNameCheck;
if (!raw_name) {
bool ok = true;
if (peek() == Token::LPAREN) {
const AstRawString* variable_name;
impl()->GetDefaultStrings(&raw_name, &variable_name);
} else {
bool is_strict_reserved = true;
bool is_await = false;
raw_name = ParseIdentifierOrStrictReservedWord(
info->function_kind(), &is_strict_reserved, &is_await, &ok);
if (!ok) return nullptr;
// If the function name is "await", ParseIdentifierOrStrictReservedWord
// recognized the error.
DCHECK(!is_await);
function_name_validity = is_strict_reserved
? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown;
}
}
FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
const AstRawString* raw_name) {
DCHECK_NOT_NULL(raw_name);
DCHECK_NULL(scope_);
DCHECK_NULL(target_stack_);
......@@ -946,7 +909,7 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info) {
info->start_position(), info->end_position());
} else {
result = ParseFunctionLiteral(
raw_name, Scanner::Location::invalid(), function_name_validity, kind,
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
kNoSourcePosition, function_type, info->language_mode(), &ok);
}
// Make sure the results agree.
......@@ -2582,16 +2545,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
const bool source_is_external =
!source_.is_null() && (source_->IsExternalTwoByteString() ||
source_->IsExternalOneByteString());
const bool is_lazy =
eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
const bool is_top_level =
impl()->AllowsLazyParsingWithoutUnresolvedVariables();
const bool is_lazy_top_level_function = is_lazy && is_top_level;
const bool is_lazy_inner_function = is_lazy && !is_top_level;
const bool is_eager_top_level_function = !is_lazy && is_top_level;
const bool is_expression =
function_type == FunctionLiteral::kAnonymousExpression ||
function_type == FunctionLiteral::kNamedExpression;
......@@ -2623,14 +2582,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
(!is_expression || FLAG_aggressive_lazy_inner_functions);
bool should_use_parse_task =
FLAG_use_parse_tasks && parse_lazily() && compiler_dispatcher_ &&
is_eager_top_level_function && source_is_external;
// This may be modified later to reflect preparsing decision taken
bool should_preparse = (parse_lazily() && (is_lazy_top_level_function ||
should_use_parse_task)) ||
should_preparse_inner;
bool should_preparse =
(parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
ZoneList<Statement*>* body = nullptr;
int expected_property_count = -1;
......@@ -2641,33 +2595,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
int function_literal_id = GetNextFunctionLiteralId();
ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
Expect(Token::LPAREN, CHECK_OK);
if (should_use_parse_task) {
int start_pos = scanner()->location().beg_pos;
if (function_name_location.IsValid()) {
start_pos = function_name_location.beg_pos;
}
// Warning!
// Only sets fields in compiler_hints that are currently used.
int compiler_hints = SharedFunctionInfo::FunctionKindBits::encode(kind);
if (function_type == FunctionLiteral::kDeclaration) {
compiler_hints |= SharedFunctionInfo::IsDeclarationBit::encode(true);
}
should_use_parse_task = compiler_dispatcher_->Enqueue(
source_, start_pos, source_->length(), language_mode,
function_literal_id, allow_natives(), parsing_module_,
function_type == FunctionLiteral::kNamedExpression, compiler_hints,
main_parse_info_, nullptr);
if (V8_UNLIKELY(FLAG_trace_parse_tasks)) {
PrintF("Spining off task for function at %d: %s\n", start_pos,
should_use_parse_task ? "SUCCESS" : "FAILED");
}
if (!should_use_parse_task) {
should_preparse = false;
}
}
Zone* outer_zone = zone();
DeclarationScope* scope;
......@@ -2692,6 +2619,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
scope->SetScopeName(function_name);
if (should_preparse) scope->set_needs_migration();
#endif
Expect(Token::LPAREN, CHECK_OK);
scope->set_start_position(scanner()->location().beg_pos);
// Eager or lazy parse? If is_lazy_top_level_function, we'll parse
......@@ -2701,8 +2630,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// try to lazy parse in the first place, we'll have to parse eagerly.
if (should_preparse) {
DCHECK(parse_lazily());
DCHECK(is_lazy_top_level_function || is_lazy_inner_function ||
should_use_parse_task);
DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
Scanner::BookmarkScope bookmark(scanner());
bookmark.Set();
LazyParsingResult result = SkipFunction(
......@@ -2722,7 +2650,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
zone_scope.Reset();
// Trigger eager (re-)parsing, just below this block.
should_preparse = false;
should_use_parse_task = false;
}
}
......@@ -2783,9 +2710,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
function_name, scope, body, expected_property_count, num_parameters,
function_length, duplicate_parameters, function_type, eager_compile_hint,
pos, true, function_literal_id, produced_preparsed_scope_data);
if (should_use_parse_task) {
literals_to_stitch_.emplace_back(function_literal);
}
function_literal->set_function_token_position(function_token_pos);
if (should_be_used_once_hint)
function_literal->set_should_be_used_once_hint();
......@@ -3491,7 +3415,7 @@ void Parser::ParseOnBackground(ParseInfo* info) {
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
result = DoParseProgram(info);
} else {
result = DoParseFunction(info);
result = DoParseFunction(info, info->function_name());
}
info->set_literal(result);
......@@ -4554,41 +4478,6 @@ Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
return final_loop;
}
void Parser::StitchAst(ParseInfo* top_level_parse_info, Isolate* isolate) {
if (literals_to_stitch_.empty()) return;
std::map<int, ParseInfo*> child_infos = top_level_parse_info->child_infos();
DCHECK(std::is_sorted(literals_to_stitch_.begin(), literals_to_stitch_.end(),
[](FunctionLiteral* a, FunctionLiteral* b) {
return a->start_position() < b->start_position();
}));
auto it = literals_to_stitch_.begin();
for (auto& child_info : child_infos) {
ParseInfo* result = child_info.second;
// If the parse task failed the function will be treated as lazy function
// and reparsed before it gets called
if (!result) continue;
result->UpdateStatisticsAfterBackgroundParse(isolate);
if (!result->literal()) continue;
while ((*it)->start_position() != child_info.first) {
if (++it == literals_to_stitch_.end()) {
return;
}
}
FunctionLiteral* literal = *it;
// FIXME(wiktorg) better handling of default params for arrow functions
Scope* outer_scope = literal->scope()->outer_scope();
if (outer_scope->is_declaration_scope() &&
outer_scope->AsDeclarationScope()->was_lazily_parsed()) {
continue;
}
// TODO(wiktorg) in the future internalize somewhere else (stitching may be
// done on streamer thread)
result->ast_value_factory()->Internalize(isolate);
literal->ReplaceBodyAndScope(result->literal());
literal->SetShouldEagerCompile();
}
}
#undef CHECK_OK
#undef CHECK_OK_VOID
#undef CHECK_FAILED
......
......@@ -262,7 +262,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<SharedFunctionInfo> shared_info);
FunctionLiteral* DoParseFunction(ParseInfo* info);
FunctionLiteral* DoParseFunction(ParseInfo* info,
const AstRawString* raw_name);
// Called by ParseProgram after setting up the scanner.
FunctionLiteral* DoParseProgram(ParseInfo* info);
......@@ -1124,11 +1125,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
PreParser* reusable_preparser_;
Mode mode_;
std::vector<FunctionLiteral*> literals_to_stitch_;
Handle<String> source_;
CompilerDispatcher* compiler_dispatcher_ = nullptr;
ParseInfo* main_parse_info_ = nullptr;
SourceRangeMap* source_range_map_ = nullptr;
friend class ParserTarget;
......
......@@ -301,8 +301,6 @@ TEST(UsingCachedData) {
TEST(PreparseFunctionDataIsUsed) {
// Producing cached parser data while parsing eagerly is not supported.
if (!i::FLAG_lazy) return;
// Test does not apply if parse tasks are used.
if (i::FLAG_use_parse_tasks) return;
// This tests that we actually do use the function data generated by the
// preparser.
......@@ -513,8 +511,6 @@ TEST(RegressChromium62639) {
TEST(Regress928) {
// Test only applies when lazy parsing.
if (!i::FLAG_lazy) return;
// Test does not apply if parse tasks are used
if (i::FLAG_use_parse_tasks) return;
// Tests that the first non-toplevel function is not included in the preparse
// data.
......@@ -2438,9 +2434,6 @@ TEST(DontRegressPreParserDataSizes) {
// These tests make sure that Parser doesn't start producing less "preparse
// data" (data which the embedder can cache).
// Test does not apply if parse tasks are used.
if (i::FLAG_use_parse_tasks) return;
v8::V8::Initialize();
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --compiler-dispatcher --use-parse-tasks --use-external-strings
(function(a) {
assertEquals(a, "IIFE");
})("IIFE");
(function(a, ...rest) {
assertEquals(a, 1);
assertEquals(rest.length, 2);
assertEquals(rest[0], 2);
assertEquals(rest[1], 3);
})(1,2,3);
var outer_var = 42;
function lazy_outer() {
return 42;
}
var eager_outer = (function() { return 42; });
(function() {
assertEquals(outer_var, 42);
assertEquals(lazy_outer(), 42);
assertEquals(eager_outer(), 42);
})();
var gen = (function*() {
yield 1;
yield 2;
})();
assertEquals(gen.next().value, 1);
assertEquals(gen.next().value, 2);
var result = (function recursive(a=0) {
if (a == 1) {
return 42;
}
return recursive(1);
})();
assertEquals(result, 42);
var a = 42;
var b;
var c = (a, b = (function z(){ return a+1; })());
assertEquals(b, 43);
assertEquals(c, 43);
var c = (a, b = (function z(){ return a+1; })()) => { return b; };
assertEquals(c(314), 315);
......@@ -12,6 +12,7 @@
#include "src/base/platform/semaphore.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
#include "src/compiler-dispatcher/unoptimized-compile-job.h"
#include "src/compiler.h"
#include "src/flags.h"
#include "src/handles.h"
......@@ -294,8 +295,6 @@ class MockPlatform : public v8::Platform {
DISALLOW_COPY_AND_ASSIGN(MockPlatform);
};
const char test_script[] = "(x) { x*x; }";
} // namespace
TEST_F(CompilerDispatcherTest, Construct) {
......@@ -902,31 +901,6 @@ TEST_F(CompilerDispatcherTest, EnqueueJob) {
ASSERT_FALSE(platform.BackgroundTasksPending());
}
TEST_F(CompilerDispatcherTest, EnqueueWithoutSFI) {
MockPlatform platform;
CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
ASSERT_TRUE(dispatcher.jobs_.empty());
ASSERT_TRUE(dispatcher.shared_to_unoptimized_job_id_.empty());
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
std::unique_ptr<test::ScriptResource> resource(
new test::ScriptResource(test_script, strlen(test_script)));
ASSERT_TRUE(callback->result() == nullptr);
ASSERT_TRUE(dispatcher.Enqueue(CreateSource(i_isolate(), resource.get()), 0,
static_cast<int>(resource->length()), SLOPPY,
1, false, false, false, 0, callback.get(),
nullptr));
ASSERT_TRUE(!dispatcher.jobs_.empty());
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToParse,
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
ASSERT_TRUE(dispatcher.shared_to_unoptimized_job_id_.empty());
ASSERT_TRUE(callback->result() == nullptr);
ASSERT_TRUE(platform.IdleTaskPending());
platform.ClearIdleTask();
ASSERT_TRUE(platform.BackgroundTasksPending());
platform.ClearBackgroundTasks();
}
TEST_F(CompilerDispatcherTest, EnqueueAndStep) {
MockPlatform platform;
CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
......
......@@ -11,6 +11,7 @@
#include "src/base/platform/semaphore.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
#include "src/compiler-dispatcher/unoptimized-compile-job.h"
#include "src/flags.h"
#include "src/isolate-inl.h"
#include "src/parsing/parse-info.h"
......@@ -67,12 +68,6 @@ class UnoptimizedCompileJobTest : public TestWithContext {
SaveFlags* UnoptimizedCompileJobTest::save_flags_ = nullptr;
namespace {
const char test_script[] = "(x) { x*x; }";
} // namespace
#define ASSERT_JOB_STATUS(STATUS, JOB) ASSERT_EQ(STATUS, GetStatus(JOB))
TEST_F(UnoptimizedCompileJobTest, Construct) {
......@@ -81,19 +76,6 @@ TEST_F(UnoptimizedCompileJobTest, Construct) {
test::CreateSharedFunctionInfo(i_isolate(), nullptr), FLAG_stack_size));
}
TEST_F(UnoptimizedCompileJobTest, ConstructWithoutSFI) {
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
std::unique_ptr<test::ScriptResource> resource(
new test::ScriptResource(test_script, strlen(test_script)));
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
i_isolate()->thread_id().ToInteger(), tracer(), FLAG_stack_size,
test::CreateSource(i_isolate(), resource.get()), 0,
static_cast<int>(resource->length()), SLOPPY, 1, false, false, false,
i_isolate()->heap()->HashSeed(), i_isolate()->allocator(),
ScriptCompiler::kNoCompileOptions, i_isolate()->ast_string_constants(),
callback.get()));
}
TEST_F(UnoptimizedCompileJobTest, StateTransitions) {
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
i_isolate(), tracer(),
......@@ -125,26 +107,6 @@ TEST_F(UnoptimizedCompileJobTest, StateTransitions) {
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kInitial, job);
}
TEST_F(UnoptimizedCompileJobTest, StateTransitionsParseWithCallback) {
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
std::unique_ptr<test::ScriptResource> resource(
new test::ScriptResource(test_script, strlen(test_script)));
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
i_isolate()->thread_id().ToInteger(), tracer(), FLAG_stack_size,
test::CreateSource(i_isolate(), resource.get()), 0,
static_cast<int>(resource->length()), SLOPPY, 1, false, false, false,
i_isolate()->heap()->HashSeed(), i_isolate()->allocator(),
ScriptCompiler::kNoCompileOptions, i_isolate()->ast_string_constants(),
callback.get()));
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kReadyToParse, job);
job->StepNextOnBackgroundThread();
ASSERT_FALSE(job->IsFailed());
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kDone, job);
job->ResetOnMainThread(i_isolate());
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kInitial, job);
ASSERT_TRUE(callback->result() != nullptr);
}
TEST_F(UnoptimizedCompileJobTest, SyntaxError) {
test::ScriptResource script("^^^", strlen("^^^"));
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
......
......@@ -40,17 +40,6 @@ class ScriptResource : public v8::String::ExternalOneByteStringResource {
DISALLOW_COPY_AND_ASSIGN(ScriptResource);
};
class FinishCallback : public UnoptimizedCompileJobFinishCallback {
public:
void ParseFinished(std::unique_ptr<ParseInfo> result) override {
result_ = std::move(result);
}
ParseInfo* result() const { return result_.get(); }
private:
std::unique_ptr<ParseInfo> result_;
};
Handle<Object> RunJS(v8::Isolate* isolate, const char* script);
Handle<String> CreateSource(
Isolate* isolate,
......
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