Commit 65d738d4 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[parser] Move Compiler::Analyze into Parser

Move rewriting, scope analysis, and internalization, to be unconditional
operations done after parsing rather than a separate compile phase. This
removes some of the complexity about rememberering when to call
Compiler::Analyze, and makes these paths a bit more uniform.

Also, forbid allocating any more AST strings after AstValueFactory
internalization, by nulling out the Zone. Add an InternalizePartial
method which doesn't null out the zone for those cases where we do want
to be able to allocate after internalizing (e.g. internalization before
scope analysis).

Change-Id: Id444246d8362a1d169baf664fc37657d9576fd96
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2182458Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67608}
parent 2c45f607
...@@ -332,20 +332,22 @@ const AstRawString* AstValueFactory::CloneFromOtherFactory( ...@@ -332,20 +332,22 @@ const AstRawString* AstValueFactory::CloneFromOtherFactory(
} }
AstConsString* AstValueFactory::NewConsString() { AstConsString* AstValueFactory::NewConsString() {
return new (zone_) AstConsString; return new (zone()) AstConsString;
} }
AstConsString* AstValueFactory::NewConsString(const AstRawString* str) { AstConsString* AstValueFactory::NewConsString(const AstRawString* str) {
return NewConsString()->AddString(zone_, str); return NewConsString()->AddString(zone(), str);
} }
AstConsString* AstValueFactory::NewConsString(const AstRawString* str1, AstConsString* AstValueFactory::NewConsString(const AstRawString* str1,
const AstRawString* str2) { const AstRawString* str2) {
return NewConsString()->AddString(zone_, str1)->AddString(zone_, str2); return NewConsString()->AddString(zone(), str1)->AddString(zone(), str2);
} }
template <typename LocalIsolate> template <typename LocalIsolate>
void AstValueFactory::Internalize(LocalIsolate* isolate) { void AstValueFactory::Internalize(LocalIsolate* isolate) {
if (!zone_) return;
// Strings need to be internalized before values, because values refer to // Strings need to be internalized before values, because values refer to
// strings. // strings.
for (AstRawString* current = strings_; current != nullptr;) { for (AstRawString* current = strings_; current != nullptr;) {
...@@ -355,6 +357,7 @@ void AstValueFactory::Internalize(LocalIsolate* isolate) { ...@@ -355,6 +357,7 @@ void AstValueFactory::Internalize(LocalIsolate* isolate) {
} }
ResetStrings(); ResetStrings();
zone_ = nullptr;
} }
template EXPORT_TEMPLATE_DEFINE( template EXPORT_TEMPLATE_DEFINE(
V8_EXPORT_PRIVATE) void AstValueFactory::Internalize<Isolate>(Isolate* V8_EXPORT_PRIVATE) void AstValueFactory::Internalize<Isolate>(Isolate*
...@@ -373,9 +376,9 @@ AstRawString* AstValueFactory::GetString(uint32_t hash_field, bool is_one_byte, ...@@ -373,9 +376,9 @@ AstRawString* AstValueFactory::GetString(uint32_t hash_field, bool is_one_byte,
if (entry->value == nullptr) { if (entry->value == nullptr) {
// Copy literal contents for later comparison. // Copy literal contents for later comparison.
int length = literal_bytes.length(); int length = literal_bytes.length();
byte* new_literal_bytes = zone_->NewArray<byte>(length); byte* new_literal_bytes = zone()->NewArray<byte>(length);
memcpy(new_literal_bytes, literal_bytes.begin(), length); memcpy(new_literal_bytes, literal_bytes.begin(), length);
AstRawString* new_string = new (zone_) AstRawString( AstRawString* new_string = new (zone()) AstRawString(
is_one_byte, Vector<const byte>(new_literal_bytes, length), hash_field); is_one_byte, Vector<const byte>(new_literal_bytes, length), hash_field);
CHECK_NOT_NULL(new_string); CHECK_NOT_NULL(new_string);
AddString(new_string); AddString(new_string);
......
...@@ -288,6 +288,7 @@ class AstValueFactory { ...@@ -288,6 +288,7 @@ class AstValueFactory {
empty_cons_string_(nullptr), empty_cons_string_(nullptr),
zone_(zone), zone_(zone),
hash_seed_(hash_seed) { hash_seed_(hash_seed) {
DCHECK_NOT_NULL(zone_);
DCHECK_EQ(hash_seed, string_constants->hash_seed()); DCHECK_EQ(hash_seed, string_constants->hash_seed());
std::fill(one_character_strings_, std::fill(one_character_strings_,
one_character_strings_ + arraysize(one_character_strings_), one_character_strings_ + arraysize(one_character_strings_),
...@@ -295,7 +296,10 @@ class AstValueFactory { ...@@ -295,7 +296,10 @@ class AstValueFactory {
empty_cons_string_ = NewConsString(); empty_cons_string_ = NewConsString();
} }
Zone* zone() const { return zone_; } Zone* zone() const {
DCHECK_NOT_NULL(zone_);
return zone_;
}
const AstRawString* GetOneByteString(Vector<const uint8_t> literal) { const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
return GetOneByteStringInternal(literal); return GetOneByteStringInternal(literal);
...@@ -317,6 +321,9 @@ class AstValueFactory { ...@@ -317,6 +321,9 @@ class AstValueFactory {
V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str1, V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str1,
const AstRawString* str2); const AstRawString* str2);
// Internalize all the strings in the factory, and prevent any more from being
// allocated. Multiple calls to Internalize are allowed, for simplicity, where
// subsequent calls are a no-op.
template <typename LocalIsolate> template <typename LocalIsolate>
void Internalize(LocalIsolate* isolate); void Internalize(LocalIsolate* isolate);
......
...@@ -2243,7 +2243,7 @@ class FunctionLiteral final : public Expression { ...@@ -2243,7 +2243,7 @@ class FunctionLiteral final : public Expression {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
FunctionLiteral(Zone* zone, const AstRawString* name, FunctionLiteral(Zone* zone, const AstConsString* name,
AstValueFactory* ast_value_factory, DeclarationScope* scope, AstValueFactory* ast_value_factory, DeclarationScope* scope,
const ScopedPtrList<Statement>& body, const ScopedPtrList<Statement>& body,
int expected_property_count, int parameter_count, int expected_property_count, int parameter_count,
...@@ -2259,7 +2259,7 @@ class FunctionLiteral final : public Expression { ...@@ -2259,7 +2259,7 @@ class FunctionLiteral final : public Expression {
function_token_position_(kNoSourcePosition), function_token_position_(kNoSourcePosition),
suspend_count_(0), suspend_count_(0),
function_literal_id_(function_literal_id), function_literal_id_(function_literal_id),
raw_name_(name ? ast_value_factory->NewConsString(name) : nullptr), raw_name_(name),
scope_(scope), scope_(scope),
body_(0, nullptr), body_(0, nullptr),
raw_inferred_name_(ast_value_factory->empty_cons_string()), raw_inferred_name_(ast_value_factory->empty_cons_string()),
...@@ -3110,7 +3110,8 @@ class AstNodeFactory final { ...@@ -3110,7 +3110,8 @@ class AstNodeFactory final {
bool has_braces, int function_literal_id, bool has_braces, int function_literal_id,
ProducedPreparseData* produced_preparse_data = nullptr) { ProducedPreparseData* produced_preparse_data = nullptr) {
return new (zone_) FunctionLiteral( return new (zone_) FunctionLiteral(
zone_, name, ast_value_factory_, scope, body, expected_property_count, zone_, name ? ast_value_factory_->NewConsString(name) : nullptr,
ast_value_factory_, scope, body, expected_property_count,
parameter_count, function_length, function_syntax_kind, parameter_count, function_length, function_syntax_kind,
has_duplicate_parameters, eager_compile_hint, position, has_braces, has_duplicate_parameters, eager_compile_hint, position, has_braces,
function_literal_id, produced_preparse_data); function_literal_id, produced_preparse_data);
...@@ -3123,8 +3124,8 @@ class AstNodeFactory final { ...@@ -3123,8 +3124,8 @@ class AstNodeFactory final {
DeclarationScope* scope, const ScopedPtrList<Statement>& body, DeclarationScope* scope, const ScopedPtrList<Statement>& body,
int expected_property_count, int parameter_count) { int expected_property_count, int parameter_count) {
return new (zone_) FunctionLiteral( return new (zone_) FunctionLiteral(
zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope, zone_, ast_value_factory_->empty_cons_string(), ast_value_factory_,
body, expected_property_count, parameter_count, parameter_count, scope, body, expected_property_count, parameter_count, parameter_count,
FunctionSyntaxKind::kAnonymousExpression, FunctionSyntaxKind::kAnonymousExpression,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false, FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false,
......
...@@ -598,7 +598,7 @@ bool DeclarationScope::Analyze(ParseInfo* info) { ...@@ -598,7 +598,7 @@ bool DeclarationScope::Analyze(ParseInfo* info) {
DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE); DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
allow_deref.emplace(); allow_deref.emplace();
info->consumed_preparse_data()->RestoreScopeAllocationData( info->consumed_preparse_data()->RestoreScopeAllocationData(
scope, info->ast_value_factory()); scope, info->ast_value_factory(), info->zone());
} }
if (!scope->AllocateVariables(info)) return false; if (!scope->AllocateVariables(info)) return false;
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "src/parsing/parser.h" #include "src/parsing/parser.h"
#include "src/parsing/parsing.h" #include "src/parsing/parsing.h"
#include "src/parsing/pending-compilation-error-handler.h" #include "src/parsing/pending-compilation-error-handler.h"
#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h" #include "src/parsing/scanner-character-streams.h"
#include "src/snapshot/code-serializer.h" #include "src/snapshot/code-serializer.h"
#include "src/utils/ostreams.h" #include "src/utils/ostreams.h"
...@@ -624,11 +623,9 @@ std::unique_ptr<UnoptimizedCompilationJob> GenerateUnoptimizedCode( ...@@ -624,11 +623,9 @@ std::unique_ptr<UnoptimizedCompilationJob> GenerateUnoptimizedCode(
DisallowHeapAccess no_heap_access; DisallowHeapAccess no_heap_access;
DCHECK(inner_function_jobs->empty()); DCHECK(inner_function_jobs->empty());
std::unique_ptr<UnoptimizedCompilationJob> job; std::unique_ptr<UnoptimizedCompilationJob> job =
if (Compiler::Analyze(parse_info)) { ExecuteUnoptimizedCompileJobs(parse_info, parse_info->literal(),
job = ExecuteUnoptimizedCompileJobs(parse_info, parse_info->literal(),
allocator, inner_function_jobs); allocator, inner_function_jobs);
}
// Character stream shouldn't be used again. // Character stream shouldn't be used again.
parse_info->ResetCharacterStream(); parse_info->ResetCharacterStream();
...@@ -640,9 +637,6 @@ MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel( ...@@ -640,9 +637,6 @@ MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
Isolate* isolate, Handle<Script> script, ParseInfo* parse_info, Isolate* isolate, Handle<Script> script, ParseInfo* parse_info,
AccountingAllocator* allocator, IsCompiledScope* is_compiled_scope) { AccountingAllocator* allocator, IsCompiledScope* is_compiled_scope) {
EnsureSharedFunctionInfosArrayOnScript(script, parse_info, isolate); EnsureSharedFunctionInfosArrayOnScript(script, parse_info, isolate);
parse_info->ast_value_factory()->Internalize(isolate);
if (!Compiler::Analyze(parse_info)) return MaybeHandle<SharedFunctionInfo>();
DeclarationScope::AllocateScopeInfos(parse_info, isolate); DeclarationScope::AllocateScopeInfos(parse_info, isolate);
// Prepare and execute compilation of the outer-most function. // Prepare and execute compilation of the outer-most function.
...@@ -1399,25 +1393,6 @@ void BackgroundCompileTask::Run() { ...@@ -1399,25 +1393,6 @@ void BackgroundCompileTask::Run() {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of Compiler // Implementation of Compiler
bool Compiler::Analyze(ParseInfo* parse_info) {
DCHECK_NOT_NULL(parse_info->literal());
RuntimeCallTimerScope runtimeTimer(parse_info->runtime_call_stats(),
RuntimeCallCounterId::kCompileAnalyse,
RuntimeCallStats::kThreadSpecific);
if (!Rewriter::Rewrite(parse_info)) return false;
if (!DeclarationScope::Analyze(parse_info)) return false;
return true;
}
bool Compiler::ParseAndAnalyze(ParseInfo* parse_info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate) {
if (!parsing::ParseAny(parse_info, shared_info, isolate)) {
return false;
}
return Compiler::Analyze(parse_info);
}
// static // static
bool Compiler::CollectSourcePositions(Isolate* isolate, bool Compiler::CollectSourcePositions(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info) { Handle<SharedFunctionInfo> shared_info) {
...@@ -1485,14 +1460,6 @@ bool Compiler::CollectSourcePositions(Isolate* isolate, ...@@ -1485,14 +1460,6 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
// wasting time fully parsing them when they won't ever be used. // wasting time fully parsing them when they won't ever be used.
std::unique_ptr<UnoptimizedCompilationJob> job; std::unique_ptr<UnoptimizedCompilationJob> job;
{ {
if (!Compiler::Analyze(&parse_info)) {
// Recompiling failed probably as a result of stack exhaustion.
bytecode->SetSourcePositionsFailedToCollect();
return FailWithPendingException(
isolate, handle(Script::cast(shared_info->script()), isolate),
&parse_info, Compiler::ClearExceptionFlag::CLEAR_EXCEPTION);
}
job = interpreter::Interpreter::NewSourcePositionCollectionJob( job = interpreter::Interpreter::NewSourcePositionCollectionJob(
&parse_info, parse_info.literal(), bytecode, isolate->allocator()); &parse_info, parse_info.literal(), bytecode, isolate->allocator());
...@@ -1590,9 +1557,6 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info, ...@@ -1590,9 +1557,6 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
&parse_info, flag); &parse_info, flag);
} }
// Internalize ast values onto the heap.
parse_info.ast_value_factory()->Internalize(isolate);
// Finalize compilation of the unoptimized bytecode or asm-js data. // Finalize compilation of the unoptimized bytecode or asm-js data.
if (!FinalizeUnoptimizedCode(&parse_info, isolate, shared_info, if (!FinalizeUnoptimizedCode(&parse_info, isolate, shared_info,
outer_function_job.get(), outer_function_job.get(),
......
...@@ -94,13 +94,6 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic { ...@@ -94,13 +94,6 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
// offer this chance, optimized closure instantiation will not call this. // offer this chance, optimized closure instantiation will not call this.
static void PostInstantiation(Handle<JSFunction> function); static void PostInstantiation(Handle<JSFunction> function);
// Parser::Parse, then Compiler::Analyze.
static bool ParseAndAnalyze(ParseInfo* parse_info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate);
// Rewrite and analyze scopes.
static bool Analyze(ParseInfo* parse_info);
// =========================================================================== // ===========================================================================
// The following family of methods instantiates new functions for scripts or // The following family of methods instantiates new functions for scripts or
// function literals. The decision whether those functions will be compiled, // function literals. The decision whether those functions will be compiled,
......
...@@ -272,8 +272,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) { ...@@ -272,8 +272,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
isolate_) isolate_)
: parsing::ParseFunction(info_.get(), shared_info, isolate_); : parsing::ParseFunction(info_.get(), shared_info, isolate_);
if (parse_result && Rewriter::Rewrite(info_.get())) { if (parse_result) {
info_->ast_value_factory()->Internalize(isolate_);
DeclarationScope* literal_scope = info_->literal()->scope(); DeclarationScope* literal_scope = info_->literal()->scope();
ScopeChainRetriever scope_chain_retriever(literal_scope, function_, ScopeChainRetriever scope_chain_retriever(literal_scope, function_,
...@@ -287,7 +286,6 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) { ...@@ -287,7 +286,6 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
? scope_chain_retriever.ClosureScope() ? scope_chain_retriever.ClosureScope()
: literal_scope; : literal_scope;
CHECK(DeclarationScope::Analyze(info_.get()));
if (ignore_nested_scopes) { if (ignore_nested_scopes) {
current_scope_ = closure_scope_; current_scope_ = closure_scope_;
start_scope_ = current_scope_; start_scope_ = current_scope_;
......
...@@ -758,10 +758,6 @@ bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info, ...@@ -758,10 +758,6 @@ bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info,
.ToHandle(&shared); .ToHandle(&shared);
} else { } else {
success = parsing::ParseProgram(parse_info, script, isolate); success = parsing::ParseProgram(parse_info, script, isolate);
if (success) {
success = Compiler::Analyze(parse_info);
parse_info->ast_value_factory()->Internalize(isolate);
}
} }
if (!success) { if (!success) {
isolate->OptionalRescheduleException(false); isolate->OptionalRescheduleException(false);
......
...@@ -508,8 +508,8 @@ void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root, ...@@ -508,8 +508,8 @@ void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
} // namespace } // namespace
FunctionLiteral* Parser::ParseProgram( void Parser::ParseProgram(Isolate* isolate, Handle<Script> script,
Isolate* isolate, Handle<Script> script, ParseInfo* info, ParseInfo* info,
MaybeHandle<ScopeInfo> maybe_outer_scope_info) { MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here, // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
// see comment for HistogramTimerScope class. // see comment for HistogramTimerScope class.
...@@ -539,6 +539,7 @@ FunctionLiteral* Parser::ParseProgram( ...@@ -539,6 +539,7 @@ FunctionLiteral* Parser::ParseProgram(
FunctionLiteral* result = DoParseProgram(isolate, info); FunctionLiteral* result = DoParseProgram(isolate, info);
MaybeResetCharacterStream(info, result); MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_); MaybeProcessSourceRanges(info, result, stack_limit_);
PostProcessParseResult(isolate, info, result);
HandleSourceURLComments(isolate, script); HandleSourceURLComments(isolate, script);
...@@ -555,7 +556,6 @@ FunctionLiteral* Parser::ParseProgram( ...@@ -555,7 +556,6 @@ FunctionLiteral* Parser::ParseProgram(
LOG(isolate, LOG(isolate,
FunctionEvent(event_name, flags().script_id(), ms, start, end, "", 0)); FunctionEvent(event_name, flags().script_id(), ms, start, end, "", 0));
} }
return result;
} }
FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
...@@ -684,6 +684,33 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { ...@@ -684,6 +684,33 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
return result; return result;
} }
void Parser::PostProcessParseResult(Isolate* isolate, ParseInfo* info,
FunctionLiteral* literal) {
if (literal == nullptr) return;
info->set_literal(literal);
info->set_language_mode(literal->language_mode());
if (info->flags().is_eval()) {
info->set_allow_eval_cache(allow_eval_cache());
}
// We cannot internalize on a background thread; a foreground task will take
// care of calling AstValueFactory::Internalize just before compilation.
DCHECK_EQ(isolate != nullptr, parsing_on_main_thread_);
if (isolate) info->ast_value_factory()->Internalize(isolate);
{
RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(),
RuntimeCallCounterId::kCompileAnalyse,
RuntimeCallStats::kThreadSpecific);
if (!Rewriter::Rewrite(info) || !DeclarationScope::Analyze(info)) {
// Null out the literal to indicate that something failed.
info->set_literal(nullptr);
return;
}
}
}
ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments( ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
Isolate* isolate, ParseInfo* info, Zone* zone) { Isolate* isolate, ParseInfo* info, Zone* zone) {
DCHECK(parsing_on_main_thread_); DCHECK(parsing_on_main_thread_);
...@@ -783,7 +810,7 @@ Expression* Parser::WrapREPLResult(Expression* value) { ...@@ -783,7 +810,7 @@ Expression* Parser::WrapREPLResult(Expression* value) {
false); false);
} }
FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, void Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<SharedFunctionInfo> shared_info) { Handle<SharedFunctionInfo> shared_info) {
// It's OK to use the Isolate & counters here, since this function is only // It's OK to use the Isolate & counters here, since this function is only
// called in the main thread. // called in the main thread.
...@@ -835,11 +862,12 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -835,11 +862,12 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<String> inferred_name(shared_info->inferred_name(), isolate); Handle<String> inferred_name(shared_info->inferred_name(), isolate);
result->set_inferred_name(inferred_name); result->set_inferred_name(inferred_name);
} }
PostProcessParseResult(isolate, info, result);
if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) { if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
// We need to make sure that the debug-name is available. // We should already be internalized by now, so the debug name will be
ast_value_factory()->Internalize(isolate); // available.
DeclarationScope* function_scope = result->scope(); DeclarationScope* function_scope = result->scope();
std::unique_ptr<char[]> function_name = result->GetDebugName(); std::unique_ptr<char[]> function_name = result->GetDebugName();
LOG(isolate, LOG(isolate,
...@@ -848,7 +876,6 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -848,7 +876,6 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
function_scope->end_position(), function_name.get(), function_scope->end_position(), function_name.get(),
strlen(function_name.get()))); strlen(function_name.get())));
} }
return result;
} }
FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
...@@ -3117,11 +3144,7 @@ void Parser::ParseOnBackground(ParseInfo* info, int start_position, ...@@ -3117,11 +3144,7 @@ void Parser::ParseOnBackground(ParseInfo* info, int start_position,
} }
MaybeResetCharacterStream(info, result); MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_); MaybeProcessSourceRanges(info, result, stack_limit_);
PostProcessParseResult(/* isolate = */ nullptr, info, result);
info->set_literal(result);
// We cannot internalize on a background thread; a foreground task will take
// care of calling AstValueFactory::Internalize just before compilation.
} }
Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
......
...@@ -135,6 +135,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -135,6 +135,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
static bool IsPreParser() { return false; } static bool IsPreParser() { return false; }
// Sets the literal on |info| if parsing succeeded.
void ParseOnBackground(ParseInfo* info, int start_position, int end_position, void ParseOnBackground(ParseInfo* info, int start_position, int end_position,
int function_literal_id); int function_literal_id);
...@@ -209,13 +210,17 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -209,13 +210,17 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void PrepareGeneratorVariables(); void PrepareGeneratorVariables();
// Returns nullptr if parsing failed. // Sets the literal on |info| if parsing succeeded.
FunctionLiteral* ParseProgram(Isolate* isolate, Handle<Script> script, void ParseProgram(Isolate* isolate, Handle<Script> script, ParseInfo* info,
ParseInfo* info,
MaybeHandle<ScopeInfo> maybe_outer_scope_info); MaybeHandle<ScopeInfo> maybe_outer_scope_info);
FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info, // Sets the literal on |info| if parsing succeeded.
void ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<SharedFunctionInfo> shared_info); Handle<SharedFunctionInfo> shared_info);
void PostProcessParseResult(Isolate* isolate, ParseInfo* info,
FunctionLiteral* literal);
FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info, FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
int start_position, int end_position, int start_position, int end_position,
int function_literal_id, int function_literal_id,
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/parsing/parse-info.h" #include "src/parsing/parse-info.h"
#include "src/parsing/parser.h" #include "src/parsing/parser.h"
#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h" #include "src/parsing/scanner-character-streams.h"
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816 #include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
...@@ -19,6 +20,22 @@ namespace v8 { ...@@ -19,6 +20,22 @@ namespace v8 {
namespace internal { namespace internal {
namespace parsing { namespace parsing {
namespace {
void MaybeReportErrorsAndStatistics(ParseInfo* info, Handle<Script> script,
Isolate* isolate, Parser* parser,
ReportErrorsAndStatisticsMode mode) {
if (mode == ReportErrorsAndStatisticsMode::kYes) {
if (info->literal() == nullptr) {
info->pending_error_handler()->ReportErrors(isolate, script,
info->ast_value_factory());
}
parser->UpdateStatistics(isolate, script);
}
}
} // namespace
bool ParseProgram(ParseInfo* info, Handle<Script> script, bool ParseProgram(ParseInfo* info, Handle<Script> script,
MaybeHandle<ScopeInfo> maybe_outer_scope_info, MaybeHandle<ScopeInfo> maybe_outer_scope_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) { Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
...@@ -36,27 +53,11 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script, ...@@ -36,27 +53,11 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script,
Parser parser(info); Parser parser(info);
FunctionLiteral* result = nullptr;
// Ok to use Isolate here; this function is only called in the main thread. // Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_); DCHECK(parser.parsing_on_main_thread_);
parser.ParseProgram(isolate, script, info, maybe_outer_scope_info);
result = parser.ParseProgram(isolate, script, info, maybe_outer_scope_info); MaybeReportErrorsAndStatistics(info, script, isolate, &parser, mode);
info->set_literal(result); return info->literal() != nullptr;
if (result) {
info->set_language_mode(info->literal()->language_mode());
if (info->flags().is_eval()) {
info->set_allow_eval_cache(parser.allow_eval_cache());
}
}
if (mode == ReportErrorsAndStatisticsMode::kYes) {
if (result == nullptr) {
info->pending_error_handler()->ReportErrors(isolate, script,
info->ast_value_factory());
}
parser.UpdateStatistics(isolate, script);
}
return (result != nullptr);
} }
bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate, bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate,
...@@ -70,6 +71,8 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info, ...@@ -70,6 +71,8 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
DCHECK(!shared_info.is_null()); DCHECK(!shared_info.is_null());
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
VMState<PARSER> state(isolate);
// Create a character stream for the parser. // Create a character stream for the parser.
Handle<Script> script(Script::cast(shared_info->script()), isolate); Handle<Script> script(Script::cast(shared_info->script()), isolate);
Handle<String> source(String::cast(script->source()), isolate); Handle<String> source(String::cast(script->source()), isolate);
...@@ -79,31 +82,13 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info, ...@@ -79,31 +82,13 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
shared_info->EndPosition())); shared_info->EndPosition()));
info->set_character_stream(std::move(stream)); info->set_character_stream(std::move(stream));
VMState<PARSER> state(isolate);
Parser parser(info); Parser parser(info);
FunctionLiteral* result = nullptr;
// Ok to use Isolate here; this function is only called in the main thread. // Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_); DCHECK(parser.parsing_on_main_thread_);
parser.ParseFunction(isolate, info, shared_info);
result = parser.ParseFunction(isolate, info, shared_info); MaybeReportErrorsAndStatistics(info, script, isolate, &parser, mode);
info->set_literal(result); return info->literal() != nullptr;
if (result) {
info->ast_value_factory()->Internalize(isolate);
if (info->flags().is_eval()) {
info->set_allow_eval_cache(parser.allow_eval_cache());
}
}
if (mode == ReportErrorsAndStatisticsMode::kYes) {
if (result == nullptr) {
info->pending_error_handler()->ReportErrors(isolate, script,
info->ast_value_factory());
}
parser.UpdateStatistics(isolate, script);
}
return (result != nullptr);
} }
bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info, bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
......
...@@ -158,17 +158,20 @@ class BaseConsumedPreparseData : public ConsumedPreparseData { ...@@ -158,17 +158,20 @@ class BaseConsumedPreparseData : public ConsumedPreparseData {
LanguageMode* language_mode) final; LanguageMode* language_mode) final;
void RestoreScopeAllocationData(DeclarationScope* scope, void RestoreScopeAllocationData(DeclarationScope* scope,
AstValueFactory* ast_value_factory) final; AstValueFactory* ast_value_factory,
Zone* zone) final;
#ifdef DEBUG #ifdef DEBUG
bool VerifyDataStart(); bool VerifyDataStart();
#endif #endif
private: private:
void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory); void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory,
Zone* zone);
void RestoreDataForVariable(Variable* var); void RestoreDataForVariable(Variable* var);
void RestoreDataForInnerScopes(Scope* scope, void RestoreDataForInnerScopes(Scope* scope,
AstValueFactory* ast_value_factory); AstValueFactory* ast_value_factory,
Zone* zone);
std::unique_ptr<ByteData> scope_data_; std::unique_ptr<ByteData> scope_data_;
// When consuming the data, these indexes point to the data we're going to // When consuming the data, these indexes point to the data we're going to
......
...@@ -613,7 +613,7 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction( ...@@ -613,7 +613,7 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
template <class Data> template <class Data>
void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData( void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
DeclarationScope* scope, AstValueFactory* ast_value_factory) { DeclarationScope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE); DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
typename ByteData::ReadingScope reading_scope(this); typename ByteData::ReadingScope reading_scope(this);
...@@ -628,7 +628,7 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData( ...@@ -628,7 +628,7 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
DCHECK_EQ(end_position_from_data, scope->end_position()); DCHECK_EQ(end_position_from_data, scope->end_position());
#endif #endif
RestoreDataForScope(scope, ast_value_factory); RestoreDataForScope(scope, ast_value_factory, zone);
// Check that we consumed all scope data. // Check that we consumed all scope data.
DCHECK_EQ(scope_data_->RemainingBytes(), 0); DCHECK_EQ(scope_data_->RemainingBytes(), 0);
...@@ -636,7 +636,7 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData( ...@@ -636,7 +636,7 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
template <typename Data> template <typename Data>
void BaseConsumedPreparseData<Data>::RestoreDataForScope( void BaseConsumedPreparseData<Data>::RestoreDataForScope(
Scope* scope, AstValueFactory* ast_value_factory) { Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
if (scope->is_declaration_scope() && if (scope->is_declaration_scope() &&
scope->AsDeclarationScope()->is_skipped_function()) { scope->AsDeclarationScope()->is_skipped_function()) {
return; return;
...@@ -670,7 +670,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope( ...@@ -670,7 +670,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
if (scope->AsClassScope()->is_anonymous_class()) { if (scope->AsClassScope()->is_anonymous_class()) {
var = scope->AsClassScope()->DeclareClassVariable( var = scope->AsClassScope()->DeclareClassVariable(
ast_value_factory, nullptr, kNoSourcePosition); ast_value_factory, nullptr, kNoSourcePosition);
AstNodeFactory factory(ast_value_factory, ast_value_factory->zone()); AstNodeFactory factory(ast_value_factory, zone);
Declaration* declaration = Declaration* declaration =
factory.NewVariableDeclaration(kNoSourcePosition); factory.NewVariableDeclaration(kNoSourcePosition);
scope->declarations()->Add(declaration); scope->declarations()->Add(declaration);
...@@ -692,7 +692,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope( ...@@ -692,7 +692,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var); if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var);
} }
RestoreDataForInnerScopes(scope, ast_value_factory); RestoreDataForInnerScopes(scope, ast_value_factory, zone);
} }
template <typename Data> template <typename Data>
...@@ -732,10 +732,10 @@ void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) { ...@@ -732,10 +732,10 @@ void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) {
template <typename Data> template <typename Data>
void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes( void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(
Scope* scope, AstValueFactory* ast_value_factory) { Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
for (Scope* inner = scope->inner_scope(); inner != nullptr; for (Scope* inner = scope->inner_scope(); inner != nullptr;
inner = inner->sibling()) { inner = inner->sibling()) {
RestoreDataForScope(inner, ast_value_factory); RestoreDataForScope(inner, ast_value_factory, zone);
} }
} }
......
...@@ -297,8 +297,9 @@ class ConsumedPreparseData { ...@@ -297,8 +297,9 @@ class ConsumedPreparseData {
// Restores the information needed for allocating the Scope's (and its // Restores the information needed for allocating the Scope's (and its
// subscopes') variables. // subscopes') variables.
virtual void RestoreScopeAllocationData( virtual void RestoreScopeAllocationData(DeclarationScope* scope,
DeclarationScope* scope, AstValueFactory* ast_value_factory) = 0; AstValueFactory* ast_value_factory,
Zone* zone) = 0;
protected: protected:
ConsumedPreparseData() = default; ConsumedPreparseData() = default;
......
...@@ -17,12 +17,12 @@ namespace internal { ...@@ -17,12 +17,12 @@ namespace internal {
class Processor final : public AstVisitor<Processor> { class Processor final : public AstVisitor<Processor> {
public: public:
Processor(uintptr_t stack_limit, DeclarationScope* closure_scope, Processor(uintptr_t stack_limit, DeclarationScope* closure_scope,
Variable* result, AstValueFactory* ast_value_factory) Variable* result, AstValueFactory* ast_value_factory, Zone* zone)
: result_(result), : result_(result),
replacement_(nullptr), replacement_(nullptr),
zone_(ast_value_factory->zone()), zone_(zone),
closure_scope_(closure_scope), closure_scope_(closure_scope),
factory_(ast_value_factory, ast_value_factory->zone()), factory_(ast_value_factory, zone),
result_assigned_(false), result_assigned_(false),
is_set_(false), is_set_(false),
breakable_(false) { breakable_(false) {
...@@ -31,10 +31,10 @@ class Processor final : public AstVisitor<Processor> { ...@@ -31,10 +31,10 @@ class Processor final : public AstVisitor<Processor> {
} }
Processor(Parser* parser, DeclarationScope* closure_scope, Variable* result, Processor(Parser* parser, DeclarationScope* closure_scope, Variable* result,
AstValueFactory* ast_value_factory) AstValueFactory* ast_value_factory, Zone* zone)
: result_(result), : result_(result),
replacement_(nullptr), replacement_(nullptr),
zone_(ast_value_factory->zone()), zone_(zone),
closure_scope_(closure_scope), closure_scope_(closure_scope),
factory_(ast_value_factory, zone_), factory_(ast_value_factory, zone_),
result_assigned_(false), result_assigned_(false),
...@@ -392,7 +392,7 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody( ...@@ -392,7 +392,7 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody(
Variable* result = scope->AsDeclarationScope()->NewTemporary( Variable* result = scope->AsDeclarationScope()->NewTemporary(
info->ast_value_factory()->dot_result_string()); info->ast_value_factory()->dot_result_string());
Processor processor(info->stack_limit(), scope->AsDeclarationScope(), Processor processor(info->stack_limit(), scope->AsDeclarationScope(),
result, info->ast_value_factory()); result, info->ast_value_factory(), info->zone());
processor.Process(body); processor.Process(body);
DCHECK_IMPLIES(scope->is_module_scope(), processor.result_assigned()); DCHECK_IMPLIES(scope->is_module_scope(), processor.result_assigned());
......
...@@ -522,6 +522,7 @@ TEST(InterpreterStringAdd) { ...@@ -522,6 +522,7 @@ TEST(InterpreterStringAdd) {
{ast_factory.GetOneByteString(""), LiteralForTest(2.5), {ast_factory.GetOneByteString(""), LiteralForTest(2.5),
factory->NewStringFromStaticChars("2.5"), BinaryOperationFeedback::kAny}, factory->NewStringFromStaticChars("2.5"), BinaryOperationFeedback::kAny},
}; };
ast_factory.Internalize(isolate);
for (size_t i = 0; i < arraysize(test_cases); i++) { for (size_t i = 0; i < arraysize(test_cases); i++) {
FeedbackVectorSpec feedback_spec(zone); FeedbackVectorSpec feedback_spec(zone);
...@@ -534,7 +535,6 @@ TEST(InterpreterStringAdd) { ...@@ -534,7 +535,6 @@ TEST(InterpreterStringAdd) {
builder.LoadLiteral(test_cases[i].lhs).StoreAccumulatorInRegister(reg); builder.LoadLiteral(test_cases[i].lhs).StoreAccumulatorInRegister(reg);
LoadLiteralForTest(&builder, test_cases[i].rhs); LoadLiteralForTest(&builder, test_cases[i].rhs);
builder.BinaryOperation(Token::Value::ADD, reg, GetIndex(slot)).Return(); builder.BinaryOperation(Token::Value::ADD, reg, GetIndex(slot)).Return();
ast_factory.Internalize(isolate);
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
InterpreterTester tester(isolate, bytecode_array, metadata); InterpreterTester tester(isolate, bytecode_array, metadata);
...@@ -744,6 +744,7 @@ TEST(InterpreterBinaryOpTypeFeedback) { ...@@ -744,6 +744,7 @@ TEST(InterpreterBinaryOpTypeFeedback) {
{Token::Value::MOD, LiteralForTest(3), {Token::Value::MOD, LiteralForTest(3),
LiteralForTest(ast_factory.GetOneByteString("-2")), LiteralForTest(ast_factory.GetOneByteString("-2")),
Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}}; Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}};
ast_factory.Internalize(isolate);
for (const BinaryOpExpectation& test_case : kTestCases) { for (const BinaryOpExpectation& test_case : kTestCases) {
i::FeedbackVectorSpec feedback_spec(zone); i::FeedbackVectorSpec feedback_spec(zone);
...@@ -760,7 +761,6 @@ TEST(InterpreterBinaryOpTypeFeedback) { ...@@ -760,7 +761,6 @@ TEST(InterpreterBinaryOpTypeFeedback) {
LoadLiteralForTest(&builder, test_case.arg2); LoadLiteralForTest(&builder, test_case.arg2);
builder.BinaryOperation(test_case.op, reg, GetIndex(slot0)).Return(); builder.BinaryOperation(test_case.op, reg, GetIndex(slot0)).Return();
ast_factory.Internalize(isolate);
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
InterpreterTester tester(isolate, bytecode_array, metadata); InterpreterTester tester(isolate, bytecode_array, metadata);
...@@ -849,6 +849,7 @@ TEST(InterpreterBinaryOpSmiTypeFeedback) { ...@@ -849,6 +849,7 @@ TEST(InterpreterBinaryOpSmiTypeFeedback) {
Handle<Smi>(Smi::zero(), isolate), BinaryOperationFeedback::kNumber}, Handle<Smi>(Smi::zero(), isolate), BinaryOperationFeedback::kNumber},
{Token::Value::SAR, LiteralForTest(ast_factory.GetOneByteString("2")), 1, {Token::Value::SAR, LiteralForTest(ast_factory.GetOneByteString("2")), 1,
Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}}; Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}};
ast_factory.Internalize(isolate);
for (const BinaryOpExpectation& test_case : kTestCases) { for (const BinaryOpExpectation& test_case : kTestCases) {
i::FeedbackVectorSpec feedback_spec(zone); i::FeedbackVectorSpec feedback_spec(zone);
...@@ -866,7 +867,6 @@ TEST(InterpreterBinaryOpSmiTypeFeedback) { ...@@ -866,7 +867,6 @@ TEST(InterpreterBinaryOpSmiTypeFeedback) {
.BinaryOperation(test_case.op, reg, GetIndex(slot0)) .BinaryOperation(test_case.op, reg, GetIndex(slot0))
.Return(); .Return();
ast_factory.Internalize(isolate);
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
InterpreterTester tester(isolate, bytecode_array, metadata); InterpreterTester tester(isolate, bytecode_array, metadata);
...@@ -1358,8 +1358,6 @@ TEST(InterpreterCall) { ...@@ -1358,8 +1358,6 @@ TEST(InterpreterCall) {
Isolate* isolate = handles.main_isolate(); Isolate* isolate = handles.main_isolate();
Zone* zone = handles.main_zone(); Zone* zone = handles.main_zone();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
FeedbackVectorSpec feedback_spec(zone); FeedbackVectorSpec feedback_spec(zone);
FeedbackSlot slot = feedback_spec.AddLoadICSlot(); FeedbackSlot slot = feedback_spec.AddLoadICSlot();
...@@ -1371,10 +1369,12 @@ TEST(InterpreterCall) { ...@@ -1371,10 +1369,12 @@ TEST(InterpreterCall) {
int call_slot_index = -1; int call_slot_index = -1;
call_slot_index = GetIndex(call_slot); call_slot_index = GetIndex(call_slot);
const AstRawString* name = ast_factory.GetOneByteString("func");
// Check with no args. // Check with no args.
{ {
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
const AstRawString* name = ast_factory.GetOneByteString("func");
BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec); BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
Register reg = builder.register_allocator()->NewRegister(); Register reg = builder.register_allocator()->NewRegister();
RegisterList args = builder.register_allocator()->NewRegisterList(1); RegisterList args = builder.register_allocator()->NewRegisterList(1);
...@@ -1399,6 +1399,10 @@ TEST(InterpreterCall) { ...@@ -1399,6 +1399,10 @@ TEST(InterpreterCall) {
// Check that receiver is passed properly. // Check that receiver is passed properly.
{ {
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
const AstRawString* name = ast_factory.GetOneByteString("func");
BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec); BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
Register reg = builder.register_allocator()->NewRegister(); Register reg = builder.register_allocator()->NewRegister();
RegisterList args = builder.register_allocator()->NewRegisterList(1); RegisterList args = builder.register_allocator()->NewRegisterList(1);
...@@ -1424,6 +1428,10 @@ TEST(InterpreterCall) { ...@@ -1424,6 +1428,10 @@ TEST(InterpreterCall) {
// Check with two parameters (+ receiver). // Check with two parameters (+ receiver).
{ {
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
const AstRawString* name = ast_factory.GetOneByteString("func");
BytecodeArrayBuilder builder(zone, 1, 4, &feedback_spec); BytecodeArrayBuilder builder(zone, 1, 4, &feedback_spec);
Register reg = builder.register_allocator()->NewRegister(); Register reg = builder.register_allocator()->NewRegister();
RegisterList args = builder.register_allocator()->NewRegisterList(3); RegisterList args = builder.register_allocator()->NewRegisterList(3);
...@@ -1457,6 +1465,10 @@ TEST(InterpreterCall) { ...@@ -1457,6 +1465,10 @@ TEST(InterpreterCall) {
// Check with 10 parameters (+ receiver). // Check with 10 parameters (+ receiver).
{ {
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
const AstRawString* name = ast_factory.GetOneByteString("func");
BytecodeArrayBuilder builder(zone, 1, 12, &feedback_spec); BytecodeArrayBuilder builder(zone, 1, 12, &feedback_spec);
Register reg = builder.register_allocator()->NewRegister(); Register reg = builder.register_allocator()->NewRegister();
RegisterList args = builder.register_allocator()->NewRegisterList(11); RegisterList args = builder.register_allocator()->NewRegisterList(11);
...@@ -2286,14 +2298,15 @@ TEST(InterpreterTestIn) { ...@@ -2286,14 +2298,15 @@ TEST(InterpreterTestIn) {
Isolate* isolate = handles.main_isolate(); Isolate* isolate = handles.main_isolate();
Zone* zone = handles.main_zone(); Zone* zone = handles.main_zone();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
// Allocate an array // Allocate an array
Handle<i::JSArray> array = Handle<i::JSArray> array =
factory->NewJSArray(0, i::ElementsKind::PACKED_SMI_ELEMENTS); factory->NewJSArray(0, i::ElementsKind::PACKED_SMI_ELEMENTS);
// Check for these properties on the array object // Check for these properties on the array object
const char* properties[] = {"length", "fuzzle", "x", "0"}; const char* properties[] = {"length", "fuzzle", "x", "0"};
for (size_t i = 0; i < arraysize(properties); i++) { for (size_t i = 0; i < arraysize(properties); i++) {
AstValueFactory ast_factory(zone, isolate->ast_string_constants(),
HashSeed(isolate));
bool expected_value = (i == 0); bool expected_value = (i == 0);
FeedbackVectorSpec feedback_spec(zone); FeedbackVectorSpec feedback_spec(zone);
BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec); BytecodeArrayBuilder builder(zone, 1, 1, &feedback_spec);
...@@ -2363,6 +2376,7 @@ TEST(InterpreterUnaryNotNonBoolean) { ...@@ -2363,6 +2376,7 @@ TEST(InterpreterUnaryNotNonBoolean) {
false), false),
std::make_pair(LiteralForTest(ast_factory.GetOneByteString("")), true), std::make_pair(LiteralForTest(ast_factory.GetOneByteString("")), true),
}; };
ast_factory.Internalize(isolate);
for (size_t i = 0; i < arraysize(object_type_tuples); i++) { for (size_t i = 0; i < arraysize(object_type_tuples); i++) {
BytecodeArrayBuilder builder(zone, 1, 0); BytecodeArrayBuilder builder(zone, 1, 0);
...@@ -2370,7 +2384,6 @@ TEST(InterpreterUnaryNotNonBoolean) { ...@@ -2370,7 +2384,6 @@ TEST(InterpreterUnaryNotNonBoolean) {
Register r0(0); Register r0(0);
LoadLiteralForTest(&builder, object_type_tuples[i].first); LoadLiteralForTest(&builder, object_type_tuples[i].first);
builder.LogicalNot(ToBooleanMode::kConvertToBoolean).Return(); builder.LogicalNot(ToBooleanMode::kConvertToBoolean).Return();
ast_factory.Internalize(isolate);
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
InterpreterTester tester(isolate, bytecode_array); InterpreterTester tester(isolate, bytecode_array);
auto callable = tester.GetCallable<>(); auto callable = tester.GetCallable<>();
......
...@@ -724,9 +724,6 @@ TEST(PreParserScopeAnalysis) { ...@@ -724,9 +724,6 @@ TEST(PreParserScopeAnalysis) {
CHECK(i::ScopeTestHelper::HasSkippedFunctionInside( CHECK(i::ScopeTestHelper::HasSkippedFunctionInside(
scope_with_skipped_functions)); scope_with_skipped_functions));
// Do scope allocation (based on the preparsed scope data).
CHECK(i::DeclarationScope::Analyze(&using_scope_data));
// Parse the lazy function again eagerly to produce baseline data. // Parse the lazy function again eagerly to produce baseline data.
i::UnoptimizedCompileState not_using_scope_state(isolate); i::UnoptimizedCompileState not_using_scope_state(isolate);
i::ParseInfo not_using_scope_data(isolate, flags, &not_using_scope_state); i::ParseInfo not_using_scope_data(isolate, flags, &not_using_scope_state);
...@@ -739,9 +736,6 @@ TEST(PreParserScopeAnalysis) { ...@@ -739,9 +736,6 @@ TEST(PreParserScopeAnalysis) {
CHECK(!i::ScopeTestHelper::HasSkippedFunctionInside( CHECK(!i::ScopeTestHelper::HasSkippedFunctionInside(
scope_without_skipped_functions)); scope_without_skipped_functions));
// Do normal scope allocation.
CHECK(i::DeclarationScope::Analyze(&not_using_scope_data));
// Verify that scope allocation gave the same results when parsing w/ the // Verify that scope allocation gave the same results when parsing w/ the
// scope data (and skipping functions), and when parsing without. // scope data (and skipping functions), and when parsing without.
i::ScopeTestHelper::CompareScopes( i::ScopeTestHelper::CompareScopes(
......
...@@ -1082,9 +1082,6 @@ TEST(ScopeUsesArgumentsSuperThis) { ...@@ -1082,9 +1082,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
flags.set_allow_lazy_parsing(false); flags.set_allow_lazy_parsing(false);
i::ParseInfo info(isolate, flags, &compile_state); i::ParseInfo info(isolate, flags, &compile_state);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Rewriter::Rewrite(&info));
info.ast_value_factory()->Internalize(isolate);
CHECK(i::DeclarationScope::Analyze(&info));
i::DeclarationScope::AllocateScopeInfos(&info, isolate); i::DeclarationScope::AllocateScopeInfos(&info, isolate);
CHECK_NOT_NULL(info.literal()); CHECK_NOT_NULL(info.literal());
...@@ -1513,10 +1510,20 @@ TEST(DiscardFunctionBody) { ...@@ -1513,10 +1510,20 @@ TEST(DiscardFunctionBody) {
i::parsing::ParseProgram(&info, script, isolate); i::parsing::ParseProgram(&info, script, isolate);
function = info.literal(); function = info.literal();
CHECK_NOT_NULL(function); CHECK_NOT_NULL(function);
CHECK_EQ(1, function->body()->length()); // The rewriter will rewrite this to
i::FunctionLiteral* inner = // .result = (function f(){...})();
function->body()->first()->AsExpressionStatement()->expression()-> // return .result;
AsCall()->expression()->AsFunctionLiteral(); // so extract the function from there.
CHECK_EQ(2, function->body()->length());
i::FunctionLiteral* inner = function->body()
->first()
->AsExpressionStatement()
->expression()
->AsAssignment()
->value()
->AsCall()
->expression()
->AsFunctionLiteral();
i::Scope* inner_scope = inner->scope(); i::Scope* inner_scope = inner->scope();
i::FunctionLiteral* fun = nullptr; i::FunctionLiteral* fun = nullptr;
if (!inner_scope->declarations()->is_empty()) { if (!inner_scope->declarations()->is_empty()) {
...@@ -3526,7 +3533,6 @@ TEST(InnerAssignment) { ...@@ -3526,7 +3533,6 @@ TEST(InnerAssignment) {
info = std::make_unique<i::ParseInfo>(isolate, flags, &compile_state); info = std::make_unique<i::ParseInfo>(isolate, flags, &compile_state);
CHECK(i::parsing::ParseProgram(info.get(), script, isolate)); CHECK(i::parsing::ParseProgram(info.get(), script, isolate));
} }
CHECK(i::Compiler::Analyze(info.get()));
CHECK_NOT_NULL(info->literal()); CHECK_NOT_NULL(info->literal());
i::Scope* scope = info->literal()->scope(); i::Scope* scope = info->literal()->scope();
...@@ -3636,7 +3642,6 @@ TEST(MaybeAssignedParameters) { ...@@ -3636,7 +3642,6 @@ TEST(MaybeAssignedParameters) {
flags.set_allow_lazy_parsing(allow_lazy); flags.set_allow_lazy_parsing(allow_lazy);
info = std::make_unique<i::ParseInfo>(isolate, flags, &state); info = std::make_unique<i::ParseInfo>(isolate, flags, &state);
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate)); CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
CHECK(i::Compiler::Analyze(info.get()));
CHECK_NOT_NULL(info->literal()); CHECK_NOT_NULL(info->literal());
i::Scope* scope = info->literal()->scope(); i::Scope* scope = info->literal()->scope();
...@@ -3678,7 +3683,6 @@ static void TestMaybeAssigned(Input input, const char* variable, bool module, ...@@ -3678,7 +3683,6 @@ static void TestMaybeAssigned(Input input, const char* variable, bool module,
std::make_unique<i::ParseInfo>(isolate, flags, &state); std::make_unique<i::ParseInfo>(isolate, flags, &state);
CHECK(i::parsing::ParseProgram(info.get(), script, isolate)); CHECK(i::parsing::ParseProgram(info.get(), script, isolate));
CHECK(i::Compiler::Analyze(info.get()));
CHECK_NOT_NULL(info->literal()); CHECK_NOT_NULL(info->literal());
i::Scope* scope = info->literal()->scope(); i::Scope* scope = info->literal()->scope();
...@@ -7837,7 +7841,6 @@ TEST(ModuleParsingInternals) { ...@@ -7837,7 +7841,6 @@ TEST(ModuleParsingInternals) {
flags.set_is_module(true); flags.set_is_module(true);
i::ParseInfo info(isolate, flags, &compile_state); i::ParseInfo info(isolate, flags, &compile_state);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Compiler::Analyze(&info));
i::FunctionLiteral* func = info.literal(); i::FunctionLiteral* func = info.literal();
i::ModuleScope* module_scope = func->scope()->AsModuleScope(); i::ModuleScope* module_scope = func->scope()->AsModuleScope();
i::Scope* outer_scope = module_scope->outer_scope(); i::Scope* outer_scope = module_scope->outer_scope();
...@@ -10867,7 +10870,6 @@ TEST(NoPessimisticContextAllocation) { ...@@ -10867,7 +10870,6 @@ TEST(NoPessimisticContextAllocation) {
i::ParseInfo info(isolate, flags, &compile_state); i::ParseInfo info(isolate, flags, &compile_state);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Compiler::Analyze(&info));
CHECK_NOT_NULL(info.literal()); CHECK_NOT_NULL(info.literal());
i::Scope* scope = info.literal()->scope()->inner_scope(); i::Scope* scope = info.literal()->scope()->inner_scope();
...@@ -11430,8 +11432,6 @@ TEST(LexicalLoopVariable) { ...@@ -11430,8 +11432,6 @@ TEST(LexicalLoopVariable) {
flags.set_allow_lazy_parsing(false); flags.set_allow_lazy_parsing(false);
i::ParseInfo info(isolate, flags, &compile_state); i::ParseInfo info(isolate, flags, &compile_state);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Rewriter::Rewrite(&info));
CHECK(i::DeclarationScope::Analyze(&info));
i::DeclarationScope::AllocateScopeInfos(&info, isolate); i::DeclarationScope::AllocateScopeInfos(&info, isolate);
CHECK_NOT_NULL(info.literal()); CHECK_NOT_NULL(info.literal());
......
...@@ -84,8 +84,6 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone { ...@@ -84,8 +84,6 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
Parser parser(parse_info()); Parser parser(parse_info());
parser.InitializeEmptyScopeChain(parse_info()); parser.InitializeEmptyScopeChain(parse_info());
parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel); parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel);
CHECK(DeclarationScope::Analyze(parse_info()));
} }
parse_info()->ast_value_factory()->Internalize(off_thread_isolate()); parse_info()->ast_value_factory()->Internalize(off_thread_isolate());
...@@ -310,10 +308,13 @@ TEST_F(OffThreadFactoryTest, LazyFunction) { ...@@ -310,10 +308,13 @@ TEST_F(OffThreadFactoryTest, LazyFunction) {
TEST_F(OffThreadFactoryTest, EagerFunction) { TEST_F(OffThreadFactoryTest, EagerFunction) {
FunctionLiteral* program = ParseProgram("(function eager() {})"); FunctionLiteral* program = ParseProgram("(function eager() {})");
// Rewritten to `.result = (function eager() {}); return .result`
FunctionLiteral* eager = program->body() FunctionLiteral* eager = program->body()
->at(0) ->at(0)
->AsExpressionStatement() ->AsExpressionStatement()
->expression() ->expression()
->AsAssignment()
->value()
->AsFunctionLiteral(); ->AsFunctionLiteral();
OffThreadTransferHandle<SharedFunctionInfo> shared; OffThreadTransferHandle<SharedFunctionInfo> shared;
......
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