Commit b31cbbd4 authored by marja's avatar marja Committed by Commit bot

Parser: store parameters in a ThreadedList instead of ZoneList.

ThreadedList is more memory-efficient than ZoneList. This also enables
us to use ThreadedList when making Preparser track parameters (upcoming
work).

BUG=v8:5501

Review-Url: https://codereview.chromium.org/2531593002
Cr-Commit-Position: refs/heads/master@{#41307}
parent 0f48dc7c
...@@ -3520,10 +3520,7 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters, ...@@ -3520,10 +3520,7 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
} }
} }
for (int i = 0; i < parameters->arity; ++i) { impl()->DeclareFormalParameters(parameters->scope, parameters->params);
auto parameter = parameters->at(i);
impl()->DeclareFormalParameter(parameters->scope, parameter);
}
} }
template <typename Impl> template <typename Impl>
......
...@@ -964,7 +964,7 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info, ...@@ -964,7 +964,7 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
} else { } else {
// BindingIdentifier // BindingIdentifier
ParseFormalParameter(&formals, &ok); ParseFormalParameter(&formals, &ok);
if (ok) DeclareFormalParameter(formals.scope, formals.at(0)); if (ok) DeclareFormalParameters(formals.scope, formals.params);
} }
} }
...@@ -2476,15 +2476,11 @@ void Parser::DeclareArrowFunctionFormalParameters( ...@@ -2476,15 +2476,11 @@ void Parser::DeclareArrowFunctionFormalParameters(
if (!parameters->is_simple) { if (!parameters->is_simple) {
this->classifier()->RecordNonSimpleParameter(); this->classifier()->RecordNonSimpleParameter();
} }
for (int i = 0; i < parameters->arity; ++i) { DeclareFormalParameters(parameters->scope, parameters->params);
auto parameter = parameters->at(i); if (!this->classifier()
DeclareFormalParameter(parameters->scope, parameter); ->is_valid_formal_parameter_list_without_duplicates()) {
if (!this->classifier() *duplicate_loc =
->is_valid_formal_parameter_list_without_duplicates() && this->classifier()->duplicate_formal_parameter_error().location;
!duplicate_loc->IsValid()) {
*duplicate_loc =
this->classifier()->duplicate_formal_parameter_error().location;
}
} }
DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
} }
...@@ -2493,9 +2489,9 @@ void Parser::ReindexLiterals(const ParserFormalParameters& parameters) { ...@@ -2493,9 +2489,9 @@ void Parser::ReindexLiterals(const ParserFormalParameters& parameters) {
if (function_state_->materialized_literal_count() > 0) { if (function_state_->materialized_literal_count() > 0) {
AstLiteralReindexer reindexer; AstLiteralReindexer reindexer;
for (const auto p : parameters.params) { for (auto p : parameters.params) {
if (p.pattern != nullptr) reindexer.Reindex(p.pattern); if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
if (p.initializer != nullptr) reindexer.Reindex(p.initializer); if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
} }
DCHECK(reindexer.count() <= function_state_->materialized_literal_count()); DCHECK(reindexer.count() <= function_state_->materialized_literal_count());
...@@ -2926,44 +2922,44 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -2926,44 +2922,44 @@ Block* Parser::BuildParameterInitializationBlock(
DCHECK(!parameters.is_simple); DCHECK(!parameters.is_simple);
DCHECK(scope()->is_function_scope()); DCHECK(scope()->is_function_scope());
Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
for (int i = 0; i < parameters.params.length(); ++i) { int index = 0;
auto parameter = parameters.params[i]; for (auto parameter : parameters.params) {
if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; if (parameter->is_rest && parameter->pattern->IsVariableProxy()) break;
DeclarationDescriptor descriptor; DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
descriptor.scope = scope(); descriptor.scope = scope();
descriptor.hoist_scope = nullptr; descriptor.hoist_scope = nullptr;
descriptor.mode = LET; descriptor.mode = LET;
descriptor.declaration_pos = parameter.pattern->position(); descriptor.declaration_pos = parameter->pattern->position();
// The position that will be used by the AssignmentExpression // The position that will be used by the AssignmentExpression
// which copies from the temp parameter to the pattern. // which copies from the temp parameter to the pattern.
// //
// TODO(adamk): Should this be kNoSourcePosition, since // TODO(adamk): Should this be kNoSourcePosition, since
// it's just copying from a temp var to the real param var? // it's just copying from a temp var to the real param var?
descriptor.initialization_pos = parameter.pattern->position(); descriptor.initialization_pos = parameter->pattern->position();
Expression* initial_value = Expression* initial_value =
factory()->NewVariableProxy(parameters.scope->parameter(i)); factory()->NewVariableProxy(parameters.scope->parameter(index));
if (parameter.initializer != nullptr) { if (parameter->initializer != nullptr) {
// IS_UNDEFINED($param) ? initializer : $param // IS_UNDEFINED($param) ? initializer : $param
// Ensure initializer is rewritten // Ensure initializer is rewritten
RewriteParameterInitializer(parameter.initializer, scope()); RewriteParameterInitializer(parameter->initializer, scope());
auto condition = factory()->NewCompareOperation( auto condition = factory()->NewCompareOperation(
Token::EQ_STRICT, Token::EQ_STRICT,
factory()->NewVariableProxy(parameters.scope->parameter(i)), factory()->NewVariableProxy(parameters.scope->parameter(index)),
factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
initial_value = factory()->NewConditional( initial_value = factory()->NewConditional(
condition, parameter.initializer, initial_value, kNoSourcePosition); condition, parameter->initializer, initial_value, kNoSourcePosition);
descriptor.initialization_pos = parameter.initializer->position(); descriptor.initialization_pos = parameter->initializer->position();
} }
Scope* param_scope = scope(); Scope* param_scope = scope();
Block* param_block = init_block; Block* param_block = init_block;
if (!parameter.is_simple() && scope()->calls_sloppy_eval()) { if (!parameter->is_simple() && scope()->calls_sloppy_eval()) {
param_scope = NewVarblockScope(); param_scope = NewVarblockScope();
param_scope->set_start_position(descriptor.initialization_pos); param_scope->set_start_position(descriptor.initialization_pos);
param_scope->set_end_position(parameter.initializer_end_position); param_scope->set_end_position(parameter->initializer_end_position);
param_scope->RecordEvalCall(); param_scope->RecordEvalCall();
param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
param_block->set_scope(param_scope); param_block->set_scope(param_scope);
...@@ -2978,7 +2974,7 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -2978,7 +2974,7 @@ Block* Parser::BuildParameterInitializationBlock(
BlockState block_state(&scope_state_, param_scope); BlockState block_state(&scope_state_, param_scope);
DeclarationParsingResult::Declaration decl( DeclarationParsingResult::Declaration decl(
parameter.pattern, parameter.initializer_end_position, initial_value); parameter->pattern, parameter->initializer_end_position, initial_value);
PatternRewriter::DeclareAndInitializeVariables( PatternRewriter::DeclareAndInitializeVariables(
this, param_block, &descriptor, &decl, nullptr, CHECK_OK); this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
...@@ -2989,6 +2985,7 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -2989,6 +2985,7 @@ Block* Parser::BuildParameterInitializationBlock(
} }
init_block->statements()->Add(param_block, zone()); init_block->statements()->Add(param_block, zone());
} }
++index;
} }
return init_block; return init_block;
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "src/parsing/preparse-data.h" #include "src/parsing/preparse-data.h"
#include "src/parsing/preparser.h" #include "src/parsing/preparser.h"
#include "src/pending-compilation-error-handler.h" #include "src/pending-compilation-error-handler.h"
#include "src/utils.h"
namespace v8 { namespace v8 {
...@@ -135,7 +136,7 @@ class Parser; ...@@ -135,7 +136,7 @@ class Parser;
struct ParserFormalParameters : FormalParametersBase { struct ParserFormalParameters : FormalParametersBase {
struct Parameter { struct Parameter : public ZoneObject {
Parameter(const AstRawString* name, Expression* pattern, Parameter(const AstRawString* name, Expression* pattern,
Expression* initializer, int initializer_end_position, Expression* initializer, int initializer_end_position,
bool is_rest) bool is_rest)
...@@ -149,16 +150,17 @@ struct ParserFormalParameters : FormalParametersBase { ...@@ -149,16 +150,17 @@ struct ParserFormalParameters : FormalParametersBase {
Expression* initializer; Expression* initializer;
int initializer_end_position; int initializer_end_position;
bool is_rest; bool is_rest;
Parameter* next_parameter = nullptr;
bool is_simple() const { bool is_simple() const {
return pattern->IsVariableProxy() && initializer == nullptr && !is_rest; return pattern->IsVariableProxy() && initializer == nullptr && !is_rest;
} }
Parameter** next() { return &next_parameter; }
Parameter* const* next() const { return &next_parameter; }
}; };
explicit ParserFormalParameters(DeclarationScope* scope) explicit ParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope), params(4, scope->zone()) {} : FormalParametersBase(scope) {}
ZoneList<Parameter> params; ThreadedList<Parameter> params;
const Parameter& at(int i) const { return params[i]; }
}; };
template <> template <>
...@@ -1045,34 +1047,39 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -1045,34 +1047,39 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
const AstRawString* name = is_simple const AstRawString* name = is_simple
? pattern->AsVariableProxy()->raw_name() ? pattern->AsVariableProxy()->raw_name()
: ast_value_factory()->empty_string(); : ast_value_factory()->empty_string();
parameters->params.Add( auto parameter =
ParserFormalParameters::Parameter(name, pattern, initializer, new (parameters->scope->zone()) ParserFormalParameters::Parameter(
initializer_end_position, is_rest), name, pattern, initializer, initializer_end_position, is_rest);
parameters->scope->zone());
parameters->params.Add(parameter);
} }
V8_INLINE void DeclareFormalParameter( V8_INLINE void DeclareFormalParameters(
DeclarationScope* scope, DeclarationScope* scope,
const ParserFormalParameters::Parameter& parameter) { const ThreadedList<ParserFormalParameters::Parameter>& parameters) {
bool is_duplicate = false; for (auto parameter : parameters) {
bool is_simple = classifier()->is_simple_parameter_list(); bool is_duplicate = false;
auto name = is_simple || parameter.is_rest bool is_simple = classifier()->is_simple_parameter_list();
? parameter.name auto name = is_simple || parameter->is_rest
: ast_value_factory()->empty_string(); ? parameter->name
auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY; : ast_value_factory()->empty_string();
if (!is_simple) scope->SetHasNonSimpleParameters(); auto mode = is_simple || parameter->is_rest ? VAR : TEMPORARY;
bool is_optional = parameter.initializer != nullptr; if (!is_simple) scope->SetHasNonSimpleParameters();
Variable* var = bool is_optional = parameter->initializer != nullptr;
scope->DeclareParameter(name, mode, is_optional, parameter.is_rest, Variable* var =
&is_duplicate, ast_value_factory()); scope->DeclareParameter(name, mode, is_optional, parameter->is_rest,
if (is_duplicate) { &is_duplicate, ast_value_factory());
classifier()->RecordDuplicateFormalParameterError(scanner()->location()); if (is_duplicate &&
} classifier()->is_valid_formal_parameter_list_without_duplicates()) {
if (is_sloppy(scope->language_mode())) { classifier()->RecordDuplicateFormalParameterError(
// TODO(sigurds) Mark every parameter as maybe assigned. This is a scanner()->location());
// conservative approximation necessary to account for parameters }
// that are assigned via the arguments array. if (is_sloppy(scope->language_mode())) {
var->set_maybe_assigned(); // TODO(sigurds) Mark every parameter as maybe assigned. This is a
// conservative approximation necessary to account for parameters
// that are assigned via the arguments array.
var->set_maybe_assigned();
}
} }
} }
......
...@@ -752,7 +752,8 @@ class PreParserFactory { ...@@ -752,7 +752,8 @@ class PreParserFactory {
struct PreParserFormalParameters : FormalParametersBase { struct PreParserFormalParameters : FormalParametersBase {
explicit PreParserFormalParameters(DeclarationScope* scope) explicit PreParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope) {} : FormalParametersBase(scope) {}
PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
void* params = nullptr; // Dummy
}; };
...@@ -1440,8 +1441,8 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1440,8 +1441,8 @@ class PreParser : public ParserBase<PreParser> {
parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest); parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
} }
V8_INLINE void DeclareFormalParameter(DeclarationScope* scope, V8_INLINE void DeclareFormalParameters(DeclarationScope* scope,
PreParserIdentifier parameter) { void* parameters) {
if (!classifier()->is_simple_parameter_list()) { if (!classifier()->is_simple_parameter_list()) {
scope->SetHasNonSimpleParameters(); scope->SetHasNonSimpleParameters();
} }
......
...@@ -1627,9 +1627,31 @@ class ThreadedList final { ...@@ -1627,9 +1627,31 @@ class ThreadedList final {
friend class ThreadedList; friend class ThreadedList;
}; };
class ConstIterator final {
public:
ConstIterator& operator++() {
entry_ = (*entry_)->next();
return *this;
}
bool operator!=(const ConstIterator& other) {
return entry_ != other.entry_;
}
const T* operator*() const { return *entry_; }
private:
explicit ConstIterator(T* const* entry) : entry_(entry) {}
T* const* entry_;
friend class ThreadedList;
};
Iterator begin() { return Iterator(&head_); } Iterator begin() { return Iterator(&head_); }
Iterator end() { return Iterator(tail_); } Iterator end() { return Iterator(tail_); }
ConstIterator begin() const { return ConstIterator(&head_); }
ConstIterator end() const { return ConstIterator(tail_); }
void Rewind(Iterator reset_point) { void Rewind(Iterator reset_point) {
tail_ = reset_point.entry_; tail_ = reset_point.entry_;
*tail_ = nullptr; *tail_ = nullptr;
......
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